Android側滑菜單代碼實現


前兩天學習了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;
    }

}


好了,代碼已經展示完畢,大家按照流程來,就能實現絢麗的側滑功能了

如果大家有不懂的地方或者有錯誤的地方,歡迎發表評論提出,謝謝觀看,下次我們在分享~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM