仿QQ5.0的侧滑菜单

这里写图片描述

第一步:设置菜单的布局,left_menu.xml

<?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:background="@drawable/img_frame_background" >

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
         android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/image1"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@drawable/img_1" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image1"
                android:text="第一个item"
                android:textColor="#ffffff"
                android:textSize="20sp" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/image2"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@drawable/img_2" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image2"
                android:text="第二个item"
                android:textColor="#ffffff"
                android:textSize="20sp" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/image3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@drawable/img_3" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image3"
                android:text="第三个item"
                android:textColor="#ffffff"
                android:textSize="20sp" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/image4"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@drawable/img_4" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image4"
                android:text="第四个item"
                android:textColor="#ffffff"
                android:textSize="20sp" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/image5"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@drawable/img_5" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image5"
                android:text="第五个item"
                android:textColor="#ffffff"
                android:textSize="20sp" />
        </RelativeLayout>

    </LinearLayout>
</RelativeLayout>

这里写图片描述

android:src与android:background的区别:
http://blog.csdn.net/dalleny/article/details/14048375


第二步:改写activity_main.xml的代码,实现总的布局

<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" >

    <!-- SlidingMenu继承自HorizontalScrollView -->
    <com.example.sideslipfollowqq5_0.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/qq" >      
           </LinearLayout>

        </LinearLayout>

    </com.example.sideslipfollowqq5_0.SlidingMenu>

</RelativeLayout>

注意:HorizontalScrollView的内部只能有一个控件


第三步:实现SlidingMenu.java

自定义ViewGroup需要做的事:
1、 onMeasure
决定内部View(子View)的宽和高,(可选,因为有时候在.xml文件中会设置成”match_parent”)以及自己的宽和高
2、 onLayout
决定子View放置的位置
3、 onTounchEvent(可选)
决定内部View的移动效果或者变化

public class SlidingMenu extends HorizontalScrollView {
    private LinearLayout mWapper;//activity_main.xml中com.example.sideslipfollowqq5_0.SlidingMenu布局
    private ViewGroup mMenu;//activity_main.xml中include的布局
    private ViewGroup mContent;//activity_main.xml中第二个LinearLayout布局

    private int mScreenWidth;//屏幕的宽度

    private int mMenuRightPadding;//菜单完全显示时与屏幕右侧的距离(在SlidingMenu中设置成一个固定值)

    private boolean isOnce=true;//因为onMeasure又可能会多次调用(影响效率),这里用于判断onMeasure是否是第一次调用

    private int mMenuWidth;//代表mMenu的宽度

    /**
     * 未使用自定义属性时调用(使用自定义属性会在下一篇说明)
     * @param context
     * @param attrs
     */
    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);//getMetrics将会为传入的outMetrics赋值
        mScreenWidth=outMetrics.widthPixels;

        //将50dp转化成相应的px
        //因为dp是相对于分辨率的,而px就是一个像素点,是固定大小的
        //为了在不同分辨率的屏幕上显示的效果相同,应该将mMenuRightPadding依据不同的分辨率而变换
        mMenuRightPadding=(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
    }

    /**
     * 设置子View的宽和高以及自己的宽和高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (isOnce) {
            mWapper = (LinearLayout) getChildAt(0);// 得到activity_main.xml中SlidingMenu布局下的第一个元素,即activity_main.xml中第一个LinearLayout
            mMenu = (ViewGroup) mWapper.getChildAt(0);
            mContent = (ViewGroup) mWapper.getChildAt(1);

            mMenuWidth=mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;// 设置mMenu的宽度
            mContent.getLayoutParams().width = mScreenWidth;
            isOnce = false;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 通过设置偏移量,一开始就将menu隐藏
     */
    @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) {
        int action=ev.getAction();//通过action判断用户的操作,是按下、抬起、还是在移动
        switch (action) {
        case MotionEvent.ACTION_UP:
            int scrollX=(int) getScrollX();//得到未在屏幕显示出的内容的左侧区域宽度(即左侧隐藏的宽度),动态变化的
            if(scrollX>=mMenuWidth/2) {
                this.smoothScrollTo(mMenuWidth, 0);
                //this.scrollTo(mMenuWidth, 0);
                //如果内容隐藏的区域>=菜单的一半,隐藏菜单
                //smoothScrollTo方法与scroolTo相似,只不过scroolTo是瞬间完成,而该方法有一个缓冲的效果
            }
            else {
                this.smoothScrollTo(0, 0);
            }
            return true;
        default:
            break;
        }
        return super.onTouchEvent(ev);
    }
}

scrollTo(int x,int y) :当第一个参数为正时,滚动条向左移动,内容区域向右移动
将一个视图的内容移动到指定位置(即给定的x、y坐标).此时偏移量 mScrollX,mScrollY就分别等于x,y,该动作是瞬间完成的,无法给用户一个缓冲的感觉(smoothScrollTo则具有缓冲效果)
进一步了解请参考:http://www.tuicool.com/articles/JBFrauZ

getScrollX():得到未在屏幕显示出的内容的左侧区域(即左侧隐藏的宽度)
这里写图片描述

关于TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
请参考:http://www.cnblogs.com/xilinch/p/4444833.html


第四步:修改MainActivity.java,隐藏活动的标题

public class MainActivity extends Activity {

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

源码:http://download.csdn.net/download/qq_22804827/9284053

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值