无法在 ListView 中使用自定义项目布局正确显示图像

Posted

技术标签:

【中文标题】无法在 ListView 中使用自定义项目布局正确显示图像【英文标题】:Cannot display image correctly using custom item layout in ListView 【发布时间】:2011-02-11 01:52:51 【问题描述】:

我正在使用 ListView 来显示我的自定义项目布局,其中可能包含一些 TextView 和一个 ImageView。

这是我制作的项目布局(post_item.xml):

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_ android:layout_ android:padding="5dip" > <TextView android:id="@+id/listItem_title" android:layout_ android:layout_ android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_weight="1" /> <FrameLayout android:id="@+id/listItem_frameContent" android:layout_ android:layout_ android:layout_alignParentLeft="true" android:layout_below="@id/userStream_listItem_title" android:layout_weight="1" > </FrameLayout> </RelativeLayout>

我最初并没有将 ImageView 放在 xml 布局中,但我会在需要时以编程方式将其插入到 FrameLayout 中(我还会在需要时将另一个视图放入其中)。所以,会有一些项目中有 ImageView 而没有。

我从互联网(通过 URL)获取图像填充 ImageView,将其解码为 Bitmap,并将其作为 Bitmap 变量保存在一个代表自定义项目布局的类(PostItem 类)中。

当活动第一次显示时它看起来不错,但是当我滚动浏览项目时出现了一个问题,不应该显示任何图像的项目显示来自其他项目的图像,尽管它们没有'没有任何 ImageView(因为我没有插入它)。

我正在使用 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】:

单元格被列表重用,看起来您只是在更改与项目关联的图像时才更改内容框架图像。这意味着当没有图像并且您正在重用一个单元格时,它只会显示在转换视图中传入的任何内容。如果没有图像,则应删除 contentframe 的所有子视图。

也就是说,通过更简洁,您将来可能会得到更好的响应。编写一堆代码并花一些时间来解决问题会使阅读变得更加繁琐,因此会更少人这样做。

【讨论】:

非常感谢您的回答!正如你告诉我的那样,我从框架中删除了所有子视图,现在它工作正常:)。也感谢您的建议,从现在开始我会尽量简洁。你真的拯救了我的一天:D

以上是关于无法在 ListView 中使用自定义项目布局正确显示图像的主要内容,如果未能解决你的问题,请参考以下文章

自定义ListView的RelativeLayout中的Android布局居中

使用 xib 和自动布局的自定义 UITableViewCell 无法在顶部的多个单元格中正确显示

片段中的自定义列表视图。未找到布局

使用自定义布局将宽度和高度设置为 AlertDialog 无法正确应用

无法使用自定义 FocusNode 将焦点移到 LIstView 项目上

使用微调器从自定义列表视图中删除了错误的行