自定义控件之侧滑栏

最终效果图

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

猜你喜欢

转载自blog.csdn.net/qq_31392539/article/details/93721415