极客学院Android12案例---案例4--自定义左右菜单

该案例主要是算法,学习意义不大

1.创建基本视图
package com.fengray.ex041;

import android.content.Context;
import android.graphics.Color;
import android.icu.util.Measure;
import android.util.AttributeSet;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

public class MainUI extends RelativeLayout {
    private Context context;
    private FrameLayout leftMenu;
    private FrameLayout middleMenu;
    private FrameLayout rightMenu;

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

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



    private void initView(Context context) {
        this.context = context;
        leftMenu = new FrameLayout(context);
        middleMenu = new FrameLayout(context);
        rightMenu = new FrameLayout(context);

        leftMenu.setBackgroundColor(Color.RED);
        middleMenu.setBackgroundColor(Color.GREEN);
        rightMenu.setBackgroundColor(Color.RED);

        addView(leftMenu);
        addView(middleMenu);
        addView(rightMenu);
    }




    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        middleMenu.measure(widthMeasureSpec, heightMeasureSpec);
        int realWidth = MeasureSpec.getSize(widthMeasureSpec);
        int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
                (int) (realWidth * 0.8f), MeasureSpec.EXACTLY);
        leftMenu.measure(tempWidthMeasure, heightMeasureSpec);
        rightMenu.measure(tempWidthMeasure, heightMeasureSpec);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        middleMenu.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);
    }


}
2.完成左右滑动
package com.fengray.ex041;

import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.icu.util.Measure;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

public class MainUI extends RelativeLayout {
    private Context context;
    private FrameLayout leftMenu;
    private FrameLayout middleMenu;
    private FrameLayout rightMenu;

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

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



    private void initView(Context context) {
        this.context = context;
        leftMenu = new FrameLayout(context);
        middleMenu = new FrameLayout(context);
        rightMenu = new FrameLayout(context);

        leftMenu.setBackgroundColor(Color.RED);
        middleMenu.setBackgroundColor(Color.GREEN);
        rightMenu.setBackgroundColor(Color.RED);

        addView(leftMenu);
        addView(middleMenu);
        addView(rightMenu);
    }




    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        middleMenu.measure(widthMeasureSpec, heightMeasureSpec);
        int realWidth = MeasureSpec.getSize(widthMeasureSpec);
        int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
                (int) (realWidth * 0.8f), MeasureSpec.EXACTLY);
        leftMenu.measure(tempWidthMeasure, heightMeasureSpec);
        rightMenu.measure(tempWidthMeasure, heightMeasureSpec);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        middleMenu.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);
    }

    private boolean isTestCompete;//上下还是左右滑动
    private boolean isleftRightEvent;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!isTestCompete){
            getEventType(ev);
            return  true;
        }
        if (isleftRightEvent){
            switch (ev.getActionMasked()){
                case MotionEvent.ACTION_MOVE:
                    int curScrollX=getScrollX();
                    int distance_x=(int)(ev.getX()-point.x);
                    int expectX=-distance_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:
                    isleftRightEvent=false;
                    isTestCompete=false;
                    break;
                default:
                    break;
            }
        }else{
            switch (ev.getActionMasked()){
                case MotionEvent.ACTION_UP:
                    isleftRightEvent=false;
                    isTestCompete=false;
                    break;
                default:
                    break;
            }
        }

        return super.dispatchTouchEvent(ev);
    }

    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();
                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;
                    isTestCompete=true;

                    point.x=(int)ev.getX();
                }else if(dY>=TEST_DIS && dY>dX){//上下滑动
                    isleftRightEvent=false;
                    isTestCompete=true;
                    point.x=(int)ev.getX();
                    point.y=(int)ev.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
    }
}
3.完成左右滑动

MainUI类

package com.fengray.ex041;

import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.icu.util.Measure;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

public class MainUI extends RelativeLayout {
    private Context context;
    private FrameLayout leftMenu;
    private FrameLayout middleMenu;
    private FrameLayout rightMenu;
    private FrameLayout middleMask;
    private Scroller mScroller;
    public static  final  int LEFT_ID=0xaabbcc;
    public static final  int MIDEELE_ID=0xaaccbb;
    public static final  int RIGHT_ID=0xccbbaa;

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

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



    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(Color.GRAY);//灰色

        leftMenu.setId(LEFT_ID);
        middleMenu.setId(MIDEELE_ID);
        rightMenu.setId(RIGHT_ID);

        addView(middleMask);
        addView(leftMenu);
        addView(middleMenu);
        addView(rightMenu);
        middleMask.setAlpha(0);
    }
    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);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        middleMenu.measure(widthMeasureSpec, heightMeasureSpec);

        middleMask.measure(widthMeasureSpec, heightMeasureSpec);
        int realWidth = MeasureSpec.getSize(widthMeasureSpec);
        int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
                (int) (realWidth * 0.8f), MeasureSpec.EXACTLY);
        leftMenu.measure(tempWidthMeasure, heightMeasureSpec);
        rightMenu.measure(tempWidthMeasure, heightMeasureSpec);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        middleMenu.layout(l, t, r, b);
        middleMenu.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);
    }

    private boolean isTestCompete;//上下还是左右滑动
    private boolean isleftRightEvent;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!isTestCompete){
            getEventType(ev);
            return  true;
        }
        if (isleftRightEvent){
            switch (ev.getActionMasked()){
                case MotionEvent.ACTION_MOVE:
                    int curScrollX=getScrollX();
                    int distance_x=(int)(ev.getX()-point.x);
                    int expectX=-distance_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:
                    isleftRightEvent=false;
                    isTestCompete=false;
                    break;
                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;
                    isTestCompete=false;
                    break;
                default:
                    break;
            }
        }else{
            switch (ev.getActionMasked()){
                case MotionEvent.ACTION_UP://手指抬起时
                    isleftRightEvent=false;
                    isTestCompete=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;
                    isTestCompete=true;

                    point.x=(int)ev.getX();
                }else if(dY>=TEST_DIS && dY>dX){//上下滑动
                    isleftRightEvent=false;
                    isTestCompete=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;
                isTestCompete=false;
                break;
        }
    }
}

leftMenu类

package com.fengray.ex041;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class LeftMenu extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.left,container,false);
        view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("hello world!");
            }
        });
        return view;
    }


}

MainActivity类

package com.fengray.ex041;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentActivity;

import android.os.Bundle;

public class MainActivity extends FragmentActivity {
    private  MainUI mainUI;
    private LeftMenu leftMenu;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        mainUI=new MainUI(this);
        setContentView(mainUI);

        leftMenu=new LeftMenu();
        getSupportFragmentManager().beginTransaction().add(MainUI.LEFT_ID,leftMenu).commit();

    }
}

效果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值