可移动扩展浮动操作按钮

问题描述 投票:0回答:1

我正在使用 ExtendedFloatingActionButton 并使其在屏幕上可移动,但当将其移动到屏幕左侧时,左侧的视图丢失。

这是屏幕图像,其中按钮在右侧工作正常:

这是左侧按钮不起作用的屏幕图像: 这是 xml 文件:

<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:icon="@drawable/ic_baseline_4g_mobiledata_24"
    android:text=""
    app:iconTint="@color/white"
    android:textColor="@color/white"
    app:backgroundTint="@color/black"
    app:iconGravity="end"
    android:textAllCaps="false"
    android:layout_gravity="center|end"
    android:layout_marginBottom="20dp"
    android:layout_marginEnd="20dp"/>

这是我的主类代码:

class MainActivity : AppCompatActivity(), View.OnTouchListener {
lateinit var fab: ExtendedFloatingActionButton

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


private var downRawX = 0f
private  var downRawY:kotlin.Float = 0f
private var dX = 0f
private  var dY:kotlin.Float = 0f

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val view: View = findViewById(R.id.fab);
    view.setOnTouchListener(this);

    fab = findViewById(R.id.fab)

    fab.shrink()

    fab.setOnClickListener {
        if (!fab.isExtended) {
            fab.extend()
            fab.text = "Boost: Off \nPing: 99 Jitter: 15"
            fab.maxLines = 2
            fab.background = applicationContext.getDrawable(R.drawable.fab_back)
        } else {
            fab.shrink()
            fab.background = applicationContext.getDrawable(R.drawable.circle_fab)

        }
    }
}

override fun onTouch(view: View?, motionEvent: MotionEvent): Boolean {

    val action = motionEvent.action
    return if (action == MotionEvent.ACTION_DOWN) {
        downRawX = motionEvent.rawX
        downRawY = motionEvent.rawY
        dX = view!!.x - downRawX
        dY = view!!.y - downRawY
        true // Consumed
    } else if (action == MotionEvent.ACTION_MOVE) {
        val viewWidth = view!!.width
        val viewHeight = view!!.height
        val viewParent = view!!.parent as View
        val parentWidth = viewParent.width
        val parentHeight = viewParent.height
        var newX = motionEvent.rawX + dX
        newX = Math.max(0f, newX) // Don't allow the FAB past the left hand side of the parent
        newX = Math.min(
            (parentWidth - viewWidth).toFloat(),
            newX)

        if (newX < 1.0) {
            fab.iconGravity = MaterialButton.ICON_GRAVITY_START
        } else {
            fab.iconGravity = MaterialButton.ICON_GRAVITY_END
        }
        Log.e("error", newX.toString())
        // Don't allow the FAB past the right hand side of the parent
        var newY = motionEvent.rawY + dY
        newY = Math.max(0f, newY) // Don't allow the FAB past the top of the parent
        newY = Math.min(
            (parentHeight - viewHeight).toFloat(),
            newY
        ) // Don't allow the FAB past the bottom of the parent
        view!!.animate()
            .x(newX)
            .y(newY)
            .setDuration(0)
            .start()
        true // Consumed
    } else if (action == MotionEvent.ACTION_UP) {
        val upRawX = motionEvent.rawX
        val upRawY = motionEvent.rawY
        val upDX = upRawX - downRawX
        val upDY = upRawY - downRawY
        if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
            performClick()
        } else { // A drag
            true // Consumed
        }
    } else {
        super.onTouchEvent(motionEvent)
    }
}

private fun performClick(): Boolean {

    if (!fab.isExtended) {
        fab.extend()
        fab.text = "Boost: Off \nPing: 99 Jitter: 15"
        fab.maxLines = 2
        fab.background = applicationContext.getDrawable(R.drawable.fab_back)
    } else {
        fab.shrink()
        fab.background = applicationContext.getDrawable(R.drawable.circle_fab)

    }
    return true
}

}

有人可以帮我解决这个问题吗?我不知道为什么会这样。

android kotlin floating-action-button moveable
1个回答
0
投票

请检查下面的类及其 xml

package com.example.merchantdemo.customDesign;

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.ExtendedFloatingActionButton;

public class MovableFloatingActionButton extends ExtendedFloatingActionButton 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);
    }

}

}

这是 MovableFloatingActionButton 的 XML

<com.example.MovableFloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="@dimen/fab_margin"
    android:layout_marginBottom="16dp"
    app:icon="@android:drawable/ic_input_add"
    android:text="@string/extended_fab_label"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

希望这对您有帮助

© www.soinside.com 2019 - 2024. All rights reserved.