ListView使用多个子项

时间:2014-11-16 03:21:19

标签: android android-listview

你好,这次又一个关于List的问题..一个ListView ......

我正在使用BaseAdapter来扩展一个包含RelativeLayout(Parent)和4个ImagesViews的布局,它们是alignBaseline(水平)到第一个ImageView。(它并不重要)它们都有相同的源,是一个imageArray。问题是getView-Method仅针对创建/重用/滚动到视图中的每个ListItem触发..但不针对ListItem(我的ImageViews)的子节点触发。正如您已经预料到的那样:“如果getView仅针对每个listItem触发,那么他如何将图像设置为来自相同源的ImageViews,而不是针对每个listitem的子节点?”。

我坚持到这里:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ImageView img1;
    ImageView img2;
    ImageView img3;
    ImageView img4;
    TextView tv1;
    TextView tv2;
    TextView tv3;
    TextView tv4;
    TextView tv_abc;

    if(convertView == null) {
        convertView = inflater.inflate(R.layout.customadapter_view_layout, null);
        img1 = (ImageView) convertView.findViewById(R.id.img_normal_portrait_1);
        img2 = (ImageView) convertView.findViewById(R.id.img_normal_portrait_2);
        img3 = (ImageView) convertView.findViewById(R.id.img_normal_portrait_3);
        img4 = (ImageView) convertView.findViewById(R.id.img_normal_portrait_4);
        tv1 =(TextView) convertView.findViewById(R.id.tv_normal_portrait_1);
        tv2 =(TextView) convertView.findViewById(R.id.tv_normal_portrait_2);
        tv3 =(TextView) convertView.findViewById(R.id.tv_normal_portrait_3);
        tv4 =(TextView) convertView.findViewById(R.id.tv_normal_portrait_4);
        tv_abc = (TextView) convertView.findViewById(R.id.tv_normal_portrait_abc);
        convertView.setTag(new Holder(img1,img2,img3,img4,tv1, tv2, tv3, tv4,tv_abc));
    } else {
        Holder holder = (Holder) convertView.getTag();
        img1 = holder.img1;
        img2 = holder.img2;
        img3 = holder.img3;
        img4 = holder.img4;
        tv1 = holder.tv1;
        tv2 = holder.tv2;
        tv3 = holder.tv3;
        tv4 = holder.tv4;
        tv_abc = holder.tv_abc;

    }
        img1.setImageDrawable(scaledImage[position]);
        img2.setImageDrawable(scaledImage[position+1]);
        img3.setImageDrawable(scaledImage[position+2]);
        img4.setImageDrawable(scaledImage[position+3]);
        tv1.setText(labels[position]);
        tv2.setText(labels[position+1]);
        tv3.setText(labels[position+2]);
        tv4.setText(labels[position+3]);


    return convertView;
}

}

(请忽略textViews) 正如您已经提到的,这非常缓慢,甚至无法工作。为什么?正如我之前提到的,Position(来自getView)计算每个ListItem,但不是每个Listitem的Child。此外,当我尝试这个时,我发现Position(来自getView)只有Counts ListItems。后来我想,我怎么能认为getView知道(或者更好想知道)我的布局中的Childs?甚至更多我讨厌像上面那样的解决方案......它们很慢,很复杂,常常导致IndexOutOfBoundException。

所以,请有人有一个更好的解决方案或完全不同的方式来完成这项工作。(其他适配器,无论如何)。我感谢每一个帮助。谢谢

1 个答案:

答案 0 :(得分:1)

<强> POJO

POJO实际上是一个java编程术语,不一定只与Android相关联。它代表Plain Old Java Object,许多其他语言都有自己的等效首字母缩略词。 Wikipedia对此有一个很好的写作。这个想法需要一个非常简单的类来传递一些数据。您正在使用的Holder是POJO的示例。

<强>计数

正如您所提到的,部分问题在理解BaseAdapter的工作原理方面存在轻微错误。我假设你已经定义了以下内容:

@Override
public int getCount() {
    return scaledImage.length();
}

实际上你需要的东西更像是:

@Override
public int getCount() {
    //This assumes you'll ensure the array will always be equally divisible by 4.
    //If not, you'll need to add some empty elements at the end to make it so.
    return scaledImage.length() / 4;
}

适配器只知道它包含的行数,而不知道行总共使用了多少数据。接收IndexOutOfBoundsExpections不是使用代码中显示的scaledImage的结果。这是其他地方引起的问题。使用像这样的数组是完全正常的...只要你的getCount()方法返回正确的值。

应用POJO

正如Chitrang建议的那样,您可以将scaledImage数组转换为POJO。例如,你有类似的东西:

private class ScaledImageRow {
    //You could just as easily use an array of 4 elements instead
    Drawable image1;
    Drawable image2;
    Drawable image3;
    Drawable image4;
}

然后,当您构建自定义适配器时,您需要转换:

Drawable[] scaledImage;

进入:

ScaledImageRow[] scaledImageRow;

通过执行此操作,您可以使用scaledImageRow

返回计数getView()的长度,并在scaledImageRow[position]中获取正确的图像行

现在将您的数据转换为这样的POJO并不是您真正的表现。更重要的是提高代码的可读性。它还有助于更好地概念化代码的内容。

<强>性能

您提到了getView()的一些非常慢的表现,如答案所示。您的阵列方法绝对不是它的原因。我会说这是图像的设置。我猜你已经把图像加载到内存中了。那么也许图像仍然相当大,ImageView有一些XML定义的缩放属性?否则,我会说代码中的其他地方会导致减速。