最简单侧滑退出activity的实现

侧滑退出activity的原理其实很简单:

1.设置activity为透明主题。

2.自定义viewgroup作为activity的根布局。

3.在自定义的viewgroup中onTounEvent中根据手指滑动使用scrollBy方法滑动viewgroup中的内容。

4.监听滑动完成关闭activity。

这里只提供下简单实现思路,里面当然有很多问题,特别滑动冲突需要处理。另外NestedScrollingParent和NestedScrollingChild处理滑动问题是非常好的。


public class SlideCloseLayout extends ViewGroup {
    private int screeWidth;
    private float startX;
    private int childCount;
    private Scroller mScroller;//处理平滑滑动
    private Context mContext;
    private boolean isClose = false;

    public SlideCloseLayout(Context context) {
        super(context);
        init(context);
    }

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

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

    private void init(Context mContext) {
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        screeWidth = wm.getDefaultDisplay().getWidth();
        mScroller = new Scroller(mContext);
        this.mContext = mContext;
        //scrollBy(screeWidth, 0);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        childCount = count;
        View child;
        for (int i = 0; i < count; i++) {
            child = getChildAt(i);
            child.layout(screeWidth * i, t, screeWidth * (i + 1), b);//子view的排放规则,不是重点
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();
        for (int i = 0; i < count; ++i) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
            }
        }
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                int dx = (int) (startX - x);
                if ((getScrollX() >= 0 && dx > 0)) {
                    dx = 0;
                }
                startX = x;
                //滑动
                scrollBy(dx, 0);
                break;
            case MotionEvent.ACTION_UP:
                //当手指离开屏幕时判断当前内容滑动的位置
                //如果滑动位置小于屏幕宽度的一半,则回到原始状态,反之。
                //通过Scroller类平滑移动
                float upDx = getScrollX();
                if (Math.abs(upDx) > screeWidth / 2) {
                    isClose = true;//滑动到最右边,可以关闭activity
                    mScroller.startScroll(getScrollX(), 0, -(screeWidth - getScrollX()), 0, 300);
                    invalidate();
                } else {
                    mScroller.startScroll(getScrollX(), 0, -getScrollX(), 0, 100);
                    invalidate();
                }

                break;
        }
        return true;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        if (mScroller.computeScrollOffset()) {//返回true正在滚动,false滚动完成
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        } else {
            if (isClose) {//true代表滚动到最右边可以关闭activity
                if (mContext != null) {
                    ((Activity) mContext).finish();
                }
            }
        }
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要脱离Activity实现一个单独全局侧滑应用,可以使用Android中的Service来实现。Service是一种在后台运行的组件,它可以独立于Activity运行,并且可以在后台处理一些耗时的任务,如网络请求等。 具体实现步骤如下: 1. 创建一个Service类,并在onCreate方法中初始化全局侧滑菜单布局,并将其添加到WindowManager中。 ```java public class SlideMenuService extends Service { private WindowManager mWindowManager; private View mSlideMenuView; @Override public void onCreate() { super.onCreate(); // 初始化全局侧滑菜单布局 mSlideMenuView = LayoutInflater.from(this).inflate(R.layout.slide_menu_layout, null); // 将全局侧滑菜单布局添加到WindowManager中 mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; mWindowManager.addView(mSlideMenuView, layoutParams); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); // 从WindowManager中移除全局侧滑菜单布局 mWindowManager.removeView(mSlideMenuView); } } ``` 2. 在AndroidManifest.xml文件中注册Service。 ```xml <service android:name=".SlideMenuService" /> ``` 3. 在需要使用全局侧滑菜单的地方启动Service。 ```java Intent intent = new Intent(MainActivity.this, SlideMenuService.class); startService(intent); ``` 需要注意的是,由于Android 8.0及以上版本限制了应用的后台服务,如果想要在后台运行Service,需要使用startForeground方法将Service变成前台服务,并且需要显示一个通知,告诉用户Service正在运行。 完整代码可以参考以下示例: ```java public class MainActivity extends AppCompatActivity { private boolean mIsServiceRunning = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startServiceButton = findViewById(R.id.start_service_button); startServiceButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!mIsServiceRunning) { // 启动Service Intent intent = new Intent(MainActivity.this, SlideMenuService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0及以上版本需要使用startForeground方法将Service变成前台服务 startForegroundService(intent); } else { startService(intent); } mIsServiceRunning = true; startServiceButton.setText(R.string.stop_service); } else { // 停止Service Intent intent = new Intent(MainActivity.this, SlideMenuService.class); stopService(intent); mIsServiceRunning = false; startServiceButton.setText(R.string.start_service); } } }); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值