Ответ 1
У меня была одна и та же проблема, и проблема заключалась в том, что я использовал неправильный идентификатор... и похоже, что вы тоже.
Вы должны ссылаться на
R.layout.custom_display_view
-не -
R.id.custom_display_view
нормально
то, что я пытаюсь сделать, - это вставить пользовательский вид в макет по умолчанию main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.lam.customview.CustomDisplayView
android:id="@+id/custom_display_view1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/prev"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="50"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/prev" />
</LinearLayout>
</LinearLayout>
как вы можете видеть, класс называется com.lam.customview.CustomDisplayView с идентификатором custom_display_view1.
теперь в классе com.lam.customview.CustomDisplayView, я хочу использовать другой макет под названием custom_display_view.xml, потому что я не хочу программно создавать элементы управления/виджеты.
custom_display_view.xml - это просто кнопка и изображение, содержание которого я хочу изменить на основе определенных условий:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/display_text_view1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView
android:id="@+id/display_image_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
</LinearLayout>
Я попытался сделать:
1)
public CustomDisplayView(Context context, AttributeSet attrs) {
super(context, attrs);
try
{
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
View.inflate(context, R.layout.custom_display_view, null);
...
но получил эту ошибку ", 03-08 20: 33: 15.711: ERROR/onCreate (10879): двоичная строка XML файла # 8: ошибка раздувания класса java.lang.reflect.Constructor".
2)
public CustomDisplayView(Context context, AttributeSet attrs) {
super(context, attrs);
try
{
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
View.inflate(context, R.id.custom_display_view1, null);
...
но получил эту ошибку ", 03-08 20: 28: 47.401: ERROR/CustomDisplayView (10806): Идентификатор ресурса # 0x7f050002 type # 0x12 недействителен"
также, если я делаю это так, как предложил кто-то, мне не ясно, как custom_display_view.xml связан с классом пользовательского вида.
спасибо.
У меня была одна и та же проблема, и проблема заключалась в том, что я использовал неправильный идентификатор... и похоже, что вы тоже.
Вы должны ссылаться на
R.layout.custom_display_view
-не -
R.id.custom_display_view
Вы можете раздуть cutom_display_view в свой собственный класс:
public CustomDisplayView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(inflater != null){
inflater.inflate(R.layout.custom_display_view, this);
}
}
Это сообщение в блоге помогло мне понять, что делать безгранично http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/. В случае исчезновения сообщения в блоге, вот некоторые части кода:
public class Card extends RelativeLayout {
public Card(Context context) {
super(context);
init();
}
public Card(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Card(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
inflate(getContext(), R.layout.card, this);
}
}
с этим расположением:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/card_padding"
android:background="@color/card_background">
<ImageView
... />
<TextView
... />
</merge>
Элемент управления включен как:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<com.trickyandroid.customview.app.view.Card
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/card_background"
android:padding="@dimen/card_padding"/>
</FrameLayout>
Где com.trickyandroid.customview.app.view - это пространство имен класса. Единственное, что было для меня новым, это тег "merge", который заканчивается тем же самым node, что и тег Card в содержащем документе.
Когда вы раздуваете свой макет, вы должны передать ссылку на экземпляр представления, чтобы идентифицировать его как корень. Поэтому вместо вызова:
View.inflate(context, R.layout.custom_display_view, null);
Вызов:
View.inflate(context, R.layout.custom_display_view, this);
Смотрите: Документы
Попробуйте использовать
context.getLayoutInflater().inflate( R.id.custom_display_view1, null );
Строка № 8 - это ваш пользовательский вид в первом макете. Вы пытаетесь загрузить неправильный макет, поэтому он пытается загрузить себя рекурсивно? (Я просто сделал то же самое)
Также у вас есть:
R.layout.custom_display_view
против.
R.id.custom_display_view1
с 1 на конце... какой из них?