需要帮助使用android布局技巧#1

时间:2010-02-09 06:51:18

标签: android

我已阅读此博客文章,了解如何使用相对布局优化ListView中的布局: http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html

我已将此布局用于我的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文本View的高度为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"};
}

}

4 个答案:

答案 0 :(得分:1)

我找到了解决方案。

而不是:

convertView = mInflater.inflate(R.layout.list_item_icon_text, null);

你必须使用:

convertView = mInflater.inflate(R.layout.list_item_icon_text, parent, false);

我在https://groups.google.com/forum/#!msg/android-developers/E-32MfKeyA4/BtTBF3kfw-YJ找到了这个提示,但它确实有效。

答案 1 :(得分: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"
    />

答案 2 :(得分:0)

看起来你的布局有点混乱。使用RelativeLayouts时,您需要注意不要与alignmentst相矛盾,否则会发生各种意外情况。

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%完美,但它们应该让你走上正确的道路。

答案 3 :(得分:0)

我遇到了同样的问题,而我所要做的就是将android:layout_toRightOf =“@ id / icon”更改为android:layout_toRightOf =“@ + id / icon”;注意“id”和中提琴之前的“+”!工作就像一个魅力。

-Sree