Android自定义HorizontalScrollView实现qq侧滑菜单
程序员文章站
2022-06-06 17:17:51
今天看了鸿洋_大神在慕课网讲的qq5.0侧滑菜单。学了不少的知识,同时也佩服鸿洋_大神思路的清晰。
看了教程课下也自己实现了一下。代码几乎完全相同 别喷我啊。...
今天看了鸿洋_大神在慕课网讲的qq5.0侧滑菜单。学了不少的知识,同时也佩服鸿洋_大神思路的清晰。
看了教程课下也自己实现了一下。代码几乎完全相同 别喷我啊。。没办法 o(︶︿︶)o 唉
像素不好 没办法 找不到好的制作gif的软件。
我们暂且称侧滑左边界面的为menu,右边为content
首先是menu的布局
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/img_frame_background" > <linearlayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerinparent="true" android:orientation="vertical" > <relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/image1" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginleft="20dp" android:src="@drawable/img_1" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:layout_torightof="@id/image1" android:textcolor="#ffffff" android:layout_marginleft="20dp" android:text="第一个item" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <imageview android:id="@+id/image2" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginleft="20dp" android:src="@drawable/img_2" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:layout_torightof="@id/image2" android:textcolor="#ffffff" android:layout_marginleft="20dp" android:text="第二个item" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <imageview android:id="@+id/image3" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginleft="20dp" android:src="@drawable/img_3" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:layout_torightof="@id/image3" android:textcolor="#ffffff" android:layout_marginleft="20dp" android:text="第三个item" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <imageview android:id="@+id/image4" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginleft="20dp" android:src="@drawable/img_4" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:layout_torightof="@id/image4" android:textcolor="#ffffff" android:layout_marginleft="20dp" android:text="第四个item" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <imageview android:id="@+id/image5" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginleft="20dp" android:src="@drawable/img_5" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:layout_torightof="@id/image5" android:textcolor="#ffffff" android:layout_marginleft="20dp" android:text="第五个item" android:textsize="20sp" /> </relativelayout> </linearlayout> </relativelayout>
然后是主布局,一个水平滚动条,放入menu.xml,然后下面是一个线性垂直布局,背景是qq图片
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.example.myhorizontalscrollview.myhorizontalscrollview android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none"> <linearlayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="horizontal" > <include layout="@layout/menu" /> <linearlayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/qq" /> </linearlayout> </com.example.myhorizontalscrollview.myhorizontalscrollview> </relativelayout>
其中的水平滚动条是我们自定义的view
需要重写其中的两个方法
@override protected void onlayout(boolean changed, int l, int t, int r, int b) { // todo auto-generated method stub super.onlayout(changed, l, t, r, b); }
通过设置偏移量,调整我们的初始布局,使menu全部隐藏,右侧菜单显现
@override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { // todo auto-generated method stub super.onmeasure(widthmeasurespec, heightmeasurespec); }
设置子view的宽
* 因为horizontalscrollview自己控制move和down的事件
* 所以我们还要通过ontouchevent判断一下up.如果当前的x偏移量大于menu宽度的一半
* 隐藏menu,否则显示menu 显示的时候通过smoothscrollto(x, y)方法来实现动画的效果
下面是所有的自定义的horizontalscrollview
package com.example.myhorizontalscrollview; import android.annotation.suppresslint; import android.content.context; import android.text.getchars; import android.util.attributeset; import android.util.displaymetrics; import android.util.typedvalue; import android.view.motionevent; import android.view.viewgroup; import android.view.windowmanager; import android.widget.horizontalscrollview; import android.widget.linearlayout; public class myhorizontalscrollview extends horizontalscrollview { //滚动条中的水平先行布局 private linearlayout mwrpper; //水平线性布局的左侧菜单menu private viewgroup mmenu; //水平先行布局的右侧线性布局 private viewgroup mcontent; //屏幕的宽 private int mscreenwidth; //menu的宽离屏幕右侧的距离 private int mmenurightpadding=50; //menu的宽度 private int mmenuwidth; private boolean once; /** * 未使用自定义属性时调用 * */ public myhorizontalscrollview(context context, attributeset attrs) { super(context, attrs); /* * 获取屏幕的宽度 * 通过context拿到windowmanager,在通过windowmanager拿到metrics,用displaymetrics接收 * */ windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); displaymetrics outmetrics = new displaymetrics(); wm.getdefaultdisplay().getmetrics(outmetrics); mscreenwidth=outmetrics.widthpixels; //把dp转换成px mmenurightpadding=(int) typedvalue.applydimension(typedvalue.complex_unit_dip, 50, context.getresources().getdisplaymetrics()); } /* * 设置子view的宽和高 * */ @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { // todo auto-generated method stub if(!once){ mwrpper=(linearlayout) getchildat(0); mmenu=(viewgroup) mwrpper.getchildat(0); mcontent=(viewgroup) mwrpper.getchildat(1); //menu的宽度等于屏幕的宽度减去menu离屏幕右侧的边距 mmenuwidth=mmenu.getlayoutparams().width=mscreenwidth-mmenurightpadding; //右边的先行布局的宽度直接等于屏幕的宽度 mcontent.getlayoutparams().width=mscreenwidth; once=true; } super.onmeasure(widthmeasurespec, heightmeasurespec); } /* * 通过设置偏移量将menu隐藏 * */ @override protected void onlayout(boolean changed, int l, int t, int r, int b) { // todo auto-generated method stub super.onlayout(changed, l, t, r, b); /* * 通过scrollto(x,y)方法设置屏幕的偏移量,x为正 * 内容向左移动 * */ if(changed){ this.scrollto(mmenuwidth, 0); } } /* * 因为horizontalscrollview自己控制move和down的事件 * 所以我们还要判断一下up.如果当前的x偏移量大于menu宽度的一半 * 隐藏menu,否则显示menu * */ @override public boolean ontouchevent(motionevent ev) { // todo auto-generated method stub 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加载布局就可以
package com.example.slipping; import com.example.helloworld.r; import android.os.bundle; import android.app.activity; import android.view.menu; public class mainactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!