仿SlidingMenu自定义QQ侧滑菜单

来源:互联网 发布:mysql 5.5.23.tar.gz 编辑:程序博客网 时间:2024/04/29 06:16

不多说,先上图

  • 主页面

这里写图片描述

  • 侧滑页面

这里写图片描述

一、首先我们要自定义一个DragLayout继承自FrameLayout

import android.content.Context;import android.graphics.Color;import android.graphics.PorterDuff;import android.support.v4.view.ViewCompat;import android.support.v4.widget.ViewDragHelper;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import com.nineoldandroids.view.ViewHelper;/** * ========================================= * 版权所有 违法必究 * 作者: huangxiaoguo */public class DragLayout extends FrameLayout {    private ViewDragHelper mViewDragHelper;    private ViewGroup mLeftPanel;    private ViewGroup mMainPanel;    private int mWidth;    private int mHeight;    private int mRange;    private DragState state = DragState.CLOSE;//默认关闭状态    public enum DragState {        OPEN, CLOSE, DRAGING    }    private OnDragChangeListener onDragChangeListener;    public OnDragChangeListener getOnDragChangeListener() {        return onDragChangeListener;    }    public void setOnDragChangeListener(OnDragChangeListener onDragChangeListener) {        this.onDragChangeListener = onDragChangeListener;    }    public interface OnDragChangeListener {        void onOpen();        void onClose();        void onDraging(float percent);    }    public DragLayout(Context context) {        this(context, null);    }    public DragLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //1 .初始化 ViewDragHelper        mViewDragHelper = ViewDragHelper.create(this, callback);    }    //2 事件转交 mViewDragHelper    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return mViewDragHelper.shouldInterceptTouchEvent(ev);    }    // 转交touch事件    @Override    public boolean onTouchEvent(MotionEvent event) {        try {            mViewDragHelper.processTouchEvent(event);        } catch (Exception e) {            e.printStackTrace();        }        return true;    }    // onmeasure 方法后调用    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        //左边面板的 范围//        mRange = (int) (mWidth * 0.6f);        mRange = (int) (mWidth * 0.8f);    }    //xml  --->view    @Override    protected void onFinishInflate() {        super.onFinishInflate();        //健壮性判断        mLeftPanel = (ViewGroup) getChildAt(0);        mMainPanel = (ViewGroup) getChildAt(1);    }    // mViewDragHelper 解析touch事件后   有的 回调    ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {        //  返回值 决定是否可以滑动        @Override        public boolean tryCaptureView(View child, int pointerId) {            return true;        }        //   修正  还没有真正的移动        @Override        public int clampViewPositionHorizontal(View child, int left, int dx) {            if (child == mMainPanel) { //拖动是mMainPanel                left = fixedLeft(left);            }            return left;        }        /**         * 修正主面板位置         * @param left         * @return         */        private int fixedLeft(int left) {            if (left < 0) {                left = 0;            } else if (left > mRange) {                left = mRange;            }            return left;        }        // 获取横向拖动范围  不决定实际的拖动范围        @Override        public int getViewHorizontalDragRange(View child) {            return mRange;        }        // 实际拖动的时候调用 1. 添加伴随动画 2. 更新状态 3.添加回调        @Override        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {            if (changedView == mLeftPanel) {  //如果拖动的是 changedView . 按到 之前的位置//                System.out.println("mLeftPanel>>>" + dx);                mLeftPanel.layout(0, 0, mWidth, mHeight);                // 只要  mLeftPanel移动  将瞬间变化交给mMainPanel                int currentLeft = mMainPanel.getLeft();                int newLeft = currentLeft + dx;                //重新 对位置修正                newLeft = fixedLeft(newLeft);                mMainPanel.layout(newLeft, 0, newLeft + mWidth, mHeight);            }            // 伴随动画  2.状态更新 3.添加回调            dispatchDragEvent(mMainPanel.getLeft());            //手动刷新            invalidate();        }        //当手指抬起的时候调用        @Override        public void onViewReleased(View releasedChild, float xvel, float yvel) {            //releasedChild 释放的子view            //xvel 释放时横向的速度   向左 - 向右 +    0            //yvel  释放时纵向的速度            if (xvel == 0 && mMainPanel.getLeft() > mRange * 0.5f) {                open();            } else if (xvel > 0) {                open();            } else {                close();            }        }    };    /**     * @param left 主面板 的 左边的坐标     */    private void dispatchDragEvent(int left) {//         0.0  -- 1.0        float percent = left * 1.0f / mRange;      //        10 / 111  =  0;        animView(percent);        DragState preState = state;        state = updateState(percent);        if (onDragChangeListener != null) {            onDragChangeListener.onDraging(percent);            if (state != preState) {                if (state == DragState.OPEN) {                    onDragChangeListener.onOpen();                } else if (state == DragState.CLOSE) {                    onDragChangeListener.onClose();                }            }        }    }    /**     * 更新状态     *     * @param percent     * @return     */    private DragState updateState(float percent) {        if (percent == 0) {            return DragState.CLOSE;        } else if (percent == 1) {            return DragState.OPEN;        }        return DragState.DRAGING;    }    /**     * 伴随动画     *     * @param percent     */    private void animView(float percent) {        //        1.0-----0.8      0.8+(1-percent)*0.2        //1. 主面板 缩小动画//        mMainPanel.setScaleX(0.8f+(1-percent)*0.2f);//        mMainPanel.setScaleY(0.8f+(1-percent)*0.2f);//        ViewHelper.setScaleX(mMainPanel, evaluate(percent, 1.0f, 0.8f));//        ViewHelper.setScaleY(mMainPanel, evaluate(percent, 1.0f, 0.8f));        ViewHelper.setScaleX(mMainPanel, evaluate(percent, 1.0f, 1.0f));        ViewHelper.setScaleY(mMainPanel, evaluate(percent, 1.0f, 1.0f));//        2 左边面板  缩放动画  平移动画        //0.7---1.0//        ViewHelper.setScaleX(mLeftPanel, evaluate(percent, 0.7f, 1.0f));//        ViewHelper.setScaleY(mLeftPanel, evaluate(percent, 0.7f, 1.0f));        ViewHelper.setScaleX(mLeftPanel, evaluate(percent, 1.0f, 1.0f));        ViewHelper.setScaleY(mLeftPanel, evaluate(percent, 1.0f, 1.0f));        //横向平移        ViewHelper.setTranslationX(mLeftPanel, evaluate(percent, -mWidth * 0.7f, 0));//        3 背景 黑色 -- -透明色        getBackground().setColorFilter((Integer) evaluateColor(percent, Color.BLACK, Color.TRANSPARENT), PorterDuff.Mode.SRC_OVER);    }    public Float evaluate(float fraction, Number startValue, Number endValue) {        float startFloat = startValue.floatValue();        return startFloat + fraction * (endValue.floatValue() - startFloat);    }    /**     * 颜色的估值器 @{link ArgbEvaluator}     *     * @param fraction     * @param startValue     * @param endValue     * @return     */    public Object evaluateColor(float fraction, Object startValue, Object endValue) {        int startInt = (Integer) startValue;        int startA = (startInt >> 24) & 0xff;        int startR = (startInt >> 16) & 0xff;        int startG = (startInt >> 8) & 0xff;        int startB = startInt & 0xff;        int endInt = (Integer) endValue;        int endA = (endInt >> 24) & 0xff;        int endR = (endInt >> 16) & 0xff;        int endG = (endInt >> 8) & 0xff;        int endB = endInt & 0xff;        return (int) ((startA + (int) (fraction * (endA - startA))) << 24) |                (int) ((startR + (int) (fraction * (endR - startR))) << 16) |                (int) ((startG + (int) (fraction * (endG - startG))) << 8) |                (int) ((startB + (int) (fraction * (endB - startB))));    }    //  和 ondraw 方法    @Override    public void computeScroll() {        super.computeScroll();        //是否继续触发动画        if (mViewDragHelper.continueSettling(true)) {            // 触发动画 执行动画            ViewCompat.postInvalidateOnAnimation(this);        }    }    public void open(boolean isSmooth) {        int finalLeft = mRange;        if (isSmooth) {            //返回值决定 是否触发动画            boolean b = mViewDragHelper.smoothSlideViewTo(mMainPanel, finalLeft, 0);            if (b) {                // 触发动画 执行动画                ViewCompat.postInvalidateOnAnimation(this);            }        } else {            mMainPanel.layout(finalLeft, 0, finalLeft + mWidth, mHeight);        }    }    /**     * 打开     */    public void open() {        open(true);//默认平滑打开    }    public void close(boolean isSmooth) {        int finalLeft = 0;        if (isSmooth) {            //返回值决定 是否触发动画            boolean b = mViewDragHelper.smoothSlideViewTo(mMainPanel, finalLeft, 0);            if (b) {                // 触发动画 执行动画                ViewCompat.postInvalidateOnAnimation(this);            }        } else {            mMainPanel.layout(finalLeft, 0, finalLeft + mWidth, mHeight);        }    }    /**     * 关闭     */    public void close() {        close(true);//默认平滑关闭    }}
  • 然后再xml中进行页面布局
<?xml version="1.0" encoding="utf-8"?><com.example.draglayout.view.DragLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/draglayout"    android:background="@color/colorPrimary">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        android:paddingBottom="50dp"        android:paddingLeft="16dp"        android:paddingRight="50dp"        android:paddingTop="50dp">        <ImageView            android:layout_width="55dp"            android:layout_height="55dp"            android:src="@mipmap/icon_head" />        <android.support.v7.widget.RecyclerView            android:id="@+id/left_recyclerView"            android:layout_width="match_parent"            android:layout_height="match_parent"/>    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="#fff"        android:orientation="vertical">        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="50dp"            android:background="#4a6ff4"            android:gravity="center_vertical">            <ImageView                android:id="@+id/iv_icon"                android:layout_width="35dp"                android:layout_height="35dp"                android:layout_marginLeft="8dp"                android:src="@mipmap/icon_head" />            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerInParent="true"                android:text="标题"                android:textColor="#ffffff"                android:textSize="20dp" />        </RelativeLayout>        <android.support.v7.widget.RecyclerView            android:id="@+id/main_recyclerView"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:cacheColorHint="@android:color/transparent"/>    </LinearLayout></com.example.draglayout.view.DragLayout>
  • 然后就是MainActivity中的操作了
import android.content.Context;import android.os.Bundle;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.ImageView;import com.example.draglayout.adapter.MyAdapter;import com.example.draglayout.utils.ToastUtil;import com.example.draglayout.view.DragLayout;import com.example.draglayout.view.RecycleViewDivider;import java.util.concurrent.CopyOnWriteArrayList;public class MainActivity extends AppCompatActivity {    private RecyclerView left_recyclerView;    private ImageView iv_icon;    private RecyclerView main_recyclerView;    private LinearLayoutManager manager;    private Context mContext;    private LinearLayoutManager manager1;    private MyAdapter myAdapter;    private MyAdapter myAdapter1;    private DragLayout dragLayout;    private CopyOnWriteArrayList<String> names = new CopyOnWriteArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext = this;        init();        initData();        initView();        initListener();    }    private void init() {        for (int i = 0; i < 50; i++) {            names.add("huangxiaoguo" + i);        }    }    private void initData() {        left_recyclerView = (RecyclerView) findViewById(R.id.left_recyclerView);        iv_icon = (ImageView) findViewById(R.id.iv_icon);        main_recyclerView = (RecyclerView) findViewById(R.id.main_recyclerView);        dragLayout = (DragLayout) findViewById(R.id.draglayout);        manager = new LinearLayoutManager(mContext);        manager.setOrientation(LinearLayoutManager.VERTICAL);        left_recyclerView.setLayoutManager(manager);        int mColor = ContextCompat.getColor(mContext, R.color.light_gray);        left_recyclerView.addItemDecoration(new RecycleViewDivider(mContext, LinearLayoutManager.HORIZONTAL, 2, mColor));        manager1 = new LinearLayoutManager(mContext);        manager1.setOrientation(LinearLayoutManager.VERTICAL);        main_recyclerView.setLayoutManager(manager1);        int mColor1 = ContextCompat.getColor(mContext, R.color.light_gray);        main_recyclerView.addItemDecoration(new RecycleViewDivider(mContext, LinearLayoutManager.HORIZONTAL, 2, mColor1));    }    private void initView() {        myAdapter = new MyAdapter(mContext, names);        left_recyclerView.setAdapter(myAdapter);        myAdapter1 = new MyAdapter(mContext, names);        main_recyclerView.setAdapter(myAdapter1);        dragLayout.setOnDragChangeListener(new DragLayout.OnDragChangeListener() {            @Override            public void onOpen() {                ToastUtil.showToast(MainActivity.this, "打开");            }            @Override            public void onClose() {                ToastUtil.showToast(MainActivity.this, "关闭");            }            @Override            public void onDraging(float percent) {                ToastUtil.showToast(MainActivity.this, "偏移距离= " + percent);            }        });    }    private void initListener() {        myAdapter1.setOnItemClickListener(new MyAdapter.OnItemClickListener() {            @Override            public void OnClick(int position) {                ToastUtil.showToast(MainActivity.this, names.get(position));                dragLayout.close();            }        });        iv_icon.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                dragLayout.close();            }        });    }}

好了这样局基本实现了

Demo下载地址:http://download.csdn.net/download/huangxiaoguo1/9732303

0 0
原创粉丝点击