前两天学习了hyman老师讲的Android侧滑菜单的实现,经过自己的整理分享出来给大家学习一下
现在很多APP都有菜单侧滑的功能,本篇文章主要讲解使用自定义的HorizontalScrollView控件实现简单的菜单侧滑功能
用户可以左右滑动或者点击上方的菜单切换按钮,切换菜单
不多说先上两张效果图,图中内容正文页面只是QQ聊天界面的一张静态图片
接下来,让我们看下具体代码的实现,代码中有注释
1. left_menu.xml布局文件,用来显示图二中的菜单界面
注意:所有xml中的image图片信息没有提供,所以drawable图片资源需要自己另外,只有加上图片资源项目才能正常运行
<?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="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/img_frame_background" android:layout_marginLeft="50dp" android:layout_marginTop="80dp" android:orientation="vertical" > <RelativeLayout android:layout_width="wrap_content" 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="wrap_content" 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="wrap_content" 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="wrap_content" 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="wrap_content" 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>
2.activity_main.xml,主页面,里面包含了自定义控件HorizontalScrollView,这个对应到下面的SlidingMenu.java类
注意HorizontalScrollView里最多只能包含一个布局,本案例使用的是LinearLayout
<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.wujiandong.slidingmenu.view.SlidingMenu android:id="@+id/menu" 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="wrap_content" android:layout_height="match_parent" android:background="@drawable/qq" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text = "切换菜单" android:onClick="toggleMenu" /> </LinearLayout> </LinearLayout> </com.wujiandong.slidingmenu.view.SlidingMenu> </RelativeLayout>
3. 编写SlidingMenu.java类,这就是自定义的HorizontalScrollView控件
package com.wujiandong.slidingmenu.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.WindowManager; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; public class SlidingMenu extends HorizontalScrollView{ private LinearLayout wrapper; private ViewGroup menu; private ViewGroup content; //屏幕的宽度 private int screenWidth; //菜单view的宽度 private int muneWidth; //内容view的宽度 private int contentWidth; //菜单向右边拉出来时,离右边屏幕的距离,初始化为80dp private int muneRightPadding = 80; //判断onMeasure方法是不是第一次调用,我们只要求调用一次 private boolean flag; //判断菜单是否是打开状态 private boolean isOpen; //未使用自定义属性时,调用 public SlidingMenu(Context context, AttributeSet attrs) { super(context, attrs); //获得屏幕的宽度 WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics displayMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(displayMetrics); screenWidth = displayMetrics.widthPixels; //将dip转化为px muneRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, context.getResources().getDisplayMetrics()); } /* * 设置子view的宽和高 * 设置自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(!flag){ //获得HorizontalScrollView控件中对应的子view,参考activity_main.xml wrapper = (LinearLayout)getChildAt(0); menu = (ViewGroup)wrapper.getChildAt(0); content = (ViewGroup)wrapper.getChildAt(1); muneWidth= menu.getLayoutParams().width = screenWidth - muneRightPadding; contentWidth = content.getLayoutParams().width = screenWidth; //自己的宽度wrapperWidth,由于是一个LinearLayout,里面包含menu和content,子view的宽和高确定了,自己的宽和高就确定了,所以不设置了 flag = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /* * 我们布局文件中是menu显示,content隐藏的 * 所以在这里通过设置偏移量,将menu隐藏,content显示 */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); //防止多次调用,我们只有在布局改变时才调用这个方法 if(changed){ //向左边滑动menu的宽度,就是隐藏了menu this.scrollTo(muneWidth, 0); } } /* * 判断手指滑动的结果 */ @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_UP: //menu菜单隐藏在屏幕左边的宽度 int scrollX = getScrollX(); if(scrollX >= muneWidth/2){ //渐滑的效果,菜单隐藏,隐藏在屏幕左边的宽度为muneWidth this.smoothScrollTo(muneWidth, 0); isOpen = false; }else{ //菜单完全显示,隐藏在左边屏幕的宽度为0 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(muneWidth, 0); isOpen = false; } //点击按钮,切换菜单 public void toggle(){ if(isOpen){ closeMenu(); } else { openMenu(); } } }
4. MainActivity.java,程序的执行入口
package com.wujiandong.slidingmenu; import com.wujiandong.slidingmenu.R; import com.wujiandong.slidingmenu.view.SlidingMenu; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.view.Window; public class MainActivity extends Activity { private SlidingMenu lefMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); lefMenu = (SlidingMenu)findViewById(R.id.menu); } //布局文件中定义了点击事件,可以直接调用 public void toggleMenu(View view){ lefMenu.toggle(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
好了,代码已经展示完毕,大家按照流程来,就能实现绚丽的侧滑功能了
如果大家有不懂的地方或者有错误的地方,欢迎发表评论提出,谢谢观看,下次我们在分享~~
原文:http://www.cnblogs.com/wujiandong/p/5017831.html