我有一个自定义视图ZoneSwitchItem(扩展了LinearLayout),该片段在片段布局xml中使用.
从定制视图内部,我需要获取在片段xml中分配给它的ID.所以我用attrs.getIdAttribute();但它返回null而不是预期的id zone1.
我可以添加自定义属性ZoneSwitchItemId,但如果可以使用默认的id属性,则可以避免这种情况.
片段xml中的用法:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
android:id="@+id/zone1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/cardPadding4x"
android:gravity="center_horizontal"
app:zoneItemStyle="ArmourFont_HeadlineBig" />
...
自定义视图:
public class ZoneSwitchItem extends LinearLayout {
private TextView itemValue;
private TextView itemTitle;
public ZoneSwitchItem(Context context) {
super(context);
init(context, null);
}
public ZoneSwitchItem(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ZoneSwitchItem(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public void onStart() {
EventBus.getDefault().register(this);
}
public void onStop() {
EventBus.getDefault().unregister(this);
}
private void init(final Context context, AttributeSet attrs) {
inflate(getContext(), R.layout.zone_switch_item, this);
itemValue = findViewById(R.id.itemValue);
itemTitle = findViewById(R.id.itemTitle);
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ZoneSwitchItem, 0, 0);
try {
if (typedArray.getString(R.styleable.ZoneSwitchItem_zoneItemStyle) != null &&
typedArray.getString(R.styleable.ZoneSwitchType_zoneItemImage).equals("ArmourFont_HeadlineBig")) {
itemValue.setTextAppearance(context, R.style.ArmourFont_HeadlineBig);
}
} finally {
typedArray.recycle();
}
}
final String id = attrs.getIdAttribute(); // <<== returns null
itemValue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new OnZoneSwitchItemClickedEvent(id));
}
});
}
public void setSelected(boolean selected) {
float alpha;
if (selected) {
alpha = 1.0f;
} else {
alpha = 0.5f;
}
itemValue.setAlpha(alpha);
itemTitle.setAlpha(alpha);
}
}
解决方法:
Return the value of the “id” attribute or null if there is not one. Equivalent to getAttributeValue(null, “id”).
the getAttributeValue() method中的第一个参数是属性的名称空间.这就是问题所在,因为null表示没有命名空间,但是android:id属性位于android前缀代表的命名空间中– /apk/res/android.
这意味着getIdAttribute()方法将仅返回没有前缀的id属性的值.那是:
id="@+id/zone1"
... />
我不确定这个方法有多有用,因为在上面的示例中,它实际上将返回完整的字符串(@ id / zone1),您仍然必须具有单独的android:id属性才能获取View正确分配了ID,Android Studio肯定会抱怨该属性缺少名称空间前缀.
想到的第一个解决方案是直接调用getAttributeValue()并传递正确的名称空间.
String id = attrs.getAttributeValue("/apk/res/android", "id");
但是,这将以字符串形式返回以@开头的整数ID值,因为aapt似乎在处理XML时直接将其替换为XML中的该值.
实际的简单资源名称可以从Resources,其getResourceEntryName()方法和View的getId()方法获得,因为ID将在超级调用期间在View的构造函数中设置.例如:
String id = getResources().getResourceEntryName(getId());
标签:android
来源: https://codeday.me/bug/1110/694.html