Нужна помощь в использовании трюк макет Android # 1 - PullRequest
0 голосов
/ 09 февраля 2010

Я прочитал эту запись в блоге об использовании относительного макета для оптимизации макета в ListView: http://android -developers.blogspot.com / 2009/02 / Android-макета фокусы-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>

И я изменил List14.java в APIDemo для использования этого ListItem View. Но когда я запускаю его на эмуляторе, я вижу только значок, текст пустой. И когда я открываю 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"};
}

}

Ответы [ 4 ]

1 голос
/ 08 февраля 2012

Я нашел решение.

Вместо:

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, и он работает.

0 голосов
/ 15 февраля 2010

Похоже, ваш макет немного запутан. С 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 голосов
/ 05 октября 2010

У меня была та же проблема, и все, что мне нужно было сделать, это изменить андроид: layout_toRightOf = "@ id / icon" на android: layout_toRightOf = "@ + id / icon"; обратите внимание на «+» перед «id» и альтом! Работал как шарм.

-Sree

0 голосов
/ 09 февраля 2010

Не могу точно сказать, почему пример блога не запускается (больше?). Он не работает на моем эмуляторе (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"
    />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...