结束向右滑动活动?

问题描述:

我必须完成Activity,当用户在屏幕的任何地方提供正确的滑动。我尝试过GestureDetector,如果ScrollViewActivity中都不存在RescyclerView,并且此外包含onClickListener的视图也不允许检测它们的滑动,则表示工作正常。因此,我尝试了一种不同的方式,将视图以编程方式覆盖在所有视图顶部的布局中,然后尝试检测其上的轻扫事件。结束向右滑动活动?

private void swipeOverToExit(ViewGroup rootView) { 

     OverlayLayout child = new OverlayLayout(this); 

     ViewGroup.LayoutParams layoutParams = 
       new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 

     child.setLayoutParams(layoutParams); 

     rootView.addView(child); 

} 

OverlayLayout

public class OverlayLayout extends RelativeLayout { 

    private float x1, x2; 
    private final int MIN_DISTANCE = 150; 

    public OverlayLayout(Context context) { 
     super(context); 
    } 

    public OverlayLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public OverlayLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public OverlayLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 


    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     /* 
     * This method JUST determines whether we want to intercept the motion. 
     * If we return true, onTouchEvent will be called and we do the actual 
     * logic there. 
     */ 

     final int action = MotionEventCompat.getActionMasked(event); 

     Logger.logD("Intercept===", action + ""); 


     // Always handle the case of the touch gesture being complete. 
     if (action == MotionEvent.ACTION_DOWN) { 
      return true; // Intercept touch event, let the parent handle swipe 
     } 

     Logger.logD("===", "Out side" + action + ""); 


     // In general, we don't want to intercept touch events. They should be 
     // handled by the child view. 
     return false; 
    } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       x1 = event.getX(); 
       break; 
      case MotionEvent.ACTION_UP: 

       x2 = event.getX(); 
       float deltaX = x2 - x1; 

       if (Math.abs(deltaX) > MIN_DISTANCE) { 

        Logger.logD("Swipe Right===", MIN_DISTANCE + ""); 
        return true; 

       } else { 

        Logger.logD("Tap===", "Tap==="); 
        return super.onTouchEvent(event); 
       } 
     } 

     return true; 

    } 
} 

的逻辑是如果滑动操作执行在OverlayLayout然后进一步落得Activity到触摸事件拦截到其他视图。但是,现在我可以检测到OverlayLayout上的滑动事件,但其他视图无法响应,即使我已返回return super.onTouchEvent(event);其他条件为onTouchEvent,因为您可以在我的代码中找到它。任何人都请帮助我做到。我在这里,超级兴奋固定学习的伎俩:)

+0

尝试添加 @Override public boolean dispatchTouchEvent(MotionEvent ev){ super.dispatchTouchEvent(ev); return productGestureDetector.onTouchEvent(ev); }到您的活动 –

+0

@Stella您是否在活动中尝试过dispatchTouchEvent? – Nisarg

+0

尝试搜索以任何布局控制手势的'touchIntercept'方法。 –

什么哟你试图做的事情基本上是默认行为,在Android Wear和它被认为是标准做法Android Watches存在和应用程序。 在Android穿DismissOverlayView为你做所有重担。

智能手机有后退按钮,Wear依靠长按或刷卡消除模式退出屏幕。您应该关闭背部活动,Android智能手机中的混合佩戴模式会让用户感到困惑。至少显示警告对话框以避免意外退出。

解决方案

当我看到这个问题是标签与Android Activity我会建议你做一个基本活动将照顾轻扫手势和finish()本身从左向右轻扫。

的基本活动类应该是这样的: -

public abstract class SwipeDismissBaseActivity extends AppCompatActivity { 
    private static final int SWIPE_MIN_DISTANCE = 120; 
    private static final int SWIPE_MAX_OFF_PATH = 250; 
    private static final int SWIPE_THRESHOLD_VELOCITY = 200; 
    private GestureDetector gestureDetector; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     gestureDetector = new GestureDetector(new SwipeDetector()); 
    } 

    private class SwipeDetector extends GestureDetector.SimpleOnGestureListener { 
     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 

      // Check movement along the Y-axis. If it exceeds SWIPE_MAX_OFF_PATH, 
      // then dismiss the swipe. 
      if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
       return false; 

      // Swipe from left to right. 
      // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) 
      // and a certain velocity (SWIPE_THRESHOLD_VELOCITY). 
      if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       finish(); 
       return true; 
      } 

      return false; 
     } 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent ev) { 
     // TouchEvent dispatcher. 
     if (gestureDetector != null) { 
      if (gestureDetector.onTouchEvent(ev)) 
       // If the gestureDetector handles the event, a swipe has been 
       // executed and no more needs to be done. 
       return true; 
     } 
     return super.dispatchTouchEvent(ev); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
    } 
} 

现在您可以进行其他活动扩展此基础活动,他们将 将Inheritance自动使它们采用滑动将其关闭 行为。这种方式

  • 普尔雷OOPS方法

public class SomeActivity extends SwipeDismissBaseActivity { 

优势

  • 清洁代码 - 不需要写刷卡听众在项目中使用的布局每种类型(相对,直线等)
  • 在ScrollView中完美工作
  • +1

    工作完全罚款与罚款。任何想法如何拖动手指和解雇活动? –

    +0

    @ hitesh-sahu您可以回答Seshu问的问题,我也需要。 –

    试试这个我使用功能的刷卡一样,

    查看刷卡...

    yourview.setOnTouchListener(new SimpleGestureFilter(this)); // yourview is layout or container to swipe 
    

    SimpleGestureFilter类

    public class SimpleGestureFilter implements View.OnTouchListener { 
    
         static final String logTag = "ActivitySwipeDetector"; 
         private Context activity; 
         static final int MIN_DISTANCE = 100;// TODO change this runtime based on screen resolution. for 1920x1080 is to small the 100 distance 
         private float downX, downY, upX, upY; 
    
         // private NDAAgreementActivity mMainActivity; 
    
         public SimpleGestureFilter(Context mainActivity) { 
          activity = mainActivity; 
         } 
    
         public void onRightToLeftSwipe() { 
    
    
          //do your code to right to left 
    
    
    
         } 
    
         public void onLeftToRightSwipe() { 
          //do your code to left to right 
         } 
    
         public void onTopToBottomSwipe() { 
    
         } 
    
         public void onBottomToTopSwipe() { 
    
         } 
    
         public boolean onTouch(View v, MotionEvent event) { 
          switch (event.getAction()) { 
           case MotionEvent.ACTION_DOWN: { 
            downX = event.getX(); 
            downY = event.getY(); 
            return true; 
           } 
           case MotionEvent.ACTION_UP: { 
            upX = event.getX(); 
            upY = event.getY(); 
    
            float deltaX = downX - upX; 
            float deltaY = downY - upY; 
    
            // swipe horizontal? 
            if (Math.abs(deltaX) > MIN_DISTANCE) { 
             // left or right 
             if (deltaX < 0) { 
              this.onLeftToRightSwipe(); 
              return true; 
             } 
             if (deltaX > 0) { 
              this.onRightToLeftSwipe(); 
              return true; 
             } 
            } else { 
             Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long horizontally, need at least " + MIN_DISTANCE); 
             // return false; // We don't consume the event 
            } 
    
            // swipe vertical? 
            if (Math.abs(deltaY) > MIN_DISTANCE) { 
             // top or down 
             if (deltaY < 0) { 
              this.onTopToBottomSwipe(); 
              return true; 
             } 
             if (deltaY > 0) { 
              this.onBottomToTopSwipe(); 
              return true; 
             } 
            } else { 
             Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long vertically, need at least " + MIN_DISTANCE); 
             // return false; // We don't consume the event 
            } 
    
            return false; // no swipe horizontally and no swipe vertically 
           }// case MotionEvent.ACTION_UP: 
          } 
          return false; 
         } 
        } 
    
    +0

    这是行不通的,如果我已设置点击事件的任何孩子。 – Stella

    +0

    你应该检查你内的儿童区域刷卡..... 检查该地区匹配的父母和匹配高度比检查它... –

    我面临着与活动叠加相同的问题。这为我工作

    1)定义你SwipeListener

    公共类SwipeListener实现View.OnTouchListener {

    private SwipeListenerInterface activity; 
    private float downX, downY, upX, upY; 
    
    public SwipeListener(SwipeListenerInterface activity) { 
        this.activity = activity; 
    } 
    
    public void onRightToLeftSwipe(View v) { 
        Log.i(logTag, "RightToLeftSwipe!"); 
        activity.onRightToLeftSwipe(v); 
    } 
    
    public void onLeftToRightSwipe(View v) { 
        Log.i(logTag, "LeftToRightSwipe!"); 
        activity.onLeftToRightSwipe(v); 
    } 
    
    public void onTopToBottomSwipe(View v) { 
        Log.i(logTag, "TopToBottomSwipe!"); 
        activity.onTopToBottomSwipe(v); 
    } 
    
    public void onBottomToTopSwipe(View v) { 
        Log.i(logTag, "BottomToTopSwipe!"); 
        activity.onBottomToTopSwipe(v); 
    } 
    
    public boolean onTouch(View v, MotionEvent event) { 
        switch (event.getAction()) { 
         case MotionEvent.ACTION_DOWN: { 
          downX = event.getX(); 
          downY = event.getY(); 
          return true; 
         } 
         case MotionEvent.ACTION_UP: { 
          upX = event.getX(); 
          upY = event.getY(); 
          float deltaX = downX - upX; 
          float deltaY = downY - upY; 
    
           if (deltaX < 0) { 
            this.onLeftToRightSwipe(v); 
            return true; 
           } 
           if (deltaX > 0) { 
            this.onRightToLeftSwipe(v); 
            return true; 
           } 
    
           if (deltaY < 0) { 
            this.onTopToBottomSwipe(v); 
            return true; 
           } 
           if (deltaY > 0) { 
            this.onBottomToTopSwipe(v); 
            return true; 
           } 
    
         } 
        } 
        return false; 
    } 
    
    public void setSwipeRestrictions(int swipeRestrictionX, int swipeRestrictionY) { 
        this.swipeRestrictionX = swipeRestrictionX; 
        this.swipeRestrictionY = swipeRestrictionY; 
    } 
    

    2)使用以下简称接口

    public interface SwipeListenerInterface { 
    
        void onRightToLeftSwipe(View v); 
    
        void onLeftToRightSwipe(View v); 
    
        void onTopToBottomSwipe(View v); 
    
        void onBottomToTopSwipe(View v); 
    } 
    

    3)创建对象并将其绑定到您的overlayView(确保将接口调整为overLay视图,以便它可以接收回调)

    sl = new SwipeListener(this); 
        overlayView.setOnTouchListener(sl); 
    

    我相信您在RecyclerView和ScrollView中遇到的问题与在父母面前获得焦点的子元素有关。您可以尝试为Recycler/Scroll视图设置android:descendantFocusability="beforeDescendants"

    SwipeBack是一个Android库,用于和Activities做一样的android“后退按钮”,但是通过一个非常直观的方式使用滑动手势。

    从Maven的中央

    compile 'com.hannesdorfmann:swipeback:1.0.4'

    得到它创建一个基地活动,并写下方法

    public void initDrawerSwipe(int layoutId) { 
         SwipeBack.attach(this, Position.LEFT) 
           .setContentView(layoutId) 
           .setSwipeBackView(R.layout.layout_swipe_back) 
           .setSwipeBackTransformer(new SlideSwipeBackTransformer() { 
            @Override 
            public void onSwipeBackCompleted(SwipeBack swipeBack, Activity activity) { 
             supportFinishAfterTransition(); 
            } 
           }); 
        } 
    

    然后通过你的布局ID到放置在你的基地行动的方法

    @Override 
        protected void onCreate(@Nullable Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         initDrawerSwipe(R.layout.activity_stylists); 
        } 
    

    这适用于所有sc您在查询中指出的enario。