Android SlidingMenu多种方法详解

最近学App的时候经常会用到侧滑的效果,所以对学习到的方法进行一个总结

1.普通Sliding
在activity_main.xml利用Android自带的HorizontalScrollView实现(里面只允许放一个控件)
以下是具体的代码

主布局 activity_main.xml 在LinearLayout里包含一个left_menu菜单模块和内容模块(这里为了简单些 所以只放了一张图片)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.view.SlidingMenu
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <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:background="@drawable/bg_playing" >
            </LinearLayout>
        </LinearLayout>
    </com.example.view.SlidingMenu>

</RelativeLayout>

菜单布局 left_menu.xml 简单做几个按钮当测试用的

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

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2" />
</LinearLayout>

实现方法 SlidingMenu.java

自定义ViewGroup
1.onMeasure
设置内部View以及自己的宽和高
2.onLayout
决定子View摆放的位置
*3.onTouchEvent

package com.example.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class SlidingMenu extends HorizontalScrollView {

    private LinearLayout mWapper;  //大布局
    private ViewGroup mMenu; //菜单布局
    private ViewGroup mContent; //内容布局
    private int mMenuRightPadding=0; //滑出的菜单界面距离屏幕右边界的距离
    private boolean once = false;
    private int mScreenWidth;//屏幕宽度
    private int mMenuWidth;   //菜单宽度

    public SlidingMenu(Context context, AttributeSet attrs) {
        super(context, attrs);

        //获取屏幕宽度
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;

        // 将mMenuRightPadding的dp转化为px(像素值)
        mMenuRightPadding = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 150, context.getResources()
                        .getDisplayMetrics());
    }


    /**
     * 设置内部View以及自己的宽和高
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        if (!once) {
            mWapper = (LinearLayout) getChildAt(0);  //获取Layout 即大布局
            mMenu = (ViewGroup) mWapper.getChildAt(0); //获取菜单布局
            mContent = (ViewGroup) mWapper.getChildAt(1); //获取内容布局
            mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth  //设置菜单的宽度
                    - mMenuRightPadding;
            mContent.getLayoutParams().width = mScreenWidth; //设置内容的宽度

            once = true;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 设置子View的摆放位置
     * 设置偏移量 将Menu隐藏
     */
    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) {

        int action = ev.getAction();
        switch (action) {
        case MotionEvent.ACTION_UP:

            //初始为菜单的宽度   在滑动之后变成菜单隐藏在左边的宽度
            int ScrollX = getScrollX();
            if (ScrollX >= mMenuWidth / 2) {
                this.smoothScrollTo(mMenuWidth, 0);
            }else{
                this.smoothScrollTo(0, 0);

            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

}

MainActivity太简单就不写了

这是第一种方法,实现起来比较简单 ,但效果比较一般,并且还没加入自定义属性。

2.加入自定义属性Sliding
实现步骤:
1.在value中新建一个attr.xml
2.在布局文件中使用
3.在三个参数的构造方法中获取信息

实现目标
一.允许用户自定义菜单滑出的距离

下面是代码,根据上面三点进行操作
1.在value中新建一个attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="rightPadding" format="dimension"></attr>

    <declare-styleable name="SlidingMenu">
        <attr name="rightPadding"></attr>
    </declare-styleable>

</resources>

2.修改activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
  xmlns:demo="http://schemas.android.com/apk/res/com.example.z14sliding"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.view.SlidingMenu
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        demo:rightPadding="150dp">

        <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:background="@drawable/bg_playing" >
            </LinearLayout>
        </LinearLayout>
    </com.example.view.SlidingMenu>



</RelativeLayout>

3.修改SlidingMenu.java 只改变了构造函数部分

public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // 获取定义的属性
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.SlidingMenu, defStyle, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
            case R.styleable.SlidingMenu_rightPadding:
                mMenuRightPadding = a.getDimensionPixelOffset(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);
        mScreenWidth = outMetrics.widthPixels;
    }

二.添加按钮触发侧滑

1.修改SlidingMenu.class

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.MainActivity.class添加监听

package com.example.z14sliding;

import com.example.view.SlidingMenu;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.Window;

public class MainActivity extends Activity {

    private SlidingMenu mleftMenu;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mleftMenu =(SlidingMenu) findViewById(R.id.menu);
    }

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

至此第一种普通的侧滑讲解完了,下一步我们进阶讲一下抽屉式侧滑

3.抽屉式侧滑
初始菜单偏移量为宽度 设为300
当移动100dp时 偏移为200
当移动30pd时 偏移为270

实现:
1.修改SlidingMenu.class

/**
     * 滚动发生时自动调用
     */
    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);
    }

4.终极目标:QQ侧滑效果
1.内容区域 1~0.7 的缩放效果
scale 1.0~0
0.7+0.3*scale
2.菜单偏移量修改

3.菜单显示时的缩放以及透明度变化
缩放:0.7~1.0
1.0-0.3*scale
透明度 0.6~1.0
0.6+0.4*(1-scale)

SlidingMenu.class

    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*0.7f);

        //内容区域缩放以及中心点设置
        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);

        //菜单
        float leftScale=1.0f-scale*0.3f;
        float leftAlpha=0.6f+0.4f*(1-scale);
        ViewHelper.setScaleX(mMenu, leftScale);
        ViewHelper.setScaleY(mMenu, leftScale);
        ViewHelper.setAlpha(mMenu, leftAlpha);

    }

好了 这就是Sliding的全部内容了,写了好久,也对Sliding有了更深的理解!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值