#java #android #android-custom-view #layout-inflater
#java #Android #android-custom-view #макет-надуватель
Вопрос:
Я работаю над приложением для Android. У меня есть пользовательский вид и макет следующим образом:
<com.hello.view.card.inner.SimpleCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@ id/card_simple_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@ id/simple_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</com.hello.view.card.inner.SimpleCardView>
И это класс Java:
public class SimpleCardView extends LinearLayout {
protected SimpleCard card = null;
protected TextView textView;
public SimpleCardView(Context context) {
super(context);
init(context);
}
public SimpleCardView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SimpleCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
protected void init(Context context) {
textView = (TextView)findViewById(R.id.simple_label);
}
public void setCard(SimpleCard card) {
this.card = card;
textView.setText(card.getMessage());
}
}
И вот как я раздуваю представление (я попробовал оба следующих вызова):
SimpleCardView view = (SimpleCardView)inflater.inflate(R.layout.card_simple, null);
//SimpleCardView view = (SimpleCardView)inflater.inflate(R.layout.card_simple, parent);
view.setCard(card);
Проблема, с которой я сталкиваюсь, заключается в том, что при вызове view.setCard(card) я вижу, что TextView имеет значение null, хотя я ожидаю, что оно будет установлено в методе init(..) . Кто-нибудь может сказать мне, что он неправильно настроен? Заранее спасибо.
Комментарии:
1. Покажите код для действия, пожалуйста
Ответ №1:
Спасибо вам за ваши ответы. Оказывается, init(context) не должен вызываться в конструкторе. Правильное место для его вызова находится в onFinishInflate(). Следующее изменение помогло исправить это:
public class SimpleCardView extends LinearLayout {
protected SimpleCard card = null;
protected TextView textView;
public SimpleCardView(Context context) {
super(context);
}
public SimpleCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SimpleCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
init(getContext());
}
protected void init(Context context) {
textView = (TextView)findViewById(R.id.simple_label);
}
public void setCard(SimpleCard card) {
this.card = card;
textView.setText(card.getMessage());
}
}
Комментарии:
1. Это было именно так для меня. Должно быть выше в результатах Google.
Ответ №2:
Вместо использования корневого элемента
com.hello.view.card.inner.SimpleCardView
попробуйте использовать
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@ id/simple_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>
затем в вашем методе инициализации
LayoutInflater.from(context).inflate(R.layout.card_simple, this);
setOrientation(LinearLayout.VERTICAL);
textView = (TextView)findViewById(R.id.simple_label);
Когда вы используете представление в других макетах, именно там вы захотите поместить
<com.hello.view.card.inner.SimpleCardView />
и любые свойства, которые ему нужны, его идентификатор, его ширина / высота и т.д.