SwipeDismissBehavior 未在以编程方式添加的协调器布局的子项中触发
SwipeDismissBehavior not triggered in Child of programmatically added Coordinator Layout
我有以下视图层次结构:
所以假设我有以下内容:
我以编程方式将我的 MyCoordinatorLayout 膨胀为 LinearLayout 的子项。所以在某个地方发生了这种情况:
linearLayout.addView(myCoordinatorLayout, ..., ...);
现在我有以下代码:
public class MyCoordinatorLayout extends CoordinatorLayout{
public void inflate() {
LayoutInflater.from(getContext()).inflate(R.layout.merge_header_custom_layout, this, true);
WebView newWebView = new WebView(getContext());
addView(newWebView, 0, new ViewGroup.LayoutParams.MATCH_PARENT, MATCH_PARENT);
}
}
public class MyCustomLayout extends LinearLayout{
@Override
public void onAttachedToWindow() {
Log.v(TAG, "onAttachedToWindow() called, now adding swipe behavior"); //This is called as expected!
addSwipeBehavior();
}
private void addSwipeBehavior() {
final SwipeDismissBehavior<View> swipe = new SwipeDismissBehavior<View>();
swipe.setSwipeDirection(SWIPE_DIRECTION_ANY);
swipe.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(View view) {
Log.v(TAG, "onDismiss called!");
}
@Override
public void onDragStateChanged(int i) {
Log.v(TAG, "onDragStateChanged()");
}
}
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) get LayoutParams();
params.setBehavior(swipe);
Log.v(TAG, "behavior=" + params.getBehavior); //This shows its set.
}
}
问题来了。滑动关闭根本不起作用。事实上,我添加的那些日志语句从未被打印出来。是否可能是因为我的 CoordinatorLayout 是以编程方式添加的,而不是像我看到的示例那样预先存在于 XML 中?
我真的希望我的行为能够奏效,但就是没有被触发。另外,我检查了 MyCustomLayout
并看到它的 onTouchEvent(MotionEvent e) 被触发了……但是,该行为仍然没有被触发。我还做了一个 getLayoutParams()
和 getBehavior()
并且它 returns 是正确的行为所以我知道 CoordinatorLayout 有正确的行为,但行为根本不只是工作......不确定如果我错过了什么!如果能得到一些帮助或为我指明正确的方向,那就太好了!
我认为第一个问题是 SwipeDismissBehavior
需要与可滑动视图相关联,以及与您想要滑动以关闭的方式相关联的行为,例如,左右滑动 behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
然后适当地传播触摸,或者如果在 RecyclerView 中使用类似 ItemTouchHelper
.
的东西
这个 SO post 在解释如何正确设置滑动以关闭方面做得更好:How to use SwipeDismissBehavior.OnDismissListener on RecyclerView
希望对您有所帮助。
我能够弄清楚为什么我与 SwipeDismissBehavior 的触摸交互从未被调用过。原因很简单。在我的图表中,我忘记了视图层次结构的顶部和线性布局顶部是一个视图寻呼机。让我重新画图。
实际发生的事情是 ViewPager 拦截了我的触摸并且从不让它到达子布局。有一个修复。我需要做的是:
public class MySwipeDismissBehavior extends SwipeDismissBehavior<View> {
private float mLastX;
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, FrameLayout child, MotionEvent event) {
if (parent.isPountInChildBounds(child, event.getX(), event.getY())) {
ViewPager vp = findViewPager(child);
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
disableViewPager(vp, true);
break;
case MotionEvent.ACTION_MOVE:
boolean swipingLeftToRight = (x-mLastX) > 0; //Allow the view pager to handle it if I swiping from left to right.
if (swipingLeftToRight) {
disableViewPager(vp, false);
} else { // if swiping from right to left, let the swipe dismiss behavior handle it.
disableViewPager(vp, true);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: //As soon as it
disableViewPager(vp, true);
break;
}
}
}
private void disableViewPager(ViewPager vp, boolean enable) {
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(enable)
}
}
private ViewPager findViewPager(View child) {
ViewPager parent = child.getParent();
while (parent != null) {
parent = child.getParent();
if (parent instanceof ViewPager) {
return (ViewPager) parent;
} else if(!(parent instanceof View)) {
return null;
} else {
child = (View) parent;
}
}
return null;
}
}
在我将这个新行为添加到我的代码后,我的滑动关闭行为起作用了。我希望这对其他人有帮助。我从这里获得了解决方案的帮助和灵感:。这不是完全相同的问题,但它为我指明了正确的方向
我有以下视图层次结构:
所以假设我有以下内容:
我以编程方式将我的 MyCoordinatorLayout 膨胀为 LinearLayout 的子项。所以在某个地方发生了这种情况:
linearLayout.addView(myCoordinatorLayout, ..., ...);
现在我有以下代码:
public class MyCoordinatorLayout extends CoordinatorLayout{
public void inflate() {
LayoutInflater.from(getContext()).inflate(R.layout.merge_header_custom_layout, this, true);
WebView newWebView = new WebView(getContext());
addView(newWebView, 0, new ViewGroup.LayoutParams.MATCH_PARENT, MATCH_PARENT);
}
}
public class MyCustomLayout extends LinearLayout{
@Override
public void onAttachedToWindow() {
Log.v(TAG, "onAttachedToWindow() called, now adding swipe behavior"); //This is called as expected!
addSwipeBehavior();
}
private void addSwipeBehavior() {
final SwipeDismissBehavior<View> swipe = new SwipeDismissBehavior<View>();
swipe.setSwipeDirection(SWIPE_DIRECTION_ANY);
swipe.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(View view) {
Log.v(TAG, "onDismiss called!");
}
@Override
public void onDragStateChanged(int i) {
Log.v(TAG, "onDragStateChanged()");
}
}
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) get LayoutParams();
params.setBehavior(swipe);
Log.v(TAG, "behavior=" + params.getBehavior); //This shows its set.
}
}
问题来了。滑动关闭根本不起作用。事实上,我添加的那些日志语句从未被打印出来。是否可能是因为我的 CoordinatorLayout 是以编程方式添加的,而不是像我看到的示例那样预先存在于 XML 中?
我真的希望我的行为能够奏效,但就是没有被触发。另外,我检查了 MyCustomLayout
并看到它的 onTouchEvent(MotionEvent e) 被触发了……但是,该行为仍然没有被触发。我还做了一个 getLayoutParams()
和 getBehavior()
并且它 returns 是正确的行为所以我知道 CoordinatorLayout 有正确的行为,但行为根本不只是工作......不确定如果我错过了什么!如果能得到一些帮助或为我指明正确的方向,那就太好了!
我认为第一个问题是 SwipeDismissBehavior
需要与可滑动视图相关联,以及与您想要滑动以关闭的方式相关联的行为,例如,左右滑动 behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
然后适当地传播触摸,或者如果在 RecyclerView 中使用类似 ItemTouchHelper
.
这个 SO post 在解释如何正确设置滑动以关闭方面做得更好:How to use SwipeDismissBehavior.OnDismissListener on RecyclerView
希望对您有所帮助。
我能够弄清楚为什么我与 SwipeDismissBehavior 的触摸交互从未被调用过。原因很简单。在我的图表中,我忘记了视图层次结构的顶部和线性布局顶部是一个视图寻呼机。让我重新画图。
实际发生的事情是 ViewPager 拦截了我的触摸并且从不让它到达子布局。有一个修复。我需要做的是:
public class MySwipeDismissBehavior extends SwipeDismissBehavior<View> {
private float mLastX;
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, FrameLayout child, MotionEvent event) {
if (parent.isPountInChildBounds(child, event.getX(), event.getY())) {
ViewPager vp = findViewPager(child);
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
disableViewPager(vp, true);
break;
case MotionEvent.ACTION_MOVE:
boolean swipingLeftToRight = (x-mLastX) > 0; //Allow the view pager to handle it if I swiping from left to right.
if (swipingLeftToRight) {
disableViewPager(vp, false);
} else { // if swiping from right to left, let the swipe dismiss behavior handle it.
disableViewPager(vp, true);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: //As soon as it
disableViewPager(vp, true);
break;
}
}
}
private void disableViewPager(ViewPager vp, boolean enable) {
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(enable)
}
}
private ViewPager findViewPager(View child) {
ViewPager parent = child.getParent();
while (parent != null) {
parent = child.getParent();
if (parent instanceof ViewPager) {
return (ViewPager) parent;
} else if(!(parent instanceof View)) {
return null;
} else {
child = (View) parent;
}
}
return null;
}
}
在我将这个新行为添加到我的代码后,我的滑动关闭行为起作用了。我希望这对其他人有帮助。我从这里获得了解决方案的帮助和灵感: