使用ConstraintLayout+FloatingActionButton实现悬浮菜单效果

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_41673194/article/details/82912779

  • 布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_email"
        app:backgroundTint="@android:color/holo_blue_dark"
        app:borderWidth="0dp"
        app:fabSize="mini"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintCircle="@id/fab"
        app:layout_constraintCircleAngle="0"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:rippleColor="@android:color/darker_gray" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_map"
        app:backgroundTint="@android:color/holo_purple"
        app:borderWidth="0dp"
        app:fabSize="mini"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintCircle="@id/fab"
        app:layout_constraintCircleAngle="120"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:rippleColor="@android:color/darker_gray" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_info"
        app:backgroundTint="@android:color/holo_green_dark"
        app:borderWidth="0dp"
        app:fabSize="mini"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintCircle="@id/fab"
        app:layout_constraintCircleAngle="240"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:rippleColor="@android:color/darker_gray" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_dialer"
        app:borderWidth="0dp"
        app:fabSize="normal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:rippleColor="@android:color/darker_gray" />
    
</android.support.constraint.ConstraintLayout>
  • 代码
public class MainActivity extends AppCompatActivity {
    @BindView(R.id.fab)
    FloatingActionButton fab;
    @BindView(R.id.fab1)
    FloatingActionButton fab1;
    @BindView(R.id.fab2)
    FloatingActionButton fab2;
    @BindView(R.id.fab3)
    FloatingActionButton fab3;

    private List<View> menuViews = new ArrayList<>();
    private boolean isOpened = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        ButterKnife.bind(this);
        
        menuViews.add(fab1);
        menuViews.add(fab2);
        menuViews.add(fab3);
    }

    //事件分发控制
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (isOpened) {
                if (!inRangeOfView(fab, ev)) {
                    switchMenu(isOpened);
                    isOpened = !isOpened;
                }
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 判断点击的是否是指定的view
     * @param view   指定的view
     * @param ev
     * @return
     */
    private boolean inRangeOfView(View view, MotionEvent ev){
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];
        if(ev.getX() < x || ev.getX() > (x + view.getWidth()) || ev.getY() < y || ev.getY() > (y + view.getHeight())){
            return false;
        }
        return true;
    }

    @OnClick({R.id.fab1, R.id.fab2, R.id.fab3, R.id.fab})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.fab:
                switchMenu(isOpened);
                isOpened = !isOpened;
                break;
            case R.id.fab1:
                ToastUtil.showShort("点击fab1");
                break;
            case R.id.fab2:
                ToastUtil.showShort("点击fab2");
                break;
            case R.id.fab3:
                ToastUtil.showShort("点击fab3");
                break;
        }
    }

    private void switchMenu(boolean isOpened) {
//        int startRadius = isOpened ? DensityUtil.sp2px(100) : 0;
//        int endRadius = isOpened ? 0 : DensityUtil.sp2px(100);

        int startRadius = dpToPixel(isOpened ? 100 : 0);
        int endRadius = dpToPixel(isOpened ? 0 : 100);

        ToastUtil.showShort(startRadius + "::" + endRadius);

        ValueAnimator valueAnimator = ValueAnimator.ofInt(startRadius, endRadius);
        valueAnimator.setDuration(300);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                for (int i = 0; i < menuViews.size(); i++) {
                    ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) menuViews.get(i).getLayoutParams();
                    layoutParams.circleRadius = (int) animation.getAnimatedValue();
                    menuViews.get(i).setLayoutParams(layoutParams);
                }
            }
        });
        valueAnimator.start();
    }

    private int dpToPixel(int dp) {
        DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
        return dp < 0 ? dp : Math.round(dp * displayMetrics.density);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41673194/article/details/82912779
今日推荐