QQ5.0 侧滑栏效果

QQ5.0 侧滑栏效果

标签: Android 侧滑


我看见挺多APP采用的是这种一滑整个界面都向右移的方式。
这里采用的是 HorizontalScrollView(水平滑动视图) 布局的滑动特性。
就是两个界面放在一起,实现界面的滑动
先是布局界面

<?xml version="1.0" encoding="utf-8"?>
<com.example.myslidingmenu.MySlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns="http://schemas.android.com/tools"
    xmlns:zhy="http://schemas.android.com/apk/com.example.myslidingmenu"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:scrollbars="none"
    zhy:rightPadding="100dp">

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

        <ListView
            android:id="@+id/list_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#45f78f"
            android:listSelector="?attr/selectableItemBackground"
            xmlns:android="http://schemas.android.com/apk/res/android">
        </ListView>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#123345">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="this is one "
                android:textSize="30sp"/>
        </LinearLayout>
    </LinearLayout>
</com.example.myslidingmenu.MySlidingMenu>

就放了两个东西一个是ListView,另一个是TextView。
接下来是自定义MySlidingMenu的具体代码:

/**
 * Created by hero on 2015/12/27.
 */
public class MySlidingMenu  extends HorizontalScrollView {
    //屏幕宽度
    private int mScreemWidth;
    //
    private int mMenuRightPending;
    /**
     * 菜单宽度
     */
    private int mMenuWidth;
    private int mHalfMenuWidth;

    private boolean once ;
    /**
     *
     * @param context
     * @param attrs
     */

    public MySlidingMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScreemWidth = getScreemWidth(context);        //获得屏幕宽度
    }

    /**
     * 获取屏幕宽度的方法
     * @param context
     * @return
     */
    private int getScreemWidth(Context context){
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display mDisplay = manager.getDefaultDisplay();
        Point mPoint = new Point();
        mDisplay.getSize(mPoint);
        return mPoint.x;
    }
    public MySlidingMenu(Context context,AttributeSet attr,int defStyle){
        super(context,attr,defStyle);
        mScreemWidth = getScreemWidth(context);      //获得屏幕宽度
        //从布局文件中获得自定义属性(不是很懂)
        TypedArray a = context.getTheme().obtainStyledAttributes(attr,R.styleable.MySlidingMenu,defStyle,0);
        int n = a.getIndexCount();
        for (int i =0;i<n;i++){
            int mAttr = a.getIndex(i);
            switch (mAttr){
                case R.styleable.MySlidingMenu_rightPadding:
                    mMenuRightPending = a.getDimensionPixelSize(mAttr,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50f,getResources().getDisplayMetrics()));
            }
        }
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (!once){
            LinearLayout wrapper = (LinearLayout) getChildAt(0);
            ViewGroup menu = (ViewGroup) wrapper.getChildAt(0);         //布局中的第一个容器从左到右,即侧滑菜单是第一个
            ViewGroup content = (ViewGroup) wrapper.getChildAt(1);      //布局中的第二个容器,即主界面。
            //dp to px
      //      mMenuRightPending = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,mMenuRightPending,content.getResources().getDisplayMetrics());
     //       mMenuRightPending = 900;
            mMenuRightPending = mScreemWidth*2/3;
            mMenuWidth = mScreemWidth - mMenuRightPending;  //侧滑出的菜单的宽度
            mHalfMenuWidth = mMenuWidth/2;                  //菜单宽度的一半用于触摸判断
            menu.getLayoutParams().width = mMenuWidth;      //设置菜单宽度
            content.getLayoutParams().width = mScreemWidth;//设置主界面宽度
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //初始化时调用
        //onMeasure
        //onLayout(再次调用了onMeasure)
        //onMeasure
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //第一次建立时调用
        if (changed){
            //将菜单隐藏
            Log.d("onLayout","scrollTo");
            this.scrollTo(mMenuWidth,0);
            once = true;
        }
    }

    /**
     * 触控行为时调用
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        //判断滑动类型
        switch (action){
            case MotionEvent.ACTION_UP:
                /**
                 * scrollx 当前VIEW相对原点(母容器最左端)的距离
                 * 母容器全长mScreemWidth=1440,侧栏隐藏时scrollx=480,既
                 * mMenuRightPending = mScreemWidth*2/3;
                 * mMenuWidth = mScreemWidth - mMenuRightPending;  //侧滑出的菜单的宽度
                 *
                 */
                int scrollx = getScrollX();

                if (scrollx>mHalfMenuWidth){
                    this.smoothScrollTo(mMenuWidth,0);
                    Log.d("onTouchEvent", mScreemWidth+"smoothScrollTo(mMenuWidth,0)"+scrollx);
                }else{
                    /**
                     * smoothScrollTo(x,y)  相对原点的距离(母容器最左端)
                     * 0,0既从母容器最左端显示
                     */
                    this.smoothScrollTo(0,0);       //显示侧边
                    Log.d("onTouchEvent", mScreemWidth+"smoothScrollTo(0,0)"+scrollx);
                }
                return true;
        }
        return super.onTouchEvent(ev);
    }
}

核心部分:

smoothScrollTo(0,0);
X轴,Y轴偏移量为0,界面显示从最左边开始
偏移量相对于母容器即MySlidingMenu左上顶点

int scrollx = getScrollX();
/**
* scrollx 当前VIEW相对原点(母容器最左端)的距离
* 母容器全长mScreemWidth=1440,侧栏隐藏时scrollx=480,既
* mMenuRightPending = mScreemWidth*2/3;
* mMenuWidth = mScreemWidth - mMenuRightPending; //侧滑出的菜单的宽度
*
*/

使用app:layout_behavior属性时gradel文件要添加下面一句话

compile 'com.android.support:design:23.0.0'

侧滑时实现菜单在界面后

QQ5.0的样式并不是这么简单的一拉就出来,需要添加点动画。
在我们滑动的时候,菜单应该像是在界面的后面
那就相当于不断的改变菜单的位置,让它一直处于屏幕的左边。
就重写了一个方法

 @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //获得一个比例1-0
        //菜单不显示是为1,显示时为0
        float p = l*1.0f/menuWidth;

        menu.setTranslationX((float) (0.85*menuWidth*p));
    }

界面发生更改时执行。

menu.setTranslationX((float) (0.7*menuWidth*p));
不断改变菜单的位置实现效果。
同时也可以改变宽度和高度,同时实现缩放。

这里有一个重点:
HorizontalScrollView中两个VIEW发生重叠时其中一个VIEW重叠部分不显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值