0

我从这个答案中得到了 Movable FAB 的代码: https ://stackoverflow.com/a/46373935

我相信这样的按钮通常更方便用户体验。但是这个按钮在点击时不会改变它的动画——它会看到 onClick 监听器并在点击时通知他们,但它不会改变它的外观。

下面的代码带有 2 个浮动操作按钮——普通按钮和可移动按钮,因此您可以自己查看 onClick 动画的区别。

.0. 我的主要问题是——如何使这个可移动按钮的动画与普通按钮的动画完全相同?(动画,除了开始和结束阶段还有过渡阶段。看起来像一个圆圈从您单击按钮的地方开始。为了更好地理解,您可以查看提供的图片或运行代码)。

.1。附加问题——您是否发现使用这个可移动按钮而不是常规按钮有任何缺点(例如程序无法正常运行)?

activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton


            android:id="@+id/floating_action_button"
            android:layout_width="90dp"
            android:layout_height="90dp"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginBottom="120dp"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="56dp"/>




    <com.example.clickablemovable.MovableFloatingActionButton

            android:id="@+id/movable_floating_action_button"
            android:layout_gravity="bottom|end"
            android:clickable="true"
            android:layout_width="90dp"
            android:layout_height="90dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginEnd="56dp"
            android:layout_marginBottom="120dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

public class MainActivity extends AppCompatActivity {

    MovableFloatingActionButton mMovableFloatingActionButton;

    FloatingActionButton mFloatingActionButton;

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

        mMovableFloatingActionButton = findViewById(R.id.movable_floating_action_button);
        mFloatingActionButton = findViewById(R.id.floating_action_button);


        mMovableFloatingActionButton.setOnClickListener(view -> showMessage("mMovableFloatingActionButton"));
        mFloatingActionButton.setOnClickListener(view -> showMessage("mFloatingActionButton"));

    }

    private void showMessage(String message) {
        Snackbar.make(findViewById(R.id.floating_action_button), message, Snackbar.LENGTH_SHORT).show();
    }
}

MovableFloatingActionButton.java

import android.content.Context;

import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MovableFloatingActionButton extends FloatingActionButton implements View.OnTouchListener {

    private final static float CLICK_DRAG_TOLERANCE = 10; // Often, there will be a slight, unintentional, drag when the user taps the FAB, so we need to account for this.

    private float downRawX, downRawY;
    private float dX, dY;

    public MovableFloatingActionButton(Context context) {
        super(context);
        init();
    }

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

    public MovableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

        int action = motionEvent.getAction();
        if (action == MotionEvent.ACTION_DOWN) {

            downRawX = motionEvent.getRawX();
            downRawY = motionEvent.getRawY();
            dX = view.getX() - downRawX;
            dY = view.getY() - downRawY;

            return true; // Consumed

        } else if (action == MotionEvent.ACTION_MOVE) {

            int viewWidth = view.getWidth();
            int viewHeight = view.getHeight();

            View viewParent = (View) view.getParent();
            int parentWidth = viewParent.getWidth();
            int parentHeight = viewParent.getHeight();

            float newX = motionEvent.getRawX() + dX;
            newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
            newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent

            float newY = motionEvent.getRawY() + dY;
            newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
            newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent

            view.animate()
                    .x(newX)
                    .y(newY)
                    .setDuration(0)
                    .start();

            return true; // Consumed

        } else if (action == MotionEvent.ACTION_UP) {

            float upRawX = motionEvent.getRawX();
            float upRawY = motionEvent.getRawY();

            float upDX = upRawX - downRawX;
            float upDY = upRawY - downRawY;

            if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
                return performClick();
            } else { // A drag
                return true; // Consumed
            }

        } else {
            return super.onTouchEvent(motionEvent);
        }

    }

}

在此处输入图像描述 在此处 输入图像描述

4

0 回答 0