【发布时间】:2017-10-13 20:19:02
【问题描述】:
我知道如何为特定类创建自定义属性。您只需在 Styleable 中使用名称的类名定义它们,就像这样。
<declare-styleable name="MyCustomView">
<attr name="customAttr1" format="integer" />
<attr name="customAttr2" format="boolean" />
</declare-styleable>
然后,当我在布局中使用 MyCustomView 的实例时,可以设置 customAttr1 和 customAttr2。很简单。
我现在要做的是在我的自定义RecyclerView 的子级上使用LayoutParams 的自定义属性,或者更准确地说,在提供各个RecyclerView.ViewHolder 子类的布局文件的根视图中我正在使用。但是,我无法获得传递给我的属性,我不知道为什么。
这是我的 attrs.xml 文件...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollableGridLayoutManager.LayoutParams">
<attr name="cellLayoutMode">
<enum name="scrollable" value="0" />
<enum name="fixedHorizontal" value="1" />
<enum name="fixedVertical" value="2" />
<enum name="fixedHorizontalAndVertical" value="3" />
</attr>
</declare-styleable>
</resources>
这是我的自定义 LayoutParams 类中读取属性的代码...
public LayoutParams(Context context, AttributeSet attrs){
super(context, attrs);
TypedArray styledAttrs = context.obtainStyledAttributes(R.styleable.ScrollableGridLayoutManager_LayoutParams);
if(styledAttrs.hasValue(R.styleable.ScrollableGridLayoutManager_LayoutParams_cellLayoutMode)){
int layoutModeOrdinal = styledAttrs.getInt(R.styleable.ScrollableGridLayoutManager_LayoutParams_cellLayoutMode, layoutMode.ordinal());
layoutMode = LayoutMode.values()[layoutModeOrdinal];
}
styledAttrs.recycle();
}
这是我在布局中为我的一个 ViewHolders 设置它的地方...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:background="#0000FF"
app:cellLayoutMode="fixedVertical">
<TextView
android:id="@+id/mainTextView"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:layout_marginStart="20dp" />
</LinearLayout>
但是,我尝试的任何东西似乎都没有进入“hasValue”调用。它总是像未设置一样返回。
注意:我在定义属性时也尝试了所有这些...
<declare-styleable name="LayoutParams">
<declare-styleable name="ScrollableGridLayoutManager_LayoutParams">
<declare-styleable name="ScrollableGridAdapter_LayoutParams">
...但似乎没有一个工作。
那么我做错了什么?您如何定义特定于您的自定义 LayoutParams 类的属性?
【问题讨论】:
-
几乎完全相同。
LayoutParams子类应该有一个构造函数,它接受Context和AttributeSet,因此您可以像在View子类中一样检索这些值。确保在自定义RecyclerView中覆盖generateLayoutParams(AttributeSet)以返回您的LayoutParams子类。另外,虽然你可以使用任何你喜欢的东西,我相信惯例是将_Layout附加到自定义ViewGroup的name,用于LayoutParams'<declare-styleable>;例如,name="MyCustomView_Layout". -
我刚刚添加了我的代码,正是这样做的。问题是我不确定如何定义属性,因为无论我在布局文件中做什么,我设置的属性不反映在传递给的属性中自定义 LayoutParams 构造函数。他们总是报告为未设置。这就是我要克服的问题。 (我感觉我在您回答时发布了该代码,所以您可能没有看到它。)
-
嗯,我只是用
RecyclerView进行了一个快速而肮脏的测试,以确保我没有忽略任何东西,并且它按预期工作。你究竟是如何夸大项目布局的?您是否在inflate()调用中传递父自定义RecyclerView? -
哦,等等,我现在看到了。您使用了错误的
obtainStyledAttributes()重载。也就是说,您忘记将AttributeSet传递给它。应该是context.obtainStyledAttributes(attrs, R.styleable.ScrollableGridLayoutManager_LayoutParams);。 -
呃!!! [捂脸]我觉得自己像个白痴!我怎么没看到?问题虽然......这应该是declare-styleable标签中name属性的正确值......或者它是否重要(即没有错误的答案,它只是一个约定?)
标签: android android-layout android-recyclerview custom-attributes android-custom-attributes