自定义视图未显示

时间:2010-08-02 22:39:41

标签: java android xml layout custom-controls

以下是我希望自定义视图显示的布局的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: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>

以下是自定义视图的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>

这是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);
  }
 }


}

以下是加载包含我的自定义组件的xml的类的代码:

bookPServiceProviderButton = (SearchProviderButton)findViewById(R.id.csp_spb_1);
bookPServiceProviderButton.setOnClickListener(SPBOnClickListener);
bookPServiceProviderButton.setConnector(new bookPConnector());
bookPServiceProviderButton.setVisibility(View.VISIBLE);

编辑:在第一条评论之后,我添加了这段代码:

@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);

}

现在它有宽度和高度,但内部没有任何东西出现!

3 个答案:

答案 0 :(得分:7)

您的自定义布局视图未显示,因为您没有放入任何内容。在您的onFinishInflate中,您有inflatedView = li.inflate(R.layout.provider_view, null);行,但您不会将其添加到您的视图中。您可以通过两种方法将视图添加到自定义布局视图中。

将自定义视图更改为扩展RelativeLayout,将随附的RelativeLayout更改为provider_view.xml中的<merge>,并将findViewId行修复为{{1}因为视图会膨胀到您的布局中。

在布局xml中执行:

this.findViewId(...)

provider_view成为:

<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>

SearchProviderButton:

<?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>

或者您可以通过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(); } . . . onCreate中正确地扩充视图。该调用会将引用的布局扩展为传递的layoutInflater.inflate(R.layout.provider_view, this, true),在这种情况下是您的自定义视图,并将夸大的ViewGroup添加到其中。然后,您可以修复View中的findViewId来电。

答案 1 :(得分:2)

要使wrap_content正常工作,您需要为自定义视图正确实现measurelayout函数。有关这些方法的含义的详细信息,请参阅How Android Draws Views

我的猜测是,您视图的getMeasureWidth()getMeasureHeight()函数始终返回0.

答案 2 :(得分:0)

TC ...除非您运行它,否则它有时不会显示在预览中。