【问题标题】:Android grid view recycle issueAndroid网格视图回收问题
【发布时间】:2012-07-23 01:18:11
【问题描述】:

当我每次尝试使用回收的网格视图时都会出错,如果 convertView != null 然后我得到一个错误,这是我的源代码。 它会在 text = (TextView) convertView; 处给我一个错误。在 else 语句中。我真的迷路了,我会停止回收视图,但是它会占用大量内存并且滚动不流畅

$ 这里是 imageadapter.java

public View getView(int position, View convertView, ViewGroup parent) {
    RelativeLayout lay;

    ImageView image;
    TextView text;
    if (convertView == null) {
        Log.d("height", "Width = " + width);

        lay = new RelativeLayout(mContext);
        image = new ImageView(mContext);
        text = new TextView(mContext);


        //text.setText("This is a test");
        text.setTextSize(14);
        text.setTextColor(Color.WHITE);
        text.setGravity(Gravity.LEFT | Gravity.TOP);
        text.setPadding(2, 2, 2, 2);
        text.setBackgroundColor(Color.parseColor("#80000000"));
        RelativeLayout.LayoutParams textLayout = new RelativeLayout.LayoutParams(
                (int) Math.round(width / 2.0),
                (int) Math.round(width / 8.3));

        textLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        text.setLayoutParams(textLayout);

        MarginLayoutParams textMarginFix = (ViewGroup.MarginLayoutParams) text
                .getLayoutParams();
        textMarginFix.setMargins(0, 0, 0, (int) Math.round(width / 45.0));
        text.setLayoutParams(textMarginFix);

        image.setLayoutParams(new LayoutParams((int) Math
                .round(width / 2.0), (int) Math.round(width /              2.0)));

        image.setScaleType(ImageView.ScaleType.CENTER_CROP);
        //image.setImageResource(mThumbIds[position]);

        lay.setLayoutParams(new GridView.LayoutParams((int) Math
                .round(width / 2.0), (int) Math.round(width / 2.0)));
        lay.setBackgroundResource(R.drawable.shadowimage);
        lay.setPadding(5, 5, 15, 15);
        //lay.setId(mThumbIds[position]);

        //lay.addView(image);
        //lay.addView(text);

    } 
    else
    {
        text = (TextView) convertView;
        image = (ImageView) convertView;
        lay = (RelativeLayout) convertView;
    }

    image.setImageResource(mThumbIds[position]);
    text.setText("This is a test");

    lay.addView(image);
    lay.addView(text);

     return lay;

}
$here is where i call the imageadapter from another class

    @Override
public Object instantiateItem(View container, int position) {
   View contentView;        
   switch (position) {
    case 0:
        LayoutInflater mInflater = LayoutInflater.from(mContext);
        View contentView = mInflater.inflate(R.layout.image_grid_view,   null);
        Display display = mContext.getWindowManager().getDefaultDisplay();
        final int width = display.getWidth();
        int height = display.getHeight();
        float scale = mContext.getResources().getDisplayMetrics().density;
        GridView gridview = (GridView) contentView.findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(mContext, width, height, scale));
        gridview.setFocusable(true);
        gridview.requestFocus();
        gridview.setOnItemClickListener(itemClickListener);

        ((ViewPager) container).addView(contentView, 0);
        break;
...return contentView

【问题讨论】:

  • 但我不是,这些图像存储在应用程序中
  • 我明白了。我建议根据答案重新编写代码。

标签: android gridview android-viewpager


【解决方案1】:

convertView 是完全代表GridView一个 项的视图。如果是TextView,则为TextView,如果是整个布局,您将收到整个布局,依此类推。

那么你怎么知道和定义什么是“代表一个项目的视图”?很简单,它是你在convertView == nullreturngetView 时创建的任何内容。

您只是收到一个使用过的物品,而您只是对其进行修改以将其更新为适当的内容。所以你应该使用类型转换来得到这个View你收到的你想要的格式。

下面的代码将为您提供您想要的,而无需重做您不需要做的事情(也就是说,您不需要从 convertView 重新添加子 Views,只需一个新视图):

public View getView(int position, View convertView, ViewGroup parent) {
    RelativeLayout lay;
    ImageView image;
    TextView text;

    if (convertView == null) {
        // Setup your 'item view'
        lay = new RelativeLayout(mContext);
        image = new ImageView(mContext);
        text = new TextView(mContext);

        // Do all your customizing stuff (aka size, color, format, padding layout params)

        lay.addView(image, 0);
        lay.addView(text, 1);
    } else {
        lay = (RelativeLayout) convertView;
        image = (ImageView) lay.getChildAt(0);
        text = (TextView) lay.getChildAt(1);
    }

    // Set content for your image and text

    return lay;
}

【讨论】:

  • 好的,现在我明白这里发生了什么,非常感谢。代码运行良好。对我来说不幸的是,gridview 上的滚动条仍然被切碎,不平滑。这一定是其他原因,可能是图片被缩小了,导致加载缓慢
  • 是的,你在 GridViews 中遇到了很多大问题,我已经与这些问题斗争了一段时间。屏幕上一次显示多少项?你的图片尺寸是多少?要将其从现在的状态转变为平滑滚动的内容,需要做很多工作。Here 是一个很好的起点。从那里你将不得不对你真正需要的东西做出一些设计选择(也就是直接将所有图像加载和调整大小到缓存中是不好的,或者会花费太长时间等等)
  • 是的,我加载了大约 20 张图片,每张图片的宽度和高度约为 500 像素。我尝试加载较小的图像并且效果很好。所以我必须找到另一种方法来缩放这些图像。 gridview 不是我的朋友
  • 总共 20 张图片?还是每次每页 20 张图片?因为老实说,GridView 确实可以很好地工作。如果它总共有 20 张图像,一个进度条会启动一个AsyncTask 来调整所有图像的大小并将它们保存到缓存中,而onPostExecute() 从你的布局中删除进度条并添加网格视图,将是一个完美的解决方案。跨度>
  • 每个 gridview 20 个(稍后我将有一个活动,其中包含来自服务器的 50 多张照片,而不是用于此活动)。你搞定了,我现在只是在查看有关缓存图像的文档。我认为这就是我的解决方案。
【解决方案2】:

[添加]

另外,你有代码

image.setImageResource(mThumbIds[position]);
text.setText("This is a test");

lay.addView(image);
lay.addView(text);

return lay;

在 if 和 else 之外,这意味着每次请求单元格视图时,您都在尝试添加子视图。您实际上只需要在例程的 if 部分中添加视图。

[原创] 很可能 convertView 是您的父级,所有其他视图都是它的子级。在你的 else 子句中,你所做的只是将每个设置为相同的东西。 convertView 怎么可能同时是三个完全不同的东西。

很可能需要:

text = (TextView) convertView.SomeTextViewSubToConvertView;
image = (ImageView) convertView.SomeImageViewSubToConvertView;
lay = (RelativeLayout) convertView.SomeRelativeLayoutSubToConvertView;

【讨论】:

  • 感谢回复我会试试这个
  • @user1486574 - 我已添加到我的答案中!
  • 再次感谢,我仍然遇到问题,我尝试为各个视图分配 ID,但在同一位置仍然存在问题。我正在尝试从 google developer.android.com/guide/topics/ui/layout/gridview.html 遵循这个示例
  • 我试过这个 image.setId(2);对于每个视图,然后在 else 语句中它尝试了这个 image = (ImageView) convertView.findViewById(2);
  • 好的,我明白了!谢谢你,因为你说的两个原因,首先需要 setId 到视图,然后通过他们的 id 找到。然后我将视图添加到父视图中,即使它们已经存在。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多