美文网首页
自定义控件之侧滑栏

自定义控件之侧滑栏

作者: XINHAO_HAN | 来源:发表于2017-09-20 14:48 被阅读0次

    最终效果图

    2017-09-20-02mzLppp.gif

    好吧,看起来和上一个侧滑栏没有什么不同,但是两个实现完全不同一个是利用控件本身的TranslationX来移动的,一个是利用scrollTo /scrollBy实现的,是继承ViewGroup
    还有自带的滚动器 Scroller scroller;使用

    代码(全部)

    package com.example.downlist.view;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.Scroller;
    
    import com.example.downlist.utils.UIUtlis;
    
    /**
     * Created by Administrator on 2017/9/11.
     */
    
    //左边侧滑栏
    public class LiftView extends ViewGroup {
    
    
        //当前是否打开
        private boolean isOpen;
        //滚动器
        private Scroller scroller;
        private FrameLayout fragment_mid;
        private FrameLayout fragment_lift;
        //左边FraLayout的宽度,指定宽度
        private int w = UIUtlis.dp2Px(150);
        //中间值
        private int mid = UIUtlis.dp2Px(150) / 2;
        private int startX;
        //自定义防抖数值
        private int dipX = 10;
    
        public LiftView(Context context) {
            super(context);
            initView(context);
        }
    
        public LiftView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView(context);
        }
    
        public LiftView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(context);
        }
    
        private void initView(Context context) {
    
            scroller = new Scroller(context);
    
        }
    
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            fragment_mid = (FrameLayout) getChildAt(0);
            fragment_lift = (FrameLayout) getChildAt(1);
            fragment_mid.layout(l, t, r, b);
            fragment_lift.layout(-w, t, 0, b);
        }
    
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //开始测量左边FrameLayout
    
            if (getChildCount() < 2) {
                throw new RuntimeException("指定孩子不能小于2个");
            }
            //左边的FrameLayout
            View childAt = getChildAt(1);
    
            int liftWidth = childAt.getLayoutParams().width;
            int width = MeasureSpec.makeMeasureSpec(liftWidth, MeasureSpec.EXACTLY);
    
            childAt.measure(width, heightMeasureSpec);
            getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = (int) event.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int endX = (int) event.getX();
                    int mid = endX - startX;
                    scrollBy(-mid, 0);
                    noMove(event);
                    animFrameLayout();
                    if (getScrollX() == -w) {
                        isOpen = true;
                        isOpenListener();
                    }
                    if (getScrollX() == 0) {
                        isOpen = false;
                        isOpenListener();
                    }
                    startX = endX;
                    break;
                case MotionEvent.ACTION_UP:
    
                    noMid();
                    break;
            }
            return true;
        }
    
        //判断是否拦截该事件
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
    
            int startX = 0;
    
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = (int) ev.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int endX = (int) ev.getX();
                    int mid = endX - startX;
                    //向左滑
                    if (mid > dipX) {
                        Log.e("拦截", "onInterceptTouchEvent: " + "开始拦截");
                        return true;
                    }
                    //向右滑
                    if (mid < -dipX) {
                        Log.e("拦截", "onInterceptTouchEvent: " + "开始拦截");
                        return true;
                    }
                    endX = startX;
                    break;
                case MotionEvent.ACTION_UP:
    
                    break;
            }
    
    
            return super.onInterceptTouchEvent(ev);
        }
    
    
        //如果在中间不能让它停留在中间
        private void noMid() {
            int scrollX = getScrollX();
    
            //直接关闭到右边测
            if (scrollX >= -mid) {
                moveIndex(0);
                isOpen = false;
    
            }
            //直接开启到左侧
            if (scrollX <= -mid) {
                moveIndex(-w);
                isOpen = true;
            }
    
        }
    
        //防止越界
        private void noMove(MotionEvent event) {
    
            int scrollX = getScrollX();
    
            //左边越界标准 //不能小于 -w
            if (scrollX <= -w) {
                scrollTo(-w, 0);
                isOpen = true;
            }
            //右边越界标准 //不能大于于0
            if (scrollX >= 0) {
                scrollTo(0, 0);
                isOpen = false;
            }
    
        }
    
        @Override
        public void computeScroll() {
            super.computeScroll();
    
            //滚动器的方法,需要重写
            if (scroller.computeScrollOffset()) {
                int currX = scroller.getCurrX();
                scrollTo(currX, 0);
                Log.e("----", "computeScroll: " + currX);
                if (currX == 0 || currX == -w) {
                    isOpenListener();
                }
                animFrameLayout();
            }
            invalidate();
        }
    
        //滚动到某个位置
        private void moveIndex(int index) {
            int scrollX = getScrollX();
            int dx = index - scrollX;
            //DX表示,从哪里滑到哪里,比如:从哪个起点滑到那个终点
            scroller.startScroll(scrollX, 0, dx, 0);
            invalidate();
        }
    
        public void setOpenAndClose(boolean isOpen) {
            if (isOpen) {
                //打开
                moveIndex(-w);
                this.isOpen = true;
            } else {
                //关闭
                moveIndex(0);
                this.isOpen = false;
            }
        }
    
    
        public boolean getOpenAndClose() {
    
            return isOpen;
        }
    
        //只要打开或者关闭就会调用
        private void isOpenListener() {
            if (isOpen) {
                UIUtlis.runOnUIToast("打开了");
    
            } else {
                UIUtlis.runOnUIToast("关闭了");
            }
    
            if (onOpenCloseListener != null)
                onOpenCloseListener.isOpen(isOpen);
        }
    
        private OnOpenCloseListener onOpenCloseListener;
    
        public void setOnOpenCloseListener(OnOpenCloseListener onOpenCloseListener) {
            this.onOpenCloseListener = onOpenCloseListener;
        }
    
        public interface OnOpenCloseListener {
            void isOpen(boolean isOpen);
        }
    
        public void animFrameLayout() {
    
    
      /*
            int scrollX = getScrollX();
            float i = (float) (Math.abs(scrollX) * 1.0 / w * 1.0);
    
            float i2 = (float) (1.0 - i);
            Log.e("----", "animFrameLayout: " + i);
            getChildAt(0).setScaleX((float) (i2));
            getChildAt(0).setScaleY((float) (i2));*/
    
    
        }
    }
    
    

    希望以上代码,对你的自定义控件有所帮助

    --XINHAO_HAN

    如果那块有不懂得请联我哟...0.0 哈哈

    使用

    <?xml version="1.0" encoding="utf-8"?>
    <com.example.downlist.view.LiftView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mySheView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    
        <FrameLayout
            android:id="@+id/mid"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#123456">
    
            <LinearLayout
                android:layout_width="300dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
    
    
    
    
            </LinearLayout>
    
        </FrameLayout>
    
        <FrameLayout
            android:id="@+id/lift"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#654321">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
    
    
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="dshshfhdskjfhdsf" />
    
            </LinearLayout>
    
    
        </FrameLayout>
    
    
    </com.example.downlist.view.LiftView>
    
    

    Demo下载:
    链接: https://pan.baidu.com/s/1i5P6WML 密码: 3283

    相关文章

      网友评论

          本文标题:自定义控件之侧滑栏

          本文链接:https://www.haomeiwen.com/subject/dclosxtx.html