如何按偏好以编程方式交换 Kotlin 中的 2 个按钮位置?

How to swap 2 button positions in Kotlin programatically by preference?

所以,我有 2 个按钮,我想通过使用首选项来交换它们,但是是的,我无法让它们正确切换

这是我的偏好代码

    // In MainActivity.kt

    override fun onResume() {
        super.onResume()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val shouldFlipButtonPosition = sharedPreferences.getBoolean("buttonpositions", false)
        if (isButtonPositionFlipped != shouldFlipButtonPosition) {
            isButtonPositionFlipped = shouldFlipButtonPosition
            val cleanBtn = findViewById<Button>(R.id.cleanBtn)
            val analyzeBtn = findViewById<Button>(R.id.analyzeBtn)
            if (isButtonPositionFlipped) {

                // Buttons swaped.

            } else {

               // Buttons back to normal.

            }
        }

我再次尝试让它们交换,但我得到了一些像这样的丑陋结果:

    override fun onResume() {
        super.onResume()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val shouldFlipButtonPosition = sharedPreferences.getBoolean("buttonpositions", false)
        if (isButtonPositionFlipped != shouldFlipButtonPosition) {
            isButtonPositionFlipped = shouldFlipButtonPosition
            val cleanBtn = findViewById<Button>(R.id.cleanBtn)
            val analyzeBtn = findViewById<Button>(R.id.analyzeBtn)
            if (isButtonPositionFlipped) {
                val posX = cleanBtn.x
                val posY = cleanBtn.y
                analyzeBtn.x = posX
                analyzeBtn.y = posY
            } else {
                cleanBtn.setPadding(0, 0, 0, 0)
                analyzeBtn.setPadding(0, 0, 0, 0)
            }
        }
    }
    override fun onResume() {
        super.onResume()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val shouldFlipButtonPosition = sharedPreferences.getBoolean("buttonpositions", false)
        if (isButtonPositionFlipped != shouldFlipButtonPosition) {
            isButtonPositionFlipped = shouldFlipButtonPosition
            val cleanBtn = findViewById<Button>(R.id.cleanBtn)
            val analyzeBtn = findViewById<Button>(R.id.analyzeBtn)
            if (isButtonPositionFlipped) {
                cleanBtn.setPadding(640, 0, 0, 0)
                analyzeBtn.setPadding(0, 0, 640, 0)
            } else {
                cleanBtn.setPadding(0, 0, 0, 0)
                analyzeBtn.setPadding(0, 0, 0, 0)
            }
        }
    }

我不得不提一下我尝试使用 set.Margins 但没有用

如何使用此方法交换它们?

尝试使用 RelativeLayout(或 ConstraintLayout):

   override fun onResume() {
        super.onResume()
        val cleanBtn = findViewById<Button>(R.id.cleanBtn);
        val analyzeBtn = findViewById<Button>(R.id.analyzeBtn);
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val shouldFlipButtonPosition = sharedPreferences.getBoolean("buttonpositions", false)
        var isButtonPositionFlipped = true;
        if (isButtonPositionFlipped != shouldFlipButtonPosition) {
            isButtonPositionFlipped = shouldFlipButtonPosition;
            (cleanBtn.layoutParams as RelativeLayout.LayoutParams).leftMargin =
                dipToPixels(this, 100f);//100dp?
            (analyzeBtn.layoutParams as RelativeLayout.LayoutParams).leftMargin = 0;
        } else {
            (cleanBtn.layoutParams as RelativeLayout.LayoutParams).leftMargin = 0;
            (analyzeBtn.layoutParams as RelativeLayout.LayoutParams).leftMargin =
                dipToPixels(this, 100f);//100dp?
        }
    }

    private fun dipToPixels(context: Context, dipValue: Float): Int {
        val metrics: DisplayMetrics = context.resources.displayMetrics
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics).toInt()
    }
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    tools:context=".TestActivity">

    <Button
        android:id="@+id/cleanBtn"
        android:layout_width="wrap_content"
        android:text="111"
        android:layout_height="wrap_content"></Button>

    <Button
        android:id="@+id/analyzeBtn"
        android:layout_marginLeft="100dp"
        android:layout_width="wrap_content"
        android:text="222"
        android:layout_height="wrap_content"></Button>

</RelativeLayout>

如果它们在 LinearLayout 中并且它们是该 LinearLayout 的仅有的两个子视图,您可以像这样颠倒子视图的顺序:

findViewById<LinearLayout>(R.id.theParentLinearLayout).apply {
    val children = children.toList()
    removeAllViews()
    for (child in children.asReversed()) {
        addView(child)
    }
}

如果他们需要不同大小的边距,您也可以交换他们的布局参数:

findViewById<LinearLayout>(R.id.theParentLinearLayout).apply {
    val children = children.toList()
    children[0].layoutParams = children[1].layoutParams
        .also { children[1].layoutParams = children[0].layoutParams }
    removeAllViews()
    for (child in children.asReversed()) {
        addView(child)
    }
}

如果有两个以上的子视图,您可以在可变列表中搜索并交换它们,然后再将它们全部添加回父视图。

findViewById<LinearLayout>(R.id.theParentLinearLayout).apply {
    val children = children.toMutableList()
    val buttonAIndex = children.indexOf(findViewById(R.id.buttonA))
    val buttonBIndex = children.indexOf(findViewById(R.id.buttonB))
    children[buttonAIndex] = children[buttonBIndex]
        .also { children[buttonBIndex] = children[buttonAIndex] }
    children[buttonAIndex].layoutParams = children[buttonBIndex].layoutParams
        .also { children[buttonBIndex].layoutParams = children[buttonAIndex].layoutParams }
    removeAllViews()
    for (child in children) {
        addView(child)
    }
}