中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

自定義Android側滑菜單控件

發布時間:2020-07-03 21:16:18 來源:網絡 閱讀:837 作者:2273167391 欄目:移動開發

package com.tenghu.sideslipmenu.view;


import android.content.Context;

import android.os.AsyncTask;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.WindowManager;

import android.widget.LinearLayout;


/**

 * Created by Arvin_Li on 2014/11/18.

 */

public class SideslipMenuView extends LinearLayout {

    //滾動顯示和隱藏menu時,手指滑動需要達到的速度

    private static final int SNAP_VELOCITY = 200;

    private View mMenu;//菜單布局

    private View mContent;//主內容布局

    private int mScreenWidth;//屏幕寬度

    private int mMenuWidth;//菜單寬度

    //menu最多可以滑動到的左邊緣,值由menu布局的寬度來定

    private int leftEdge;

    //menu最多可以滑到的有邊緣,值恒為0

    private int rightEdge = 0;

    //menu完全顯示時,留給content的寬度值

    private int toRightPaddingWidth = 50;

    //menu布局的參數,通過此參數來更改leftMargin的值

    private LinearLayout.LayoutParams menuParams;

    //記錄手指按下的橫坐標

    private float xDown;

    //記錄手指抬起的橫坐標

    private float xUp;

    //記錄手指移動的橫坐標

    private float xMove;

    //當前menu是顯示還是隱藏,只有menu完全顯示和隱藏才會改變該值,滑動時不會改變

    private boolean isMenuVisible;

    //用于計算手指滑動的速度

    private VelocityTracker mVelocityTracker;

    private boolean once;


    public SideslipMenuView(Context context) {

        super(context);

        init(context);

    }


    public SideslipMenuView(Context context, AttributeSet attrs) {

        super(context, attrs);

        init(context);

    }


    /**

     * 初始化

     */

    private void init(Context context) {

        //獲取WindowManager對象

        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        DisplayMetrics displayMetrics = new DisplayMetrics();

        windowManager.getDefaultDisplay().getMetrics(displayMetrics);

        mScreenWidth = displayMetrics.widthPixels;//獲取屏幕寬度

    }


    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (!once) {

            mMenu = getChildAt(0);//獲取菜單布局

            mContent = getChildAt(1);//獲取內容布局

            menuParams = (LayoutParams) mMenu.getLayoutParams();//獲取菜單參數

            mMenuWidth = menuParams.width = mScreenWidth - toRightPaddingWidth;//設置菜單寬度

            //左邊緣的值賦值為menu寬度的負數

            leftEdge = -menuParams.width;

            //menu的leftMargin設置為左邊緣的值,默認菜單不可見

            menuParams.leftMargin = leftEdge;

            mContent.getLayoutParams().width = mScreenWidth;//設置內容寬度

            once = true;

        }

    }


    @Override

    public boolean onTouchEvent(MotionEvent event) {

        createVelocityTracker(event);//創建VelocityTracker對象

        switch (event.getAction()) {

            //手指按下

            case MotionEvent.ACTION_DOWN:

                xDown = event.getRawX();//記錄橫坐標

                break;

            //手指移動

            case MotionEvent.ACTION_MOVE:

                //手指移動時,對比按下的橫坐標,計算出移動的距離來調整menu的leftMargin值,從而顯示和隱藏menu

                xMove = event.getRawX();

                //計算獲取到距離

                int distanceX = (int) (xMove - xDown);

                if (isMenuVisible) {

                    menuParams.leftMargin = distanceX;

                } else {

                    menuParams.leftMargin = leftEdge + distanceX;

                }


                //如果菜單的左邊界小于了可以滑動的左邊界

                if (menuParams.leftMargin <= leftEdge) {

                    //將可以滑動的左邊界賦值給菜單左邊界

                    menuParams.leftMargin = leftEdge;

                } else if (menuParams.leftMargin >= rightEdge) {

                    menuParams.leftMargin = rightEdge;

                }

                mMenu.setLayoutParams(menuParams);//設置菜單參數

                break;

            //手指抬起

            case MotionEvent.ACTION_UP:

                //手指抬起時,進行判斷當前手勢的意圖,從而決定是滾動到menu界面,還是滾動到content界面

                xUp = event.getRawX();

                if (wantToShowMenu()) {

                    if (shouldScrollToMenu()) {

                        scrollToMenu();

                    } else {

                        scrollToContent();

                    }

                } else if (wantToShowContent()) {

                    if (shouldScrollToContent()) {

                        scrollToContent();

                    } else {

                        scrollToMenu();

                    }

                }

                //手指抬起是回收VelocityTracker對象

                recycleVelocityTracker();

                break;

        }

        return true;

    }


    /**

     * 創建VelocityTracker對象,并將觸摸content界面的滑動時間加入到VelocityTracker中

     *

     * @param event

     */

    private void createVelocityTracker(MotionEvent event) {

        if (null == mVelocityTracker) {

            mVelocityTracker = VelocityTracker.obtain();//初始化VelocityTracker

        }

        mVelocityTracker.addMovement(event);//添加界面滑動事件

    }


    /**

     * 判斷當前手勢的意圖是不是想顯示content,如果手指移動的距離是負數,且當前menu是可見的,則認為當前手勢是想要顯示content。

     *

     * @return

     */

    private boolean wantToShowContent() {

        return xUp - xDown < 0 && isMenuVisible;

    }


    /**

     * 判斷當前手勢的意圖是不是想顯示menu,如果手指移動的距離是正數,且當前menu是不可見,則認為當前手勢是顯示menu

     *

     * @return

     */

    private boolean wantToShowMenu() {

        return xUp - xDown > 0 && !isMenuVisible;

    }


    /**

     * 判斷是否應該滾動將menu展示出來,如果手指移動距離大于屏幕的1/2,或者手指移動速度大于SNAP_VELOCITY,就認為應該滾動將menu展示出來。

     *

     * @return 如果應該滾動將menu展示出來返回true,否則返回false。

     */

    private boolean shouldScrollToMenu() {

        return xUp - xDown > mMenuWidth / 2 || getScrollVelocity() > SNAP_VELOCITY;

    }


    /**

     * 判斷是否應該滾動將content展示出來,如果手指移動距離加上menuPadding大于屏幕的1/2,或者手指移動速度大于SNAP_VELOCITY, 就認為應該滾動將content展示出來。

     *

     * @return 如果應該滾動將content展示出來返回true,否則返回false。

     */

    private boolean shouldScrollToContent() {

        //這里菜單狀態為顯示,如果要菜單隱藏,那么手勢是從右到左滑動,這里手指按下的橫坐標就會比抬起時的橫坐標小

        return xDown - xUp + toRightPaddingWidth > mMenuWidth / 2 || getScrollVelocity() > SNAP_VELOCITY;

    }


    /**

     * 獲取手指在content上滑動的速度

     *

     * @return 滑動速度,以每秒鐘移動了多少像素為單位

     */

    private int getScrollVelocity() {

        mVelocityTracker.computeCurrentVelocity(1000);

        int velocity = (int) mVelocityTracker.getXVelocity();//獲取x方向的速度值

        return Math.abs(velocity);

    }


    /**

     * 回收VelocityTracker對象

     */

    private void recycleVelocityTracker() {

        if (null != mVelocityTracker) {

            mVelocityTracker.recycle();

            mVelocityTracker = null;

        }

    }


    /**

     * 將屏幕滾動到menu界面,設置滾動速度為30

     */

    private void scrollToMenu() {

        isMenuVisible = true;

        new ScrollTask().execute(30);

    }


    /**

     * 將屏幕滾動到content界面,設置滾動速度為-30

     */

    private void scrollToContent() {

        isMenuVisible = false;

        new ScrollTask().execute(-30);

    }


    /**

     * 創建滾動任務類

     */

    class ScrollTask extends AsyncTask<Integer, Integer, Integer> {

        @Override

        protected Integer doInBackground(Integer... speed) {

            int leftMargin = menuParams.leftMargin;

            //根據傳入的速度來滾動界面,當滾動到達左邊界或右邊界時跳出循環

            while (true) {

                leftMargin = leftMargin + speed[0];

                if (leftMargin > rightEdge) {

                    leftMargin = rightEdge;

                    break;

                }

                if (leftMargin < leftEdge) {

                    leftMargin = leftEdge;

                    break;

                }

                //更新任務進度,會把值傳入到onProgressUpdate()方法中進行UI的更新

                publishProgress(leftMargin);

                //為了要有滾動效果產生,每次循環使線程睡眠20毫秒

                sleep(20);

            }

            return leftMargin;

        }


        /**

         * 這里的Intege參數對應AsyncTask中的第二個參數

         * 在doInBackground方法當中,,每次調用publishProgress方法都會觸發onProgressUpdate執行

         * onProgressUpdate是在UI線程中執行,所有可以對UI空間進行操作

         *

         * @param leftMargin

         */

        @Override

        protected void onProgressUpdate(Integer... leftMargin) {

            menuParams.leftMargin = leftMargin[0];

            mMenu.setLayoutParams(menuParams);

        }


        /**

         * 執行異步結束,接收doInBackground()方法的返回值,接收到的返回值對應AsyncTask<Integer, Integer, Integer> 第3個參數

         *

         * @param leftMargin

         */

        @Override

        protected void onPostExecute(Integer leftMargin) {

            menuParams.leftMargin = leftMargin;

            mMenu.setLayoutParams(menuParams);

        }

    }


    /**

     * 是當前線程睡眠指定的毫秒數

     *

     * @param millis

     */

    private void sleep(long millis) {

        try {

            Thread.sleep(millis);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

以上就是整個自定義側滑菜單控件的代碼,在布局文件直接使用即可如下:

<?xml version="1.0" encoding="utf-8"?>

<com.tenghu.sideslipmenu.view.SideslipMenuView xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="@drawable/bg_01">


    <include layout="@layout/left_menu" />


    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:background="@drawable/bg_02"

        android:orientation="vertical">

       

    </LinearLayout>

</com.tenghu.sideslipmenu.view.SideslipMenuView>

其中include引用的就是一個菜單布局文件,如下:

<?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"

    android:gravity="center_vertical">


    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_marginLeft="30dp"

        android:orientation="vertical">


        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="50dp"

            android:layout_marginBottom="10dp">


            <ImageView

                android:id="@+id/iv_img_01"

                android:layout_width="50dp"

                android:layout_height="match_parent"

                android:src="@drawable/app_01" />


            <TextView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_marginLeft="10dp"

                android:layout_toRightOf="@id/iv_img_01"

                android:gravity="center_vertical"

                android:text="第一個Item" />

        </RelativeLayout>


        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="50dp"

            android:layout_marginBottom="10dp">


            <ImageView

                android:id="@+id/iv_img_02"

                android:layout_width="50dp"

                android:layout_height="match_parent"

                android:src="@drawable/app_02" />


            <TextView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_marginLeft="10dp"

                android:layout_toRightOf="@id/iv_img_02"

                android:gravity="center_vertical"

                android:text="第二個Item" />

        </RelativeLayout>


        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="50dp"

            android:layout_marginBottom="10dp">


            <ImageView

                android:id="@+id/iv_img_03"

                android:layout_width="50dp"

                android:layout_height="match_parent"

                android:src="@drawable/app_03" />


            <TextView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_marginLeft="10dp"

                android:layout_toRightOf="@id/iv_img_03"

                android:gravity="center_vertical"

                android:text="第三個Item" />

        </RelativeLayout>


        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="50dp"

            android:layout_marginBottom="10dp">


            <ImageView

                android:id="@+id/iv_img_04"

                android:layout_width="50dp"

                android:layout_height="match_parent"

                android:src="@drawable/app_04" />


            <TextView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_marginLeft="10dp"

                android:layout_toRightOf="@id/iv_img_04"

                android:gravity="center_vertical"

                android:text="第四個Item" />

        </RelativeLayout>


        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="50dp"

            android:layout_marginBottom="10dp">


            <ImageView

                android:id="@+id/iv_img_05"

                android:layout_width="50dp"

                android:layout_height="match_parent"

                android:src="@drawable/app_05" />


            <TextView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_marginLeft="10dp"

                android:layout_toRightOf="@id/iv_img_05"

                android:gravity="center_vertical"

                android:text="第五個Item" />

        </RelativeLayout>


    </LinearLayout>

</RelativeLayout>

其中的菜單可以使用ListView去布局,這里做測試就沒有去使用了

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

山东省| 金华市| 柳江县| 黄石市| 农安县| 密云县| 突泉县| 奉新县| 乐至县| 楚雄市| 增城市| 萝北县| 育儿| 涪陵区| 潮安县| 双辽市| 阿克陶县| 蒙山县| 宁河县| 桃源县| 五家渠市| 周宁县| 新营市| 许昌市| 彭州市| 尚义县| 文成县| 延津县| 安岳县| 陇川县| 新乐市| 台湾省| 奎屯市| 突泉县| 东丽区| 湟中县| 达日县| 微山县| 梅河口市| 怀安县| 刚察县|