Подтвердить что ты не робот

Как передать ссылку на просмотр пользовательского вида 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, findViewById(id) retuns null и NullPointerException.

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

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

4b9b3361

Ответ 1

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

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

В 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 вызывается, когда требуется обработать прикрепленный вид через его ссылочный идентификатор где-то еще в вашей деятельности и т.п.

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

Ответ 2

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

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

Ответ 3

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