custom view with layout
Solution 1
I had the exact same issue, and the problem was that I was using the wrong ID... and it look's like you are too.
You should be referencing
R.layout.custom_display_view
-not-
R.id.custom_display_view
Solution 2
This blog post helped me understand what to do immensely http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/. In case the blog post disappears, here are some parts of the code:
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);
}
}
with this layout:
<?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>
The control is included like:
<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>
Where com.trickyandroid.customview.app.view is the namespace of class card. One thing that was new to me was the "merge" tag, which ends up being the same node as the Card tag in the containing doc.
Solution 3
You can inflate the cutom_display_view into your custom class by:
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);
}
}
Solution 4
When you inflate your layout, you should pass in a reference to the view instance to identify it as the root. So instead of calling:
View.inflate(context, R.layout.custom_display_view, null);
Call:
View.inflate(context, R.layout.custom_display_view, this);
See: The docs
user270811
Updated on September 23, 2020Comments
-
user270811 over 3 years
ok,
what i am trying to do is to embed a custom view in the default layout 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>
as you can see the class is called com.lam.customview.CustomDisplayView, with the id of custom_display_view1.
now in the com.lam.customview.CustomDisplayView class, i want to use another layout called custom_display_view.xml because i don't want to programmatically create controls/widgets.
custom_display_view.xml is just a button and an image, the content of which i want to change based on certain conditions:
<?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>
i tried to do:
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);
...
but got this error, "03-08 20:33:15.711: ERROR/onCreate(10879): Binary XML file line #8: Error inflating class 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);
...
but got this error, "03-08 20:28:47.401: ERROR/CustomDisplayView(10806): Resource ID #0x7f050002 type #0x12 is not valid "
also, if i do it this way, as someone has suggested, it's not clear to me how the custom_display_view.xml is associated with the custom view class.
thanks.