views:

165

answers:

2

Here is the XML for the layout in which I want my custom view to appear.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/widget273"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:rs="http://schemas.android.com/apk/res/com.bookcessed.booksearch"
>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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!

A: 

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.

Mayra
+1  A: 

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 Views to it. Then you can fix up the findViewId calls in your onFinishInflate.

Qberticus
I think I've tried both ways of doing it, but probably not doing it correctly. I can't get it.
Aymon Fournier
I've updated the answer to include examples of the necessary changes for the first method.
Qberticus
THANK 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
Do 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
Aymon Fournier
Try 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.
Qberticus
Thanks again! works perfectly
Aymon Fournier