Fed*_*ede 35
我有同样的问题.我的解决方案是:
ViewPager
并添加一个名为的属性childId
.childId
属性创建一个setter 并设置id的id HorizontalScrollView
.onInterceptTouchEvent()
在子类中重写,ViewPager
如果childId
属性大于0,则获取该子节点,如果事件在HorizontalScrollView
区域中,则返回false.码
public class CustomViewPager extends ViewPager {
private int childId;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (childId > 0) {
View scroll = findViewById(childId);
if (scroll != null) {
Rect rect = new Rect();
scroll.getHitRect(rect);
if (rect.contains((int) event.getX(), (int) event.getY())) {
return false;
}
}
}
return super.onInterceptTouchEvent(event);
}
public void setChildId(int id) {
this.childId = id;
}
}
Run Code Online (Sandbox Code Playgroud)
在onCreate()
方法中
viewPager.setChildId(R.id.horizontalScrollViewId);
adapter = new ViewPagerAdapter(this);
viewPager.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)
希望这有帮助
谢谢回复.我稍微修改了你的解决方案并设法使嵌套的ViewPagers工作:
public class CustomViewPager extends ViewPager {
private int childId;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (childId > 0) {
ViewPager pager = (ViewPager)findViewById(childId);
if (pager != null) {
pager.requestDisallowInterceptTouchEvent(true);
}
}
return super.onInterceptTouchEvent(event);
}
public void setChildId(int id) {
this.childId = id;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我知道这个问题已经很老了,但是我已经找到了一个解决方案,我认为这个解决方案比这里发布的方案有一些额外的优势.可能发生的一种情况是我可以在我的ViewPager中使用多个HorizontalScrollView(我这样做),然后我需要向ViewPager提供大量的ID,以便它始终可以检查子触摸冲突.
我分析了ViewPager的源代码,发现他们使用名为"canScroll"的方法来确定是否可以滚动子视图.幸运的是,它不是静态的也不是最终的,所以我可以覆盖它.在该方法中调用了"boolean ViewCompat.canScrollHorizontally(View,int)"(对于SDK <14总是返回false的那个).我的解决方案是:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomViewPager(Context context) {
super(context);
}
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
return super.canScroll(v, checkV, dx, x, y) || (checkV && customCanScroll(v));
}
protected boolean customCanScroll(View v) {
if (v instanceof HorizontalScrollView) {
View hsvChild = ((HorizontalScrollView) v).getChildAt(0);
if (hsvChild.getWidth() > v.getWidth())
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您的ViewPager中有一个不同的View类,它也应该接收水平拖动,只需更改customCanScroll(View),这样您就可以在不应该截取触摸时返回.
如果还应检查当前视图的"可滚动性",则布尔checkV为true,这就是为什么我们也应该检查它.
希望这有助于解决此类未来的问题(或者如果有更好的解决方案,或Android平台的官方解决方案,请告诉我).
我不知道你是否已经解决了这个问题.但上面的答案都没有正常工作.因此,对于那些可能正在寻找解决方案的人来说,我认为这是必要的.
实际上,如果您阅读有关在ViewGroup中处理触摸事件的官方文档,则解决方案非常简单.
首先,您需要了解其用法
ViewParent.requestDisallowInterceptTouchEvent(boolean),在父视图上调用此方法以指示它不应使用onInterceptTouchEvent(MotionEvent)拦截触摸事件.
然后,您需要拦截事件并确保您的HorizontalScrollView的父ViewGroup不会进一步调度事件.
因此,为您设置一个OnToushListener HorizontalScrollView.检测触摸并移动事件,然后将requestDisallowInterceptTouchEvent(true)设置为它的父(ViewPager或其他),以确保HorizontalScrollView处理事件.
当然,您可以将以下代码放入CustomHorizontalScrollView组件中,以便可以重复使用它们.
希望它有所帮助.;-)
horizontalScrollView.setOnTouchListener(new View.OnTouchListener() {
float rawX;
int mTouchSlop = ViewConfiguration.get(getActivity()).getScaledTouchSlop();
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
v.getParent().requestDisallowInterceptTouchEvent(true);
rawX = event.getRawX();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
rawX = 0f;
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(rawX - event.getRawX()) > mTouchSlop)
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
这是另一个对我有用的解决方案,
创建自定义ViewPager
public class NoScrollViewPager extends ViewPager {
private boolean scrollDisable = false;
public NoScrollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(scrollDisable) {
return false;
} else {
return super.onInterceptTouchEvent(ev);
}
}
public void disableScroll() {
scrollDisable = true;
}
public void enableScroll() {
scrollDisable = false;
}
}
Run Code Online (Sandbox Code Playgroud)
然后将OnTouchListener添加到您的项目中,无论是HorizontalScrollView还是Gallery,还是其他任何您不希望viewpager在触摸时滚动的内容.
gf.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0,
MotionEvent ev) {
switch(ev.getAction()) {
case MotionEvent.ACTION_DOWN:
viewPager.disableScroll();
break;
case MotionEvent.ACTION_UP:
viewPager.enableScroll();
break;
}
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
35070 次 |
最近记录: |