App首页常见底部Path按钮(一分钟学会使用)

虽然说App底部Path按钮显示使用越来越少见,不过因为项目需要可以写写

1.布局中使用

<com.zlc.pathmenu.view.PathMenu
     android:id="@+id/id_path_menu"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_alignParentTop="true"
     android:layout_alignParentStart="true"/>

2.代码中使用

package com.zlc.pathmenu;

import android.os.Bundle;
import android.view.View;

import com.zlc.pathmenu.utils.LogUtil;
import com.zlc.pathmenu.view.PathMenu;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends BaseActivity implements PathMenu.PathListener{

    private PathMenu mPathMenu;
    private boolean isPathOpen;
    private final static int PATH_MENU_NUM = 3; //子按钮个数

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initListener();
    }

    private void initData() {
        setPathList();
    }

    private void initView() {
        mPathMenu = findView(R.id.id_path_menu);
    }

    private void initListener() {
        mPathMenu.setPathListener(this);
    }

    //Path按钮打开方法
    @Override
    public void onOpen() {
        LogUtil.e("PathMenu","onOpen");
        isPathOpen = true;
    }

    //Path按钮关闭方法
    @Override
    public void onClose() {
        LogUtil.e("PathMenu","onClose");
        isPathOpen = true;
    }

    //子按钮点击事件方法
    @Override
    public void menuClick(View view, int position) {
        LogUtil.e("menuClick",position+"");
        isPathOpen = false;
    }

    //给子按钮添加图标 弹出的按钮图标  PATH_MENU_NUM : 弹出数量
    public void setPathList(){
        if(isPathOpen) {
            mPathMenu.close();
        }
        List<Object> imageRes = new ArrayList<>();
        for (int i = 0; i < PATH_MENU_NUM ;i++){
            switch (i){
                case 0:
                    imageRes.add(new Integer(R.drawable.paizhoa));
                    break;
                case 1:
                    imageRes.add(new Integer(R.drawable.wenzi));
                    break;
                case 2:
                    imageRes.add(new Integer(R.drawable.daka));
                    break;
                case 3:
                    imageRes.add(new Integer(R.drawable.biaoq));
                    break;
                case 4:
                    imageRes.add(new Integer(R.drawable.scheme_card));
                    break;
            }
        }
        mPathMenu.setImages(imageRes);
    }

}

3.PathMenu的简单自定义

package com.zlc.pathmenu.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.nineoldandroids.view.ViewPropertyAnimator;
import com.zlc.pathmenu.R;
import com.zlc.pathmenu.utils.DensityUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zlc on 2017/10/14.
 */
public class PathMenu extends RelativeLayout implements View.OnClickListener{

    /**
     * 菜单展开时的扇面角度
     */
    private int sectorAngle = 120;

    private List<?>images;
    /**
     * 子菜单项的数量
     */
    private int menuItemCount  = 0;
    /**
     * 子菜单展开半径
     */
    private int radius = 180;
    private ArrayList<FrameLayout> containerViews = new ArrayList<>();
    private ArrayList<FrameLayout> imageViewContainers = new ArrayList<>();
    private ImageView centerButton;
    private boolean isOpen = false;
    private List<ViewPropertyAnimator> containerAnimators = new ArrayList<>();
    private List<ViewPropertyAnimator> imageAnimators = new ArrayList<>();
    private int left;
    private int top;
    private PathListener pathListener;
    private Context mContext;
    public void setImages(List<?> images){
        this.images =  images;
        menuItemCount =  images.size();
        init();
    }

    public PathMenu(Context context) {
        this(context, null);
    }

    public PathMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PathMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
    }

    private void init( ) {
        //删除所有子控件
        this.removeAllViews();
        radius = DensityUtil.dp2px(mContext, 100);
        initMenuItem();
        initCenterButton();
        if (pathListener != null) {
            initListener();
        }
    }

    //初始化子按钮
    private void initMenuItem() {
        if(menuItemCount==0)    return;
        //添加几个菜单项按钮
        RelativeLayout.LayoutParams params = getMenuParams(36,20);
        containerViews.clear();
        imageViewContainers.clear();

        for (int i = 0; i < menuItemCount; i++) {
            ImageView menuItem = new ImageView(mContext);
            if(images.get(i) instanceof Integer){
                menuItem.setImageResource(((Integer) images.get(i)).intValue());
            }else{
                //ImageUtil.showCircle2(menuItem,images.get(i).toString());
            }

            FrameLayout viewContainer = new FrameLayout(mContext);
            viewContainer.setId(0xffff + i);
            viewContainer.addView(menuItem);
            viewContainer.setLayoutParams(params);
            containerViews.add(viewContainer);
            imageViewContainers.add(viewContainer);
            this.addView(viewContainer);
        }

        containerAnimators.clear();
        imageAnimators.clear();
        //初始化动画,每个view对应一个animator
        for (int i = 0; i < menuItemCount; i++) {
            ViewGroup childAt = (ViewGroup) this.getChildAt(i);
            ViewPropertyAnimator anim = ViewPropertyAnimator.animate(childAt);
            anim.setDuration(400);
            containerAnimators.add(anim);
            View image = childAt.getChildAt(0);
            ViewPropertyAnimator anim1 = ViewPropertyAnimator.animate(image);
            anim.setDuration(400);
            imageAnimators.add(anim1);
        }
    }
    //初始化中心大按钮
    private void initCenterButton() {
        //添加中心大按钮
        RelativeLayout.LayoutParams params = getMenuParams(54,10);
        ImageView centerButton_bj = new ImageView(mContext);
        centerButton_bj.setLayoutParams(params);
        centerButton_bj.setImageResource(R.drawable.fengche_bj);
        centerButton_bj.setScaleType(ImageView.ScaleType.FIT_XY);

        RelativeLayout.LayoutParams params2 = getMenuParams(30,22);
        centerButton = new ImageView(mContext);
        centerButton.setId(0xcbcb);
        centerButton.setLayoutParams(params2);
        centerButton.setImageResource(R.drawable.fengche_x);
        centerButton.setScaleType(ImageView.ScaleType.FIT_XY);

        centerButton.setOnClickListener(this);
        this.addView(centerButton_bj);
        this.addView(centerButton);
    }

    private RelativeLayout.LayoutParams getMenuParams(int width, int margin) {
        int w = DensityUtil.dp2px(mContext, width);
        int h = w;
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h);
        params.addRule(ALIGN_PARENT_BOTTOM);
        params.addRule(CENTER_HORIZONTAL);
        params.bottomMargin = DensityUtil.dp2px(mContext, margin);
        return params;
    }

    public void setPathListener(final PathListener pathListener) {
        this.pathListener = pathListener;
        initListener();
    }

    private void initListener() {
        //给子按钮项注册监听器
        for (int i = 0; i < menuItemCount; i++) {
            containerViews.get(i).setOnClickListener(this);
        }
        this.setOnClickListener(null);
        this.setClickable(false);
    }

    //关闭子按钮时 移除所有控件 重新初始化各个控件
    public void initMenu() {
        this.removeAllViews();
        this.init();
    }

    public void open() {

        if (isOpen==true){
            return;
        }
        if(menuItemCount==1){
            sectorAngle = 0;
        }else{
            sectorAngle = 24 * menuItemCount;
        }
        this.setId(0x8888);
        this.setOnClickListener(this);
        isOpen = true;
        if(pathListener != null)
            pathListener.onOpen();
        this.setBackgroundColor(Color.parseColor("#66000000"));
        //大按钮旋转
        RotateAnimation rotate = new RotateAnimation(0, -180,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        rotate.setInterpolator(new OvershootInterpolator());
        rotate.setDuration(400);
        rotate.setFillAfter(true);
        centerButton.startAnimation(rotate);

        //小按钮扇面飞出同时旋转
        int startAngle = (180 - sectorAngle) / 2;
        //各个菜单项按钮间隔
        int distanceAngle;
        if(menuItemCount==1){
            distanceAngle = sectorAngle;
        }else{
            distanceAngle = sectorAngle / (menuItemCount - 1);
        }
        left = containerViews.get(0).getLeft();
        top = containerViews.get(0).getTop();
        for (int i = 0; i < menuItemCount; i++) {
            //角度
            int angle = startAngle + i * distanceAngle;
            //弧度  1角度=π/180弧度
            double radians = angle * Math.PI / 180;
            double deltaX = -Math.cos(radians) * radius;
            double deltaY = -Math.sin(radians) * radius;
            ViewPropertyAnimator viewPropertyAnimator = containerAnimators.get(i);
            viewPropertyAnimator.setInterpolator(new OvershootInterpolator())
                    .x((float) (left + deltaX))
                    .y((float) (top + deltaY));
            ViewPropertyAnimator viewPropertyAnimator1 = imageAnimators.get(i);
            viewPropertyAnimator1.rotation(-360);
        }
    }

    public void close() {
        this.setOnClickListener(null);
        this.setClickable(false);
        isOpen = false;
        if(pathListener != null)
            pathListener.onClose();
        this.setBackgroundResource(android.R.color.transparent);
        //大按钮旋转
        RotateAnimation rotate = new RotateAnimation(0, 180,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        rotate.setInterpolator(new OvershootInterpolator());
        rotate.setDuration(400);
        rotate.setFillAfter(true);
        centerButton.startAnimation(rotate);

        //小按钮收缩
        for (int i = 0; i < menuItemCount; i++) {
            ViewPropertyAnimator viewPropertyAnimator = containerAnimators.get(i);
            viewPropertyAnimator.setInterpolator(new AnticipateInterpolator())
                    .x((float) (left))
                    .y((float) (top));
            ViewPropertyAnimator viewPropertyAnimator1 = imageAnimators.get(i);
            viewPropertyAnimator1.rotation(0);
        }
    }

    //中心大按钮点击切换显示与否
    public void toggle() {
        if (isOpen) {
            close();
        } else {
            open();
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case 0x8888:  //点击空白区域关闭按钮
                if(isOpen)
                    close();
                break;
            case 0xcbcb:   //中心大按钮的点击切换事件
                toggle();
                break;
            //子按钮的点击事件
            case 0xffff:
                menuAnimation(view,0);
                break;
            case 0xffff+1:
                menuAnimation(view,1);
                break;
            case 0xffff+2:
                menuAnimation(view,2);
                break;
            case 0xffff+3:
                menuAnimation(view,3);
                break;
            case 0xffff+4:
                menuAnimation(view,4);
                break;
        }
    }

    private void menuAnimation(final View v, final int position) {
        if (!isOpen) {
            return;
        }
        isOpen = false;
        for (int j = 0; j < menuItemCount; j++) {
            ViewPropertyAnimator viewPropertyAnimator = containerAnimators.get(j);
            if (j != position) {
                viewPropertyAnimator
                        .scaleX(0)
                        .scaleY(0)
                        .setInterpolator(new LinearInterpolator())
                        .setDuration(400);
            }
        }

        v.animate().scaleX(4).scaleY(4).alpha(0).setDuration(400).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                PathMenu.this.setBackgroundResource(android.R.color.transparent);
                initMenu();
                if(pathListener != null)
                    pathListener.menuClick(v,position);
            }
        });
    }

    public interface PathListener {
        void onOpen();  //按钮打开事件
        void onClose(); //按钮关闭事件
        void menuClick(View view,int position); //子按钮点击事件
    }
}

4.联系方式

qq:1509815887@qq.com 
email : zlc921022@163.com 
phone : 18684732678

5.下载地址
点此去下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值