如何传递视图引用到android自定义视图?

我做了如下

1)创build一个风格

<declare-styleable name="Viewee"> <attr name="linkedView" format="reference"/> </declare-styleable> 

2)定义自定义视图布局

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ffc0"> <TextView android:id="@+id/custom_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="[text]" /> </LinearLayout> 

3)创build所需的类

 public class Viewee extends LinearLayout { public Viewee(Context context, AttributeSet attributeSet) { super(context, attributeSet); View.inflate(context, R.layout.viewee, this); TextView textView = (TextView) findViewById(R.id.custom_text); TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.Viewee); int id = typedArray.getResourceId(R.styleable.Viewee_linkedView, 0); if (id != 0) { View view = findViewById(id); textView.setText(((TextView) view).getText().toString()); } typedArray.recycle(); } } 

最后在下面的一个活动

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.ns" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:id="@+id/tvTest" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="android"/> <com.ns.Viewee android:layout_width="fill_parent" android:layout_height="fill_parent" app:linkedView="@+id/tvTest" /> </LinearLayout> 

现在,尽pipe我在Viewee约束器中收到一个非零id ,但findViewById(id)返回null和NullPointerException发生。

我错过了什么?

我在这里描述了

Solutions Collecting From Web of "如何传递视图引用到android自定义视图?"

我find了答案!

问题是与findViewById(id)和我叫它的地方。 如文档所述, findViewById仅查找子视图,而不是在较高层级上存在视图。 所以我必须调用类似于getRootView().findViewById(id)但也返回null ,因为我称之为不正确。

Viewee Viewee本身还没有附加到它的根目录,所以调用会导致NullPointerException

所以,如果我调用getRootView().findViewById(id)之后的其他地方,它工作正常, "@+id/tvTest""@id/tvTest"是正确的。 我已经testing过了!

答案如下

 public class Viewee extends LinearLayout { public Viewee(Context context, AttributeSet a) { super(context, attributeSet); View.inflate(context, R.layout.main6, this); TextView textView = (TextView) findViewById(R.id.custom_text); TypedArray t = context.obtainStyledAttributes(a, R.styleable.Viewee); int id = t.getResourceId(R.styleable.Viewee_linkedView, 0); if (id != 0) { _id = id; } t.recycle(); } private int _id; public void Foo() { TextView textView = (TextView) findViewById(R.id.custom_text); View view = getRootView().findViewById(_id); textView.setText(((TextView) view).getText().toString()); } } 

当需要在你的活动的其他地方通过其引用ID处理附加视图时调用Foo

信誉完全去那些在这个职位上贡献的人 。 在提交问题之前,我没有看到这个post。

我知道这是一个古老的问题,但我想我会添加另一种方法,因为我想把所有东西封装到我的自定义视图中。

而不是从外部调用,另一种在层次结构中获得更高视图的方式,我已经挂钩了onAttachedToWindow()

 public class MyCustomView extends LinearLayout { private int siblingResourceId; private View siblingView; public MyCustomView(Context context, AttributeSet a) { super(context, attributeSet); View.inflate(context, R.layout.main6, this); TextView textView = (TextView) findViewById(R.id.custom_text); TypedArray t = context.obtainStyledAttributes(a, R.styleable.Viewee); siblingResourceId = t.getResourceId(R.styleable.MyCustomView_siblingResourceId, 0); t.recycle(); } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); if (siblingResourceId != 0) { siblingView = getRootView().findViewById(siblingId); } } } 

onAttachedToWindow被称为相当早,但显然是足够晚的整个视图层次结算。 它至less可以满足我的需求,并且有一点控制,不需要外界的互动来工作;-)

你所描述的android:id被设置为app:linkedView="@+id/tvTest 。但是, @+id/tvTest用来创build一个名为”tvTest“的新的id,你想要做的是使用app:linkedView="@id/tvTest