android 中有没有办法通过 xml android:id 将字段设置到自定义视图中

Is there a way in android to set a field via xml android:id into a custom view

例如,我有一个自定义按钮,想将它连接到一个 SeekBar:

public class SeekBarButton extends ImageButton {

    SeekBar seekBar;

    public SeekBarButton(Context context) {
        super(context);
    }

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

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

    public void setSeekBar(SeekBar seekBar) {
        this.seekBar = seekBar;
    }

    public SeekBar getSeekBar() {
        return seekBar;
    }
}

我可以在代码中做到:

sbb = (SeekBarButton) rootView.findViewById(R.id.minus_red);
sbRed = (SeekBar) rootView.findViewById(R.id.sbRed);
sbb.setSeekBar(sbRed);

但是 8 个按钮会提供很多样板,我想要这样的东西:

    <com.whatever.views.SeekBarButton
        ...
        whatToPutHere:seekbar="@+id/sbRed"  // like this? whatToPutHere?
        android:id="@+id/minus_red" />

    <SeekBar
        android:id="@+id/sbRed"

        ... />

我觉得你很接近。在布局文件的第一个 XML 标记中(我的示例是 RelativeLayout),您需要引用 "custom":

<RelativeLayout
    xmlns:custom="http://schemas.android.com/apk/res-auto">

然后再往下,无论您的自定义 ImageButton 在哪里,您都需要这个:

<com.whatever.views.SeekBarButton
        ...
        custom:seekbar="@+id/sbRed"
        android:id="@+id/minus_red" />

您的 project\res\values 文件夹中还需要一个 seekBarButton.xml 文件,如果您还不知道的话。

最简单的方法是创建一个包含 ButtonSeekbar 的自定义 ViewGroup如果您出于任何原因无法做到这一点,这里有一个解决方案:

完成这项工作需要几个步骤。首先,您必须定义一个自定义 XML 属性,然后您可以引用和使用它。

编辑(或创建)res/values/attrs.xml。添加:

<declare-styleable name="SeekBarButton">
    <attr name="seekbarId" format="integer" />
</declare-styleable>

然后,在 SeekBarButton 中,从构造函数中调用它:

private void init(Context context, AttributeSet attrs, int defStyleAttr) {
    if (attrs != null) {
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.SeekBarButton, defStyleAttr, 0);
        mSeekbarId = a.getResourceId(R.styleable.SeekBarButton_seekbarId, 0);
        a.recycle();
    }
}

最后,在布局文件的根 ViewGroup 中,添加

xmlns:app="http://schemas.android.com/apk/res-auto"

然后,

<com.whatever.views.SeekBarButton
    android:id="@+id/minus_red"
    app:seekbarId="@+id/sbRed"
    ... />

<SeekBar
    android:id="@+id/sbRed"
    ... />

注意您需要在SeekBarButton中调用((ViewGroup) getParent()).findViewById(mSeekbarId)来实例化SeekBar,但getParent()将为空在 SeekBarButton 构造函数中。所以,延迟 findViewById() 直到你需要 SeekBar.