前兩天學習了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; } }
好了,代碼已經展示完畢,大家按照流程來,就能實現絢麗的側滑功能了
如果大家有不懂的地方或者有錯誤的地方,歡迎發表評論提出,謝謝觀看,下次我們在分享~~