1

我有一个自定义视图LockButton,它只是一个包含两个特定子视图的 FrameLayout。它拥有一个ImageButton以及一种自定义视图ProgressIndicator。这个问题围绕着 LockButton 和 ImageButton 的行为。特别是我为 LockButton 添加了一个自定义状态。ImageButton 的源有一个 StateListDrawable,它的背景有一个 ColorStateList。

问题是当我更改 LockButton 中的状态时,该更改未显示在 ImageButton 中

状态变化

我究竟做错了什么?

锁定按钮类:

public class LockButton extends FrameLayout {

    private static final int[] STATE_LOCKED = {R.attr.state_locked};
    private boolean locked = true;

    View button;

    public LockButton(@NonNull Context context) {
        this(context, null);
    }

    public LockButton(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.lock_button, this);
        button = findViewById(R.id.lock_button_actual);

    }

    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
        button.setOnClickListener(l);
    }


    @Override
    public int[] onCreateDrawableState(int extraSpace) {

        final int[] drawableState;
        if(locked){
            drawableState = super.onCreateDrawableState(extraSpace + 1);
            mergeDrawableStates(drawableState, STATE_LOCKED);
        } else {
            drawableState = super.onCreateDrawableState(extraSpace);
        }
        return drawableState;
    }

    public void lock(boolean locked) {
        if(this.locked != locked) {
            this.locked = locked;
        }
        refreshDrawableState();
        button.refreshDrawableState();

    }

    public static class ProgressCircle extends View {...}

}

锁定按钮布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:state_locked="true"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <view class="com.example.LockButton$ProgressCircle"
        android:layout_width="68dp"
        android:layout_height="68dp"
        android:layout_gravity="center"
        />

    <ImageButton
        android:id="@+id/lock_button_actual"
        android:layout_width="@dimen/fab_size"
        android:layout_height="@dimen/fab_size"
        android:background="@drawable/button_lock_background"
        android:src="@drawable/icon_lock_status"
        android:tint="@color/white"
        android:elevation="6dp"
        android:layout_gravity="center"
        android:duplicateParentState="true"
        />
</FrameLayout>

属性 XML:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="lockState">
        <attr name="state_locked" format="boolean" />
    </declare-styleable>
</resources>

可绘制的 icon_lock_status.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item app:state_locked="false" android:drawable="@drawable/icon_lock_open" />
    <item app:state_locked="true" android:drawable="@drawable/icon_lock_closed"/>
</selector>

可绘制的 button_lock_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight"
    >
    <item>
        <shape android:shape="oval">
            <solid android:color="@color/button_lock_color" />
        </shape>
    </item>
</ripple>

颜色 button_lock_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item app:state_locked="false" android:color="@color/grey_dark" />
    <item app:state_locked="true" android:color="@color/vibrant_red" />
</selector>

当我需要更改状态时,我只需调用

lockButton.lock(true); // or false

在锁定按钮上


我还测试了使用默认状态而不是我的自定义状态是否会更好。这没有帮助。ImageButton 仍然不响应默认状态的变化。

将 StateListDrawable 设置为 LockButton (FrameLayout) 的背景确实有效。所以状态变化在父母身上正常工作,只是没有反映在孩子身上。

4

0 回答 0