Как передать ссылку на просмотр пользовательского вида Android?

Я сделал следующее

1) Создание стиля

<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) Создание необходимого класса

 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> 

Теперь, хотя я получаю ненулевой id в Viewee constractor, findViewById(id) retuns null и NullPointerException .

Что мне не хватает?

Я сделал это, как описано здесь

Solutions Collecting From Web of "Как передать ссылку на просмотр пользовательского вида Android?"

Я нашел ответ!

Проблема заключалась в findViewById(id) и где я его назвал. findViewById ищет только дочерний вид, который не существует на уровне верхней иерархии, как говорит документация . Поэтому мне нужно вызвать что-то вроде getRootView().findViewById(id) но также возвращает null потому что я называл это не корневым.

В Viewee constractor Viewee сам еще не привязан к своему корню, так что вызов вызывает NullPointerException .

Итак, если я вызываю getRootView().findViewById(id) где-то еще после создания, он отлично работает, и оба "@+id/tvTest" и "@id/tvTest" верны. Я протестировал его!

Ответ таков:

 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()); } } 

И Foo вызывается, когда требуется обработать прикрепленное представление через свой ссылочный идентификатор где-то в вашей деятельности и т. П.

Кредит полностью идет к тем парням, внесенным в этот пост . Я не видел этот пост, прежде чем задавать вопрос.

Я знаю, что это старый вопрос, но я думал, что добавлю еще один способ сделать это, поскольку я хотел бы инкапсулировать все в свое собственное представление.

Вместо того, чтобы звонить извне, другой способ получить представление выше в иерархии, я вместо этого подключился к 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 называется довольно ранним, но, по-видимому, достаточно поздно для того, чтобы вся иерархия представлений была решена. Он работает безупречно для моих потребностей, по крайней мере, и немного более контролируется и не нуждается в взаимодействии со стороны, чтобы работать 😉

Ваш описанный android:id установлен в app:linkedView="@+id/tvTest . Однако, @+id/tvTest используется для создания нового идентификатора с именем" tvTest ". То, что вы хотите сделать, это использовать app:linkedView="@id/tvTest .