android5.0多种侧滑栏效果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android5.0多种侧滑栏效果相关的知识,希望对你有一定的参考价值。

1.普通侧滑
效果图:技术分享
思路:通过自定义View继承HorizontalScrollView,然后重写onMeasure(),onLayout(),onTouchEvent()
方法并设置menu(通过动画使menu开始时处于隐藏状态)布局和content布局。(注意:使用ViewHelper类需要导入nineoldandroids-2.4.0.jar包)
menu(left_menu)布局代码:

<?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">
    <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/id_img1"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/img_1"/>
            <TextView
                android:id="@+id/iv_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第一个item"
                android:textSize="21sp"
                android:textColor="#ffffff"
                android:layout_toRightOf="@+id/id_img1"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/id_img2"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/img_2"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第二个item"
                android:textSize="21sp"
                android:textColor="#ffffff"
                android:layout_toRightOf="@+id/id_img2"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/id_img3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/img_3"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第三个item"
                android:textSize="21sp"
                android:textColor="#ffffff"
                android:layout_toRightOf="@+id/id_img3"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/id_img4"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/img_4"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第四个item"
                android:textSize="21sp"
                android:textColor="#ffffff"
                android:layout_toRightOf="@+id/id_img4"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/id_img5"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/img_5"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第五个item"
                android:textSize="21sp"
                android:textColor="#ffffff"
                android:layout_toRightOf="@+id/id_img5"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
    </LinearLayout>
</RelativeLayout>

content(activity_main)布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hyname="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/img_frame_background">
    <com.imooc.view.SlidingMenu
        android:id="@+id/id_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        hyname:rightPadding="100dp">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">
            <include layout="@layout/left_menu"/>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:background="@mipmap/qq">
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="切换菜单"
                    android:onClick="toogleMenu"
                    android:textSize="21sp"/>
            </LinearLayout>
        </LinearLayout>
    </com.imooc.view.SlidingMenu>
</LinearLayout>

自定义attr.xml文件代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="rightPadding" format="dimension"/>
    <declare-styleable name="SlidingMenu">
        <attr name="rightPadding"></attr>
    </declare-styleable>
</resources>

自定义SlidingMenu代码:

public class SlidingMenu extends HorizontalScrollView {
    private LinearLayout mWapper;
    private ViewGroup mMenu;//菜单布局
    private ViewGroup mContent;//内容布局
    private int mScreenWidth;//屏幕宽度
    private int mMenuRightPadding=50;
    private boolean once;
    private int mMenuWidth;
    private boolean isOpen;

    public SlidingMenu(Context context) {
       this(context, null);
    }

    /**
     * 未使用自定义属性时,调用
     * @param context
     * @param attrs
     */
    public SlidingMenu(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    /**
     * 自定义了属性且使用时,调用次构造方法
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取定义的属性的数组
        TypedArray typedValue=context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu, defStyleAttr, 0);
        int n=typedValue.getIndexCount();
        for (int i=0;i<n;i++){
            int attr=typedValue.getIndex(i);
            switch (attr){
                case  R.styleable.SlidingMenu_rightPadding:
                mMenuRightPadding=typedValue.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,context.getResources().getDisplayMetrics()));
                    break;
            }
        }
        typedValue.recycle();
        WindowManager mg= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        //初始化屏幕信息对象
        DisplayMetrics outMetrics=new DisplayMetrics();
        //把屏幕的信息存储到DisplayMetrics中
        mg.getDefaultDisplay().getMetrics(outMetrics);
        //获取屏幕宽度赋值给mScreenWidth
        mScreenWidth=outMetrics.widthPixels;
    }

    /**
     * 设置子view的宽和高
     * 设置自己的宽和高
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if(!once){
            //获取SlidingMenu中的Linearlayout布局
            mWapper= (LinearLayout) getChildAt(0);
            //获取LinearLayout中的menu布局
            mMenu= (ViewGroup) mWapper.getChildAt(0);
            //获取LinearLayout中的Content布局
            mContent= (ViewGroup) mWapper.getChildAt(1);
            //获取menu宽度
            mMenuWidth= mMenu.getLayoutParams().width=mScreenWidth-mMenuRightPadding;
            //设置content的宽度
            mContent.getLayoutParams().width=mScreenWidth;
            mWapper.getLayoutParams().width=mScreenWidth;
            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){
            this.scrollTo(mMenuWidth,0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_UP:
                //隐藏在左边的宽度
                int scrollX=getScrollX();
                if (scrollX>=mMenuWidth/2){
                    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();
        }
    }
}

主文件代码:

public class MainActivity extends AppCompatActivity {
    private SlidingMenu mleftMenu;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mleftMenu= (SlidingMenu) findViewById(R.id.id_menu);
        textView= (TextView) findViewById(R.id.iv_text);
        //menu的第一个Item的点击事件,可不写
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mleftMenu.toggle();
            }
        });
    }

    public void toogleMenu(View view){
        mleftMenu.toggle();
    }
}

2.抽屉式侧滑(一)
效果图:技术分享
思路:在原来的基础上,在自定义View文件中重写onScrollChanged()方法
添加代码:

/**
     * 滚动时发生
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //调用属性动画,设置TranslateX,l值为menu隐藏的宽度,menu由完全隐藏变为完全可见,变化梯度                scale由1~0,menu偏移量由大到小;
        float scale=l*1.0f/mMenuWidth; //1~0
        ViewHelper.setTranslationX(mMenu, mMenuWidth * scale);
    }

3.抽屉式侧滑(二)
效果图:技术分享
思路:在一的基础上通过设置menu的缩放效果,content的缩放效果和缩放中心实现。
实现代码:

/**
     * 滚动发生
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //调用属性动画,设置TranslateX,l值为menu隐藏的宽度,menu由完全隐藏变为完全可见,变化梯度scale由1~0,menu偏移量由大到小;
        float scale=l*1.0f/mMenuWidth; //1~0
//        ViewHelper.setTranslationX(mMenu, mMenuWidth * scale);
        float leftScale=1.0f-scale*0.3f;  //0.7~1.0
        float leftAlpha=0.6f+0.4f*(1-scale); //0.6~1.0
        float rightScale=0.7f+0.3f*scale; //1.0~0.7
        //缩放动画0.7~1.0
        ViewHelper.setScaleX(mMenu, leftScale);
        ViewHelper.setScaleY(mMenu, leftScale);
        //透明度变化0.6~1.0
        ViewHelper.setAlpha(mMenu, leftAlpha);
        ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.7f);
        ViewHelper.setPivotX(mContent, 0);
        ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);
        //缩放动画1.0~0.7
        ViewHelper.setScaleX(mContent, rightScale);
        ViewHelper.setScaleY(mContent,rightScale);
    }

有不懂的地方可以到慕课网听讲解:http://www.imooc.com/learn/211
图片来源于:http://blog.csdn.net/lmj623565791/article/details/39257409博客。












以上是关于android5.0多种侧滑栏效果的主要内容,如果未能解决你的问题,请参考以下文章

android:QQ多种侧滑菜单的实现

页面侧滑栏效果

侧滑栏效果的实现

华为底部虚拟导航栏挡住布局

Android实现侧滑recycleView+CardVeiw卡片阴影效果

Android实现侧滑recycleView+CardVeiw卡片阴影效果