實現自定義側滑菜單效果

看了郭大神的 

Android滑動菜單特效實現,仿人人客戶端側滑效果,史上最簡單的側滑實現博文後,對實現側滑菜單有了基本的實現思路,然後通過自己的思路整理一遍


實現思路:

一個activity內並排顯示兩個佈局,在左邊的佈局爲菜單佈局,在右邊的佈局爲內容佈局;在初始化界面的時候,將菜單佈局完全隱藏,把內容佈局顯示在可視視圖中;在用戶滑動的過程中通過水平滑動的距離,動態修改菜單和內容的佈局(這裏通過修改左邊距的值實現)實現側滑效果。

MainActivity中代碼實現

package com.example.qdq.renrenslidemenudemo;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
    private int screenWidth;//屏幕寬度
    private LinearLayout menu_layout;
    private LinearLayout content_layout;
    private LinearLayout.LayoutParams menu_params;
    private LinearLayout.LayoutParams content_params;
    private int downX;//手指按下屏幕的x座標
    private int moveX;//手指在屏幕上移動的x座標
    private int upX;//手指離開屏幕時的x座標
    private int menuLastMarginX;//手指停止滑動時菜單的左邊距
    private int contentLastMarginX;//手指停止滑動時內容的左邊距

    private int minContentWidth=200;//內容的最小寬度
    private static int SPEED=200;//滑動速度
    private VelocityTracker tracker;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        menu_layout= (LinearLayout) findViewById(R.id.menu_layout);
        content_layout= (LinearLayout) findViewById(R.id.content_layout);
        initValues();
    }
    /**
     * 初始化一些關鍵性數據。包括獲取屏幕的寬度,給content佈局重新設置寬度,給menu佈局重新設置寬度和偏移距離等。
     */
    private void initValues() {
        //獲取屏幕寬度
        WindowManager windowManager= (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        screenWidth=windowManager.getDefaultDisplay().getWidth();
        //獲取佈局參數
        menu_params= (LinearLayout.LayoutParams) menu_layout.getLayoutParams();
        content_params= (LinearLayout.LayoutParams) content_layout.getLayoutParams();
        //將菜單佈局移除屏幕(左移),將內容佈局顯示在屏幕上(左移)
        requestLayout(-screenWidth,-screenWidth);
        //記錄最後一次的leftMargin屬性值
        menuLastMarginX=menu_params.leftMargin;
        contentLastMarginX=content_params.leftMargin;

        content_layout.setOnTouchListener(this);
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        createVelocityTracker(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX= (int) event.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                moveX= (int) event.getRawX();
                updateUI(moveX-downX);
                break;
            case MotionEvent.ACTION_UP:
                upX= (int) event.getRawX();
                //首先判斷滑動速度
                if(getScrollVelocity()>SPEED){
                    if(upX-downX>0){//向右;這裏可以使用動畫實現滑動效果
                        requestLayout(-minContentWidth,-minContentWidth);
                    }else if(upX-downX<0){//向左;<span style="font-family: Arial, Helvetica, sans-serif;">這裏可以使用動畫實現滑動效果</span>
                        requestLayout(-screenWidth,-screenWidth);
                    }
                }
                recycleVelocity();
                //記錄最後一次的leftMargin屬性值
                menuLastMarginX=menu_params.leftMargin;
                contentLastMarginX=content_params.leftMargin;
                break;
        }
        return true;
    }
    /**
     * (一)當手指左滑並且content寬度大於設定的最小寬度時;
     * (二)當向右滑並且content寬度小於屏幕寬度時
     * 以上兩種情況下需要更新界面佈局
     */
    private void updateUI(int distance){
        //獲取當前內容顯示寬度
        int contentWidth=Math.abs(content_params.leftMargin);
        //判斷是否符合條件
        if(contentWidth>minContentWidth&&distance>0||distance<0&&contentWidth<screenWidth){
            requestLayout(distance+menuLastMarginX,distance+contentLastMarginX);
        }
    }
    /**
     * 重新請求佈局
     * @param menuPadLeft 菜單左邊距
     * @param contentPadLeft 內容左邊距
     */
    private void requestLayout(int menuPadLeft,int contentPadLeft){
        //設置菜單佈局
        menu_params.leftMargin=menuPadLeft;
        menu_layout.setLayoutParams(menu_params);
        //設置內容佈局
        content_params.leftMargin=contentPadLeft;
        content_layout.setLayoutParams(content_params);
    }
    /**
     * 創建VelocityTracker對象,並將觸摸content界面的滑動事件加入到VelocityTracker當中。
     * @param motionEvent
     */
    private void createVelocityTracker(MotionEvent motionEvent){
        if(tracker==null){
            tracker=VelocityTracker.obtain();
        }
        tracker.addMovement(motionEvent);
    }
    /**
     * 獲取1s內移動的像素值
     * @return 速度
     */
    private int getScrollVelocity(){
        tracker.computeCurrentVelocity(1000);
        int speed= (int) tracker.getXVelocity();
        return Math.abs(speed);
    }
    /**
     * 回收資源
     */
    private void recycleVelocity(){
        if(tracker!=null){
            tracker.recycle();
            tracker=null;
        }
    }
}
activity_main.xml中代碼

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal"
    tools:context="com.example.qdq.renrenslidemenudemo.MainActivity">
    <LinearLayout
        android:id="@+id/menu_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#550000">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textColor="#ffffff"
            android:text="菜單界面"/>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/content_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#005500">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textColor="#ffffff"
            android:text="內容界面"/>
    </LinearLayout>
</LinearLayout>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章