三种侧滑的实现(仿qq,抽屉侧滑,普通侧滑)

自己实现了一下侧滑的三种方式(注释都写代码里了)
本文Demo下载地址:http://download.csdn.net/detail/gywuhengy/9818357
本文实现所需框架:nineoldandroids下载地址:http://download.csdn.net/detail/gywuhengy/9818304

1.普通侧滑:
主要是基于HorizontalScrollView做的:示例代码如下
主要布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:gaoyu="http://schemas.android.com/apk/res/gaoyu.com.myapplication"

    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_qqsideslip"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="gaoyu.com.myapplication.sideslip.QQSideslipActivity">

    <!--xmlns:gaoyu自定义命名空间 原有到res+包名-->

    <gaoyu.com.myapplication.sideslip.SlidingMenu_qq
        android:id="@+id/SlMenu_sideslip"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        gaoyu:rightPadding="100dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <include layout="@layout/sideslip_menu" />
            <!--这个LinearLayout就是content-->
            <LinearLayout

                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/sliding">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="onClick_sideslip_qq"
                    android:text="切换菜单" />
            </LinearLayout>

        </LinearLayout>
    </gaoyu.com.myapplication.sideslip.SlidingMenu_qq>


</RelativeLayout>

菜单的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_centerInParent="true">
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iv_sideslip1"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:src="@drawable/icon"/>
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/iv_sideslip1"
                android:layout_marginLeft="20dp"
                android:text="第一个item"/>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iv_sideslip2"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:src="@drawable/icon"/>
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/iv_sideslip2"
                android:layout_marginLeft="20dp"
                android:text="第二个item"/>
        </RelativeLayout><RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iv_sideslip3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:src="@drawable/icon"/>
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/iv_sideslip3"
                android:layout_marginLeft="20dp"
                android:text="第三个item"/>
        </RelativeLayout><RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iv_sideslip4"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:src="@drawable/icon"/>
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/iv_sideslip4"
                android:layout_marginLeft="20dp"
                android:text="第四个item"/>
        </RelativeLayout><RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iv_sideslip5"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:src="@drawable/icon"/>
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/iv_sideslip5"
                android:layout_marginLeft="20dp"
                android:text="第五个item"/>
        </RelativeLayout>
    </LinearLayout>

</RelativeLayout>

定义view类

public class SlidingMenu_qq extends HorizontalScrollView {

    private LinearLayout mWapper;
    private ViewGroup mMenu;
    private ViewGroup mContent;
    //menu的宽度
    private int mMenuWidth;
    //屏幕的宽度(内容区的宽度就是屏幕宽度)
    private int mScreenWdith;
    //菜单与右边的距离50dp
    private int mMenuRightPidding = 50;
    //调用一次
    private boolean once;
    //标识状态
    private boolean isOPen;

    /**
     * 未使用自定义属性时调用
     * 由于设置了attr所以...
     *
     * @param context
     * @param attrs
     */
    public SlidingMenu_qq(Context context, AttributeSet attrs) {
        //调用三个参数的构造方法
        this(context, attrs, 0);
        //获取屏幕宽度(窗口管理器)
        /*WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        //展示度量
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWdith = outMetrics.widthPixels;
        //把dp转换成px
        mMenuRightPidding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
*/
    }

    /**
     * 当实现自定义属性时会执行三个参数的方法
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public SlidingMenu_qq(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //获取自定义的属性

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu_qq, defStyleAttr, 0);
        //自定义属性个数
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.SlidingMenu_qq_rightPadding:
                    //设置默认值是50dp
                    mMenuRightPidding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics()));

                    break;
            }

        }
        //释放一下
        a.recycle();

        //获取屏幕宽度(窗口管理器)
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        //展示度量
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWdith = outMetrics.widthPixels;

    }

    /**
     * new 一个TextView时传一个上下文
     *
     * @param context
     */
    public SlidingMenu_qq(Context context) {
        //调用两个参数的构造方法
        super(context, null);
    }

    /**
     * 设置HorizontalScrollView子VIew的宽和高
     * 设置HorizontalScrollView自己的宽和高
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //设置循环之调用一次
        if (!once) {
            //HorizontalScrollView 内部只能有一个元素 所以直接get(0)就行就是那个Linerlayout mWapper
            mWapper = (LinearLayout) getChildAt(0);
            //获取mWapper里的第一个元素menu
            mMenu = (ViewGroup) mWapper.getChildAt(0);
            //获取mWapper里的第二个元素content
            mContent = (ViewGroup) mWapper.getChildAt(1);
            //菜单和内容宽度
            mMenuWidth = mMenu.getLayoutParams().width = mScreenWdith - mMenuRightPidding;
            mContent.getLayoutParams().width = mScreenWdith;
            //由于子对象被设置了,mWapper就先不用了
            once = true;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 通过设置偏移量 将menu隐藏
     * @param changed
     * @param l
     * @param t
     * @param r
     * @param b
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //限制多次调用
        if (changed) {
            //x为正滚动条向右 内容向左(移动mMenuWidth 正好将菜单隐藏)
            this.scrollTo(mMenuWidth, 0);
        }
    }

    /**
     * 判断将菜单滑出来多少了
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:
                //隐藏在左边的宽度
                int scrollX = getScrollX();
                if (scrollX >= mMenuWidth / 2) {
                    //scrollTo也行但是动画效果不好  (隐藏)
                    this.smoothScrollTo(mMenuWidth, 0);
                    //代表菜单隐藏
                    isOPen = false;
                } else {
                    this.smoothScrollTo(0, 0);
                    //表菜单打开
                    isOPen = true;
                }
                return true;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 打开菜单
     */
    public void openMenu() {
        //已经打开
        if (isOPen) return;
        this.smoothScrollTo(0, 0);
        isOPen = true;
    }

    /**
     * 关闭菜单
     */
    public void closeMenu() {
        //正在打开
        if (!isOPen) return;
        this.smoothScrollTo(mMenuWidth, 0);
        isOPen = false;
    }

    /**
     * 切换菜单
     */
    public void toggle(){
        if (isOPen){
            closeMenu();
        }else {
            openMenu();
        }
    }
}

2.抽屉侧滑(添加此方法)

/**
     * 实现抽屉滑动
     * l隐藏在左边的宽度
     * 后边是变化梯度
     */

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        float scale = l*1.0f/mMenuWidth;//1~0梯度的值
        //调用属性动画
        ViewHelper.setTranslationX(mMenu,mMenuWidth*scale);
    }

3.qq5.0侧滑 实现这个方法

 /**
     * 实现仿qq5.0
     * l等于隐藏在左边的宽度(越来越小)
     * 后边是变化梯度
     */

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        float scale = l * 1.0f / mMenuWidth;//1~0梯度的值

        //调用属性动画

        //菜单的缩放操作
        float leftScale = 1.0f-scale*0.3f;
        //透明度
        float leftAlpha = 0.6f + 0.4f*(1-scale);
        ViewHelper.setTranslationX(mMenu, mMenuWidth * scale*0.8f);
        ViewHelper.setScaleX(mMenu,leftScale);
        ViewHelper.setScaleY(mMenu,leftScale);
        ViewHelper.setAlpha(mMenu,leftAlpha);

        //内容区域不断缩小
        float rightScale = 0.7f+0.3f*scale;
        //横向纵向缩放(不更改缩放中心点就全隐藏了)
        ViewHelper.setPivotX(mContent,0);
        ViewHelper.setPivotY(mContent,mContent.getHeight()/2);
        ViewHelper.setScaleX(mContent,rightScale);
        ViewHelper.setScaleY(mContent,rightScale);

    }

猜你喜欢

转载自blog.csdn.net/gywuhengy/article/details/70238860
今日推荐