Custom View not appearing
Solution 1
Your custom layout view is not appearing because you're not putting anything into it. In your onFinishInflate
you have the line inflatedView = li.inflate(R.layout.provider_view, null);
But you don't add that to your view. You have two options to add the views to your custom layout view.
Change your custom view to extend RelativeLayout
, change the enclosing RelativeLayout
to <merge>
in your provider_view.xml, and fix your findViewId
lines in to this.findViewId(...)
since the views will be inflated into your layout.
In your layout xml do:
<com.bookcessed.booksearch.SearchProviderButton
android:id="@+id/csp_spb_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/csp_tv_title"
rs:providerName="BOOKP">
<!-- include this so it's added to your custom layout view -->
<include layout="@layout/provider_view" />
</com.bookcessed.booksearch.SearchProviderButton>
provider_view becomes:
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:rs="http://schemas.android.com/apk/res/com.bookcessed.booksearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:id="@+id/pv_rl_strings"
.
.
.
</merge>
SearchProviderButton:
public class SearchProviderButton extends RelativeLayout{
.
.
.
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//the <include> in the layout file has added these views to this
//so search this for the views
ImageView logo = this.findViewById(R.id.pv_logo);
logo.setImageResource(connector.getLogoDrawableID());
TextView searchTV = (TextView)this.findViewById(R.id.pv_tv_search);
TextView andTV = (TextView)this.findViewById(R.id.pv_tv_and);
if(!connector.isSearchSupported()){
andTV.setText("");
searchTV.setVisibility(GONE);
}
setgenreIcons();
}
.
.
.
Or you could properly inflate the view in onCreate
by layoutInflater.inflate(R.layout.provider_view, this, true)
. That call will inflate the referenced layout into the passed ViewGroup
, in this case your custom view, and add the inflated View
s to it. Then you can fix up the findViewId
calls in your onFinishInflate
.
Solution 2
TC... Sometimes it wont show in the preview unless you run it.
Solution 3
For wrap_content to work, you need to properly implement the measure
and layout
functions for your custom View. See How Android Draws Views for details on what these methods mean.
My guess would be that getMeasureWidth()
and getMeasureHeight()
functions for your view are always returning 0.
Related videos on Youtube
Comments
-
Aymon Fournier about 2 years
Here is the XML for the layout in which I want my custom view to appear.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rs="http://schemas.android.com/apk/res/com.bookcessed.booksearch" android:id="@+id/widget273" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/csp_tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Choose Your Source" android:textSize="40sp" android:textColor="#ffc83200" android:gravity="center" android:paddingTop="15dip" android:paddingBottom="75dip" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <com.bookcessed.booksearch.SearchProviderButton android:id="@+id/csp_spb_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/csp_tv_title" rs:providerName="BOOKP" /> </RelativeLayout>
Here is the custom view's XML:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rs="http://schemas.android.com/apk/res/com.bookcessed.booksearch" android:layout_width="fill_parent" android:layout_height="wrap_content" > <RelativeLayout android:id="@+id/pv_rl_strings" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_alignParentTop="true" > <TextView android:id="@+id/pv_tv_search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Search" android:layout_toRightOf="@+id/pv_tv_and" android:textSize="18sp" android:textColor="#ff11ab37" android:layout_alignParentTop="true" /> <TextView android:id="@+id/pv_tv_and" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" and " android:textSize="18sp" android:paddingLeft="6dip" android:paddingRight="6dip" android:textColor="#ff000000" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/pv_tv_browse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Browse" android:textSize="18sp" android:textColor="#ff0077bb" android:layout_alignParentTop="true" android:layout_toLeftOf="@+id/pv_tv_and" /> <ImageView android:id="@+id/pv_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/pv_tv_search" android:layout_centerInParent="true" android:layout_alignTop="@+id/pv_tv_and" android:src="@drawable/bookp_logo" /> </RelativeLayout> <RelativeLayout android:id="@+id/pv_rl_genres" android:layout_width="wrap_content" android:layout_below="@+id/pv_rl_strings" android:layout_height="wrap_content" android:layout_centerHorizontal="true" > <ImageView android:id="@+id/pv_genre1" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" /> <ImageView android:id="@+id/pv_genre2" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre1" /> <ImageView android:id="@+id/pv_genre3" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre2" /> <ImageView android:id="@+id/pv_genre4" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre3" /> <ImageView android:id="@+id/pv_genre5" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre4" /> <ImageView android:id="@+id/pv_genre6" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre5" /> <ImageView android:id="@+id/pv_genre7" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre6" /> <ImageView android:id="@+id/pv_genre8" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre7" /> <ImageView android:id="@+id/pv_genre9" android:layout_width="30dip" android:layout_height="30dip" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/pv_genre8" /> </RelativeLayout> </RelativeLayout>
Here is the class SearchProviderButton:
public class SearchProviderButton extends LinearLayout { private Connector connector; private Context context; private View inflatedView; public SearchProviderButton(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.SearchProviderButton); connector = SearchProvider.valueOf(a.getString(R.styleable.SearchProviderButton_providerName)).getConnector(); this.context = context; setFocusable(true); setBackgroundColor(Color.WHITE); setVisibility(VISIBLE); //setOnClickListener(listenerAdapter); setClickable(true); } @Override protected void onFinishInflate() { super.onFinishInflate(); LayoutInflater li = LayoutInflater.from(context); inflatedView = li.inflate(R.layout.provider_view, null); ImageView logo = (ImageView)inflatedView.findViewById(R.id.pv_logo); logo.setImageResource(connector.getLogoDrawableID()); TextView searchTV = (TextView)inflatedView.findViewById(R.id.pv_tv_search); TextView andTV = (TextView)inflatedView.findViewById(R.id.pv_tv_and); if(!connector.isSearchSupported()){ andTV.setText(""); searchTV.setVisibility(GONE); } setgenreIcons(); } public Connector getConnector(){ return connector; } public void setConnector(Connector connector){ this.connector = connector; } private void setgenreIcons(){ int[] genreIconDrawables = {R.id.pv_genre1,R.id.pv_genre2, R.id.pv_genre3, R.id.pv_genre4, R.id.pv_genre5, R.id.pv_genre6, R.id.pv_genre7, R.id.pv_genre8, R.id.pv_genre9}; ArrayList<Genre> availgenre = connector.getAvailablegenres(); availgenre.remove(Genre.ALL); int counter = 0; for(int genreIVid : genreIconDrawables){ ImageView curgenreImageView = (ImageView)inflatedView.findViewById(genreIVid); if(counter < availgenre.size() - 1){ curgenreImageView.setImageResource(availgenre.get(counter).getDrawable()); } else { curgenreImageView.setVisibility(GONE); } counter++; } } protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { if (gainFocus == true){ this.setBackgroundColor(Color.rgb(255, 165, 0)); } else { this.setBackgroundColor(Color.WHITE); } } }
Here is the code for the class loading the xml that contains my custom component:
bookPServiceProviderButton = (SearchProviderButton)findViewById(R.id.csp_spb_1); bookPServiceProviderButton.setOnClickListener(SPBOnClickListener); bookPServiceProviderButton.setConnector(new bookPConnector()); bookPServiceProviderButton.setVisibility(View.VISIBLE);
EDIT: After the first comment, I added this code:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpec = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int heightSpec = MeasureSpec.getMode(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); }
Now it has a width and a height, but nothing is showing up inside of it!
-
Aymon Fournier almost 14 yearsI think I've tried both ways of doing it, but probably not doing it correctly. I can't get it.
-
Jonathan O'Neil almost 14 yearsI've updated the answer to include examples of the necessary changes for the first method.
-
Aymon Fournier almost 14 yearsTHANK YOU! I hope that someone might help you as much as you just helped me! Thank you soooo much. I would never have been able to put 2 and 2 together myself. Thanks again!
-
Aymon Fournier almost 14 yearsDo you know why my custom view is extremely tall? could have something to do with onMeasure? I tried to fit one more underneath the first, but its offscreen
-
Jonathan O'Neil almost 14 yearsTry removing your onMeasure that you added since it wasn't the actual problem. I haven't actually tried running your layout so I'm not sure how tall it should be. It looks like it should not be too much more than 30px.
-
arthur0304 over 4 yearsexactly!! I had a correct xml structure, but nothing showed up until the first run. Must be an Android Studio bug