自定义仿侧滑菜单

自定义仿侧滑菜单

<com.example.makura.myapplication.MySlideLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp">

    <include
        android:id="@+id/item_content"
        layout="@layout/item_content" />

    <include

        android:id="@+id/item_menu"
        layout="@layout/item_menu" />
</com.example.makura.myapplication.MySlideLayout>
public class MySlideLayout extends FrameLayout {
    /**
     * 要显示的内容
     */
    private View contentView;
    /**
     * 要显示的菜单
     */
    private View menuView;
    /**
     * 内容的宽
     */
    private int contentWidth;
    /**
     * 菜单的宽
     */
    private int menuWidth;
    /**
     * item的高度
     */
    private int viewHeight;
    /**
     * 滚动者
     */
    private Scroller scroller;


    public MySlideLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    private void initView(Context context) {
        scroller = new Scroller(context);

    }

    /**
     * 布局文件加载完成后回调此方法
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        contentView = getChildAt(0);
        menuView = getChildAt(1);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /**
         * 获得测量时得到的宽高
         */
        contentWidth = contentView.getMeasuredWidth();
        menuWidth = menuView.getMeasuredWidth();
        viewHeight = contentView.getMeasuredHeight();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        contentView.layout(0, 0, contentWidth, viewHeight);
        menuView.layout(contentWidth, 0, contentWidth + menuWidth, viewHeight);
    }

    /**
     * 处理点击事件拦截滑动事件的问题
     * true 拦截孩子的事件,执行自身的onTouchEvent方法
     * false 不拦截孩子的事件,事件继续传递
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        /**
         * 默认将事件传递给孩子
         */
        boolean intercept = false;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                /**
                 * 记录开始位置
                 */
                startX = ev.getX();
                startY = ev.getY();

                downX = startX;
                downY = startY;

                break;
            case MotionEvent.ACTION_MOVE:
                /**
                 * 记录结束位置
                 */
                float endX = ev.getX();
                startX = ev.getX();
                startY = ev.getY();
                /**
                 * 在X轴和Y轴滑动的距离
                 */
                float DX = Math.abs(endX - downX);
                if (DX > 0) {
                    /**
                     * 只要水平方向发生滑动就拦截子View的事件
                     */
                    intercept = true;
                }
                startX = ev.getX();
                startY = ev.getY();
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return intercept;
    }

    private float startX;
    private float startY;

    private float downX;//只赋值一次
    private float downY;//只赋值一次


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                /**
                 * 记录开始位置
                 */
                startX = event.getX();
                startY = event.getY();

                downX = startX;
                downY = startY;

                break;
            case MotionEvent.ACTION_MOVE:
                /**
                 * 记录结束位置
                 */
                float endX = event.getX();
                float endY = event.getY();
                /**
                 * 计算偏移量
                 */
                float distanceX = endX - startX;
                int toScrollX = (int) (getScrollX() - distanceX);
                if (toScrollX < 0) {
                    toScrollX = 0;
                } else if (toScrollX > menuWidth) {
                    toScrollX = menuWidth;
                }

                scrollTo(toScrollX, getScrollY());

                startX = event.getX();
                startY = event.getY();
                /**
                 * 在X轴和Y轴滑动的距离
                 */
                float DX = Math.abs(endX - downX);
                float DY = Math.abs(endY - downY);
                if (DX >= DY) {
                    //TODO 水平方向滑动 响应策划
                    /**
                     * 反拦截 将事件给SlideLayout
                     */
                    getParent().requestDisallowInterceptTouchEvent(true);

                }

                break;
            case MotionEvent.ACTION_UP:
                //偏移量
                int totalScrollX = getScrollX();
                if (totalScrollX < menuWidth / 2) {
                    //TODO 自动关闭
                    closeMenu();
                } else {
                    // TODO 自动打开
                    openMenu();
                }
                break;
        }
        return true;
    }

    private void openMenu() {

        int distanceX = menuWidth - getScrollX();
        scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY());
        //强制刷新
        invalidate();
    }

    private void closeMenu() {
        int distanceX = 0 - getScrollX();
        scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY());
        //强制刷新
        invalidate();
    }

    /**
     * 刷新后触发此方法
     */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            invalidate();
        }
    }

}
 item_content.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();
                }
            });

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值