Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 開發第三彈:自定義左右菜單(滑動動畫+蒙版效果)

Android 開發第三彈:自定義左右菜單(滑動動畫+蒙版效果)

編輯:關於Android編程

下面的截圖……哎,因為1080P在Windows 10上雖然適配了,但大部分軟件並沒有跟上,比如某個錄制GIF的軟件,所以這裡有一定的偏移導致畫面不完整,但效果大概就是這麼一個效果了。

這裡寫圖片描述

MainUI.java

首先需要這麼一個類,在這裡一些UI的滑動呀之類的都會定義。首先吧,定義好這些變量,當然了,實際開發過程中肯定需要哪一個就添加上哪一個的。

    private Context context;  // 上下文
    private FrameLayout leftMenu;    // 左邊部分
    private FrameLayout middleMenu;  // 中間部分
    private FrameLayout rightMenu;   // 右邊部分
    private FrameLayout middleMask;  // 蒙版效果
    private Scroller mScroller;    // 滑動動畫
    public static final int ID = 0;    // ID
    public static final int LEFT_ID = ID+0xaabbcc;
    public static final int MIDDLE_ID = ID+0xaaccbb;
    public static final int RIGHT_ID = ID+0xccbbaa;

構造函數也是不能少的。

    public MainUI(Context context) {
        super(context);
        initView(context);
    }

    public MainUI(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

initView就是用來初始化視圖的,相應的功能我都寫在注釋上了,就不多廢話了。

    // 初始化視圖
    private void initView(Context context){
        this.context=context;
        mScroller = new Scroller(context,new DecelerateInterpolator());
        leftMenu=new FrameLayout(context);
        middleMenu = new FrameLayout(context);
        rightMenu = new FrameLayout(context);
        middleMask = new FrameLayout(context);
        leftMenu.setBackgroundColor(Color.RED);  // 設置背景顏色
        middleMenu.setBackgroundColor(Color.GREEN);
        rightMenu.setBackgroundColor(Color.RED);
        middleMask.setBackgroundColor(0x88000000);
        leftMenu.setId(LEFT_ID);
        middleMenu.setId(MIDDLE_ID);
        rightMenu.setId(RIGHT_ID);
        addView(leftMenu);   // 添加至View
        addView(middleMenu);
        addView(rightMenu);
        addView(middleMask);
        middleMask.setAlpha(0);  // 設置middleMask的透明度
    }

然後就是它們的一些布局呀,balabala……

    @Override
    protected void onMeasure(int widthMeasureSepc, int heightMeasureSpec){
        super.onMeasure(widthMeasureSepc, heightMeasureSpec);
        middleMenu.measure(widthMeasureSepc, heightMeasureSpec);
        middleMask.measure(widthMeasureSepc,heightMeasureSpec);
        int realWidth = MeasureSpec.getSize(widthMeasureSepc);  // 獲取實際(屏幕)寬度
        int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
                (int)(realWidth*0.7f), MeasureSpec.EXACTLY);  // 左右側的寬度為中間寬度的0.7
        leftMenu.measure(tempWidthMeasure, heightMeasureSpec);  // 左右側的高度和中間的一樣
        rightMenu.measure(tempWidthMeasure, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r,int b){  // l,t,r,b分別為中間部分的左、上、右、下邊界
        super.onLayout(changed, l, t, r, b);  // 設置布局
        middleMenu.layout(l, t, r, b);   // 中間部分的四個邊界不變
        middleMask.layout(l, t, r, b);  // 蒙版的四個邊界和中間部分一樣
        leftMenu.layout(l - leftMenu.getMeasuredWidth(), t, r, b); // 左側部分的左邊邊界等於中間部分的左邊邊界減去左側部分的寬度
        rightMenu.layout(l + middleMenu.getMeasuredWidth(), t,  // 右側部分的左邊邊界則等於中間部分的左邊邊界加上中間部分的寬度
                l + middleMenu.getMeasuredWidth() +   // 右側部分的右邊邊界等於中間部分的左邊邊界加上中間部分的寬度加上右側部分的寬度
                        rightMenu.getMeasuredWidth(), b);
    }
    public float onMiddleMask(){
        System.out.println(透明度+middleMask.getAlpha());
        return middleMask.getAlpha();
    }

    @Override
    public void scrollTo(int x, int y){
        super.scrollTo(x,y);
        onMiddleMask();  // 輸出透明度
        int curX = Math.abs(getScrollX());
        float scale = curX/(float)leftMenu.getMeasuredWidth();  // 設置透明度的漸變
        middleMask.setAlpha(scale);
    }

再用兩個布爾值來確定是否在左右滑動等。

    private boolean isTestComete;  // 測試是否完成
    private boolean isleftrightevent;  // 判斷是否是左右滑動
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev){
        if(!isTestComete){  // 沒有完成滑動動作
            getEventType(ev);   // 繼續調用事件進行判斷
            return true;
        }
        if(isleftrightevent){   // 左右滑動
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_MOVE:
                    int curScrollX = getScrollX();
                    int dis_x = (int) (ev.getX() - point.x);
                    int expectX = -dis_x + curScrollX;
                    int finalX = 0;
                    if (expectX < 0) {
                        finalX = Math.max(expectX, -leftMenu.getMeasuredWidth());
                    } else {
                        finalX = Math.min(expectX, rightMenu.getMeasuredWidth());
                    }
                    scrollTo(finalX, 0);
                    point.x = (int) ev.getX();
                    break;

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    curScrollX = getScrollX();
                    if (Math.abs(curScrollX) > leftMenu.getMeasuredWidth() >> 1) {
                        if (curScrollX < 0) {
                            mScroller.startScroll(curScrollX, 0, -leftMenu.getMeasuredWidth() - curScrollX, 0, 200);
                        } else {
                            mScroller.startScroll(curScrollX, 0, leftMenu.getMeasuredWidth() - curScrollX, 0, 200);
                        }
                    } else {
                        mScroller.startScroll(curScrollX, 0, -curScrollX, 0, 200);
                    }
                    invalidate();
                    isleftrightevent = false;
                    isTestComete = false;
                    break;
            }
        }else{
            switch (ev.getActionMasked()){
                case MotionEvent.ACTION_UP:
                    isleftrightevent = false;
                    isTestComete = false;
                    break;
                default:
                    break;
            }
        }
        return super.dispatchTouchEvent(ev);
    }
@Override
    public void computeScroll(){
        super.computeScroll();
        if(!mScroller.computeScrollOffset()){
            return;
        }
        int tempX = mScroller.getCurrX();
        scrollTo(tempX, 0);
    }

    private Point point = new Point();
    private static final int TEST_DIS = 20;
    private void getEventType(MotionEvent ev){
        switch (ev.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
                point.x = (int)ev.getX();
                point.y = (int) ev.getY();
                super.dispatchTouchEvent(ev);
                break;
            case MotionEvent.ACTION_MOVE:
                int dX = Math.abs((int)ev.getX() - point.x);
                int dY = Math.abs((int)ev.getY() - point.y);
                if(dX >= TEST_DIS && dX>dY ){ // 左右滑動
                    isleftrightevent = true;
                    isTestComete = true;
                    point.x = (int)ev.getX();
                    point.y = (int)ev.getY();
                }else if(dY>=TEST_DIS && dY>dX ){   // 上下滑動
                    isleftrightevent = false;
                    isTestComete = true;
                    point.x = (int)ev.getX();
                    point.y = (int)ev.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                super.dispatchTouchEvent(ev);
                isleftrightevent = false;
                isTestComete = false;
                break;
        }
    }

LeftMenu.java

下面繼續看看如何在左側的目錄中添加一個Button。

你需要創建一個LeftMenu類,並擴展Fragment,因此你需要

import android.support.v4.app.Fragment;

如果你不知道如何添加,請看這裡:

在下面這段代碼之前你需要再新建一個left.xml布局文件,其中添加一個Button1。

    @Override
      public View onCreateView(LayoutInflater inflater,
                               @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.left, container,false);
        v.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                System.out.println(Hello nomasp);
            }
        });
        return v;
    }

MainActivity.java

現在你就需要來create它們了。

    private MainUI mainUI;
    private LeftMenu leftMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainUI = new MainUI(this);
        setContentView(mainUI);
        leftMenu = new LeftMenu();
        getSupportFragmentManager().beginTransaction()
                .add(MainUI.LEFT_ID, leftMenu).commit();
    }

當然了,這裡的MainActivity也需要擴展FragmentActivity,也就是要導入android−support−v4.jar,至於如何導入請看前文的導航鏈接。

當然了,完整的代碼你可以從這裡Fork:GitHub

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved