2010-02-09 69 views
0

我讀過關於使用相對佈局的ListView優化佈局此博客條目: http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html需要幫助使用Android的佈局技巧#1

我已經使用這個佈局我的ListView項(具備稍作修改例如):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" 

    android:padding="6dip"> 

    <ImageView 
     android:id="@+id/icon" 

     android:layout_width="wrap_content" 
     android:layout_height="fill_parent" 

     android:layout_alignParentTop="true" 
     android:layout_alignParentBottom="true" 
     android:layout_marginRight="6dip" 

     android:src="@drawable/icon" /> 

    <TextView 
     android:id="@+id/secondLine" 

     android:layout_width="fill_parent" 
     android:layout_height="26dip" 

     android:layout_toRightOf="@id/icon" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentRight="true" 

     android:singleLine="true" 
     android:ellipsize="marquee"/> 

    <TextView 
     android:id="@+id/text" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 

     android:layout_toRightOf="@id/icon" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" 
     android:layout_above="@id/secondLine" 
     android:layout_alignWithParentIfMissing="true" 

     android:gravity="center_vertical" /> 

</RelativeLayout> 

而且我修改了APIDemo中的List14.java以使用該ListItem視圖。但是當我在仿真器上運行它時,我只看到圖標,文本是空白的。而當我打開HierarchyViewer文本視圖的高度爲0.有人可以告訴我爲什麼?

public class TestListView extends ListActivity { 

    private static class EfficientAdapter extends BaseAdapter { 
      private LayoutInflater mInflater; 
      private Bitmap mIcon1; 
      private Bitmap mIcon2; 

      public EfficientAdapter(Context context) { 
       // Cache the LayoutInflate to avoid asking for a new one each time. 
       mInflater = LayoutInflater.from(context); 

       // Icons bound to the rows. 
       mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1); 
       mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2); 
      } 

      /** 
      * The number of items in the list is determined by the number of speeches 
      * in our array. 
      * 
      * @see android.widget.ListAdapter#getCount() 
      */ 
      public int getCount() { 
       return DATA.length; 
      } 

      /** 
      * Since the data comes from an array, just returning the index is 
      * sufficent to get at the data. If we were using a more complex data 
      * structure, we would return whatever object represents one row in the 
      * list. 
      * 
      * @see android.widget.ListAdapter#getItem(int) 
      */ 
      public Object getItem(int position) { 
       return position; 
      } 

      /** 
      * Use the array index as a unique id. 
      * 
      * @see android.widget.ListAdapter#getItemId(int) 
      */ 
      public long getItemId(int position) { 
       return position; 
      } 

      /** 
      * Make a view to hold each row. 
      * 
      * @see android.widget.ListAdapter#getView(int, android.view.View, 
      *  android.view.ViewGroup) 
      */ 
      public View getView(int position, View convertView, ViewGroup parent) { 
       // A ViewHolder keeps references to children views to avoid unneccessary calls 
       // to findViewById() on each row. 
       ViewHolder holder; 

       // When convertView is not null, we can reuse it directly, there is no need 
       // to reinflate it. We only inflate a new View when the convertView supplied 
       // by ListView is null. 
       if (convertView == null) { 
        convertView = mInflater.inflate(R.layout.list_item_icon_text, null); 

        // Creates a ViewHolder and store references to the two children views 
        // we want to bind data to. 
        holder = new ViewHolder(); 
        holder.text = (TextView) convertView.findViewById(R.id.text); 
        holder.icon = (ImageView) convertView.findViewById(R.id.icon); 

        convertView.setTag(holder); 
       } else { 
        // Get the ViewHolder back to get fast access to the TextView 
        // and the ImageView. 
        holder = (ViewHolder) convertView.getTag(); 
       } 

       // Bind the data efficiently with the holder. 
       holder.text.setText(DATA[position]); 
       holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); 

       return convertView; 
      } 

      static class ViewHolder { 
       TextView text; 
       ImageView icon; 
      } 
     } 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setListAdapter(new EfficientAdapter(this)); 
     } 

     private static final String[] DATA = { 
       "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", 

       "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"}; 
} 

} 

回答

0

無法準確地告訴你爲什麼博客的例子不會運行(不再?)。它不能在我的模擬器上運行(1.5 & 1.6)。我終於通過切換兩個TextView並擺脫layout_above來運行它。像這樣:

<TextView 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 

    android:id="@+id/text" 
    android:layout_alignWithParentIfMissing="true" 
    android:layout_toRightOf="@id/icon" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentTop="true" 
    /> 

<TextView 
    android:id="@+id/secondLine" 

    android:layout_width="fill_parent" 
    android:layout_height="26dip" 
    android:layout_below="@id/text" 

    android:layout_toRightOf="@id/icon" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentRight="true" 
    /> 
+0

謝謝。我從來沒有想過這樣做。 – hap497 2010-02-09 18:21:45

+0

在上面的例子中,它表示「android:layout_alignParentRight =」true「,但是爲什麼當我在模擬器上運行時,TextView是與父對象左對齊的? – hap497 2010-02-09 19:21:46

+0

不知道我是否正確理解了你。 這裏是我的想法:alignParentRight這裏的意思是「將TextView的右邊框與父元素的右邊框對齊」,即LinearLayout。當然,這基本上意味着將TextView放置在LinearLayout的右邊界的左側。 TextView的文本內容與左側對齊,因爲如果不在TextView上設置android:gravity,那麼這是默認值。 這有幫助嗎? – rflexor 2010-02-10 12:21:45

0

看起來你的佈局有點混亂。有了RelativeLayouts,你需要小心,不要與對齊相抵觸,否則會發生各種意想不到的事情。

android:layout_alignParentTop="true" 
    android:layout_alignParentBottom="true" 

上面是一個例子。

我還沒有試過這個,你沒有解釋你想用你的佈局實現什麼,但嘗試以下。

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="?android:attr/listPreferredItemHeight" 
android:padding="6dip" 
> 

<ImageView 
    android:id="@+id/icon" 
    android:src="@drawable/icon" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_marginRight="6dip" 
    /> 

<TextView 
    android:id="@+id/text" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toRightOf="@id/icon" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentTop="true" 
    /> 

<TextView 
    android:id="@+id/secondLine" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toRightOf="@id/icon" 
    android:layout_below="@id/text" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentRight="true" 
    android:singleLine="true" 
    android:ellipsize="marquee" 
    /> 

儘量保持你的佈局定義邏輯順序,這將有助於調試後。

也看看你的getView方法,它可以簡單得多。

public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     LayoutInflater vi = 

(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    v = vi.inflate(R.layout.list_item_icon_text, null); 

    TextView text = (TextView) convertView.findViewById(R.id.text); 
    ImageView icon = (ImageView) convertView.findViewById(R.id.icon); 

    icon.setText(DATA[position]); 
    icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); 

    return v; 
} 

這些例子可能不是100%完美,但他們應該讓你沿着正確的道路。

0

我有同樣的問題,我只需要將android:layout_toRightOf =「@ id/icon」更改爲android:layout_toRightOf =「@ + id/icon」;注意「id」和中提琴之前的「+」!像魅力一樣工作。

-Sree