Не удается правильно отобразить изображение с помощью пользовательского макета элемента в ListView - PullRequest
2 голосов
/ 22 апреля 2010

Я использую ListView для отображения моего пользовательского макета элемента, который может содержать некоторые TextViews и ImageView.

Это макет элемента, который я сделал (post_item.xml):


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="60dip"
    android:padding="5dip"
    >

    <TextView android:id="@+id/listItem_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_weight="1"
        />
    <FrameLayout android:id="@+id/listItem_frameContent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/userStream_listItem_title"
        android:layout_weight="1"
        >
    </FrameLayout>

</RelativeLayout>

Я изначально не помещаю ImageView в макет xml, но я вставлю его, когда мне понадобится FrameLayout программно (я также добавлю другие представления в него, когда это необходимо). Итак, будут некоторые элементы, в которых есть ImageView, а какие нет.

Я получаю изображение для заполнения ImageView из Интернета (через URL), декодирую его как растровое изображение и сохраняю его как переменную растрового изображения в классе, представляющем макет пользовательского элемента (класс PostItem).

Когда упражнение в первый раз показывает, что оно выглядит нормально, но когда я прокрутил элементы, то обнаружилась проблема, элементы, которые не должны показывать изображения, показывают изображение из другого элемента, которое должно, хотя они и не отображаются. У меня нет изображения (потому что я его не вставил).

Я использую SDK 1.6 и эмулятор. Я не пробовал это на реальном устройстве, потому что у меня его нет.

Вот мой код для адаптера:


private class PostItemAdapter extends ArrayAdapter<PostItem> {
        private List<PostItem> mPostItems;

        public PostItemAdapter(Context context, int textViewResourceId, List<PostItem> postItems) {
            super(context, textViewResourceId, postItems);

            mPostItems = postItems;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;

            if (view == null) {
                LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
                view = layoutInflater.inflate(R.layout.post_item, null);
            }

            PostItem postItem = mPostItems.get(position);
            if (postItem != null) {
                final FrameLayout contentFrame = (FrameLayout) view.findViewById(R.id.listItem_frameContent);
                final TextView titleTextView = (TextView) view.findViewById(R.id.listItem_title);

                if (titleTextView != null) {
                    titleTextView.setText(postItem.getTitle());
                }
                if (contentFrame != null) {
                    if (postItem.hasImagePreview()) {
                        final ImageView previewImageView = new ImageView(getApplicationContext());
                        previewImageView.setId(LIST_ITEM_IMAGEVIEW_ID);
                        previewImageView.setAdjustViewBounds(true);
                        previewImageView.setMaxHeight(75);
                        previewImageView.setMaxWidth(75);
                        previewImageView.setImageBitmap(postItem.getImagePreview());
                        final RelativeLayout.LayoutParams layoutParams = 
                            new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
                                    RelativeLayout.LayoutParams.WRAP_CONTENT);
                        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                        contentFrame.addView(previewImageView, layoutParams);
                    }
                    if (postItem.hasContent()) {
                        final TextView contentTextView = new TextView(getApplicationContext());
                        contentTextView.setText(postItem.getContent());
                        final RelativeLayout.LayoutParams layoutParams = 
                            new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, 
                                    RelativeLayout.LayoutParams.WRAP_CONTENT);
                        layoutParams.addRule(RelativeLayout.BELOW, LIST_ITEM_IMAGEVIEW_ID);
                        layoutParams.addRule(RelativeLayout.ALIGN_LEFT, LIST_ITEM_IMAGEVIEW_ID);
                        layoutParams.alignWithParent = true;
                        contentFrame.addView(contentTextView, layoutParams);
                    }
                }               
            }

            return view;
        }
    }

А вот код для подготовки предметов:



/* inside a method to prepare the items */
mPostItems = new ArrayList<PostItem>();
for (int i=0; i<total); i++) {
    /* operation to generate titleToDisplay and contentToDisplay */
    /* contentToDisplay might be null */
    mPostItems.add(new PostItem(
            titleToDisplay,
            contentToDisplay,
            generateImagePreview()));

}

/* another method */
private Bitmap generateImagePreview(ActivityObject object) {
        Bitmap imagePreview = null;

        if (/*some condition*/) {
                try {
                    InputStream inStream = (InputStream) (new URL("http://a1.typepad.com/6a010535617444970b0133ecc20b29970b-120si")).getContent();
                    imagePreview = Drawable.createFromStream(inStream, "linkHref");
                }
                catch (MalformedURLException ex) {
                    Log.e("INSIDE generateImagePreview()", ex.getMessage());
                }
                catch (IOException ex) {
                    Log.e("INSIDE generateImagePreview()", ex.getMessage());
                }
                catch (Exception ex) {
                    Log.e("INSIDE generateImagePreview()", ex.getMessage());
                }
        }

        return imagePreview;
}

Это ошибка в эмуляторе или какая-то ошибка в моем коде (возможно, проблема с памятью для растрового изображения)? Пожалуйста, помогите мне, я действительно застрял в этом. Любая помощь или совет будут очень благодарны. Заранее спасибо:)

1 Ответ

1 голос
/ 22 апреля 2010

Ячейки повторно используются в списках, и похоже, что вы изменяете свое изображение только в том случае, если с элементом связано изображение. Это означает, что когда изображение отсутствует и вы повторно используете ячейку, оно просто покажет все, что было передано в представлении преобразования. Если изображения нет, вы должны удалить все дочерние представления содержимого.

Тем не менее, вы, вероятно, получите лучшие ответы в будущем, если будете более краткими. Если вы создадите кучу кода и потратите время на то, чтобы разобраться с этой проблемой, это станет более трудоемким занятием для чтения, и так будет меньше людей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...