android - 将自定义 View xml 文件中的属性传播给子项

标签 android android-custom-view

我有一个自定义 View ,其布局包含一个 EditText。 我希望在 xml 布局文件中添加 android:imeOptions 或其他,并让它传播到子 EditText

有没有办法做到这一点,没有自定义属性(为了保持一致性)?

谢谢。

最佳答案

这是可能的,通过在您的自定义 ViewGroup 中检索属性值的构造函数,并将其设置在适当的子项上 View在添加它们时,通过覆盖 ViewGroupaddView(View, int, LayoutParams)方法。

有几种不同的方法可以从 AttributeSet 中获取该值.以下是使用 imeOptions 的示例属性。


可能最“标准”的方法是在您的 CustomViewGroup 中包含平台属性的 <declare-styleable> ,并像检索自定义属性一样检索其值。

res/values/ :

<resources>
    <declare-styleable name="CustomViewGroup">
        <attr name="android:imeOptions" />
        ...
    </declare-styleable>
</resources>

在 Java 代码中:

public class CustomViewGroup extends ViewGroup {
    private static final int IME_OPTIONS_NONE = -1;

    private int mImeOptions;

    public CustomViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomViewGroup);
        mImeOptions = a.getInt(R.styleable.CustomViewGroup_android_imeOptions, IME_OPTIONS_NONE);
        ...
        a.recycle();
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);

        if (child instanceof EditText && mImeOptions != IME_OPTIONS_NONE) {
            ((EditText) child).setImeOptions(mImeOptions);
        }
    }
}

或者,您自己定义属性数组,而不是通过资源,并以类似方式检索值。

public class CustomViewGroup extends ViewGroup {
    private static final int[] ANDROID_ATTRS = { android.R.attr.imeOptions };
    private static final int IME_OPTIONS_NONE = -1;

    private int mImeOptions;

    public CustomViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, ANDROID_ATTRS);

        // 0 is passed as the first argument here because
        // android.R.attr.imeOptions is the 0th element in
        // the ANDROID_ATTRS array.
        mImeOptions = a.getInt(0, IME_OPTIONS_NONE);

        a.recycle();
    }

    // Same addView() method
}

或者,直接从 AttributeSet 获取原始值, 使用适当的 getAttribute*Value()方法。

public class CustomViewGroup extends ViewGroup {
    private static final String NAMESPACE = "http://schemas.android.com/apk/res/android";
    private static final String ATTR_IME_OPTIONS = "imeOptions";
    private static final int IME_OPTIONS_NONE = -1;

    private int mImeOptions;

    public CustomViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);

        mImeOptions = attrs.getAttributeIntValue(NAMESPACE, ATTR_IME_OPTIONS, IME_OPTIONS_NONE);
    }

    // Same addView() method
}

如果你想传播给 child 的属性View s 是您自定义的 ViewGroup的父类(super class)已经使用了它自己,那么你不一定需要从 AttributeSet 中读取它.您可以在调用 super 之后使用适当的 getter 方法检索其值构造函数,它已经被处理和应用。

关于android - 将自定义 View xml 文件中的属性传播给子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40701384/

相关文章:

android - 如何在Android的textview上删除顶部和底部空间

android - 在 customView 的 TypedArray 上获取 getString 的空指针异常

java - 如何解析没有数组名称的 JSON 数组

android - 线程仅在 Android 的 Release模式下卡住 UI

java - 对对象数组使用 Arrays.binarySearch 并在对象中查找字符串

android - 如何自定义 ListView 以使行项目的第一和第二位置具有不同的布局?

android - Android屏幕上的 float View

android - 调试时看不到变量值

java - 我应该在哪里调用 fragment 中的 Rest API

android - 为 ViewPager 放置阴影