Android将按钮位置与图像匹配

yftpprvb  于 2023-03-06  发布在  Android
关注(0)|答案(1)|浏览(94)

我如何放置一个按钮,使它的位置与图像上的位置匹配,图像被调整大小以适合屏幕的宽度。
这就是

我已将其添加到MainActivity的ConstraintLayout中

<?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"
        android:id="@+id/test"
        tools:context=".MainActivity">
    <ImageView
            android:layout_width="0dp"
            android:layout_margin="0dp"
            android:padding="0dp"
            android:layout_height="0dp" app:srcCompat="@drawable/untitled" android:id="@+id/imageView"
            app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
            android:scaleType="fitStart"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

左上角位于像素(100,100)上,图像的大小为500 × 500像素,黑盒的大小为50 × 50像素。
我试着通过使用屏幕上图像的宽度来计算位置,并使用实际宽度创建一个乘数。但是按钮关闭了很多,我不知道如何将它与图像匹配。

public class MainActivity extends AppCompatActivity {

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

        ConstraintLayout viewById = findViewById(R.id.test);

        Button button = new Button(this);
        button.setId(View.generateViewId());
        ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(200, 200);
        layoutParams.setMargins(0, 0, 0, 0);
        button.setLayoutParams(layoutParams);
        button.setPadding(0, 0, 0, 0);
        button.setElevation(100f);

        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.clone(viewById);
        constraintSet.connect(button.getId(), ConstraintSet.START, viewById.getId(), ConstraintSet.START);
        constraintSet.connect(button.getId(), ConstraintSet.TOP, viewById.getId(), ConstraintSet.TOP);

        viewById.addView(button);

        constraintSet.applyTo(viewById);

        ImageView image = findViewById(R.id.imageView);
        final be.robben.test.MainActivity mainActivity = this;

        ViewTreeObserver vto = image.getViewTreeObserver();

        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            public boolean onPreDraw() {
                image.getViewTreeObserver().removeOnPreDrawListener(this);
                int finalHeight, finalWidth;
                finalHeight = image.getHeight();
                finalWidth = image.getWidth();

                init(image.getDrawable().getIntrinsicWidth(), finalHeight, mainActivity);
                return true;
            }
        });
    }

    public void init(final int x, final int y, final AppCompatActivity context) {

        float mult = ((float) x) / ((float) 500);
        ConstraintLayout viewById = context.findViewById(R.id.test);

        Button button = new Button(context);
        button.setId(View.generateViewId());
        ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams((int) (50 * mult), (int) (50 * mult));
        float a = ((float) 100 / (float) 500) * x;
        layoutParams.setMargins(0, 0, 0, 0);
        layoutParams.setMarginStart(0);
        layoutParams.setMarginEnd(0);
        layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;
        button.setLayoutParams(layoutParams);
        button.setX(a);
        button.setY(a);
        button.setPadding(0, 0, 0, 0);

        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.connect(button.getId(), ConstraintSet.START, viewById.getId(), ConstraintSet.START, 0);
        constraintSet.connect(button.getId(), ConstraintSet.TOP, viewById.getId(), ConstraintSet.TOP, 0);

        viewById.addView(button);

    }

}
hgc7kmma

hgc7kmma1#

仅仅为了获得图像中矩形的屏幕位置就需要你获得图像。你不能在OnCreate中完成它,因为图像还没有附加到屏幕上。你需要做如下的事情:

@Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        ImageView imageView = findViewById(R.id.imageView);
        Matrix matrix = imageView.getImageMatrix();
        RectF rect = new RectF(100,100,500+100,500+100);
        matrix.mapRect(rect);

获得屏幕上的位置后,可以添加按钮。无需使用约束集创建按钮并填充其layoutParams来定位按钮:

Button button = new Button(this);
        button.setId(View.generateViewId());
        ConstraintLayout.LayoutParams layoutParams =
                new ConstraintLayout.LayoutParams((int) rect.width(), (int) rect.height());
        layoutParams.leftMargin = (int) rect.left;
        layoutParams.topMargin = (int) rect.top;
        layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;
        ConstraintLayout layout = findViewById(R.id.test);
        layout.addView(button, layoutParams);
    }

这似乎是一件奇怪的事情,但这应该会给你指明正确的方向。

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.stack1)
        var iv = findViewById<ImageView>(R.id.imageView)
        iv.doOnLayout {
            var iv = findViewById<ImageView>(R.id.imageView)
            val matrix = iv.imageMatrix
            val bounds = iv.drawable.bounds
            val boxX = 100f
            val boxY = 100f
            val boxW = 50f
            val boxH = 50f
            val imageWidth = 500f
            val imageHeight = 500f
            val rect = RectF(boxX, boxY, boxW + boxX, boxH + boxY)
            matrix.postScale(bounds.width() / imageWidth, bounds.height() / imageHeight)
            matrix.mapRect(rect)
            val button = Button(this)
            button.text = "DoIt"
            button.setBackgroundColor(0xFFFF3300.toInt())
            button.setId(View.generateViewId())
            val layoutParams =
                ConstraintLayout.LayoutParams(rect.width().toInt(), rect.height().toInt())
            layoutParams.leftMargin = rect.left.toInt()
            layoutParams.topMargin = rect.top.toInt()
            layoutParams.topToTop = iv.id
            layoutParams.leftToLeft = iv.id
            val layout = findViewById<ConstraintLayout>(R.id.test)
            layout.addView(button, layoutParams)
            button.requestLayout()
        }
    }

这个管用

相关问题