1

我遇到了一个问题,即我的 ListView 的自定义 ArrayAdapter 没有更新 Gallery 小部件及其内容,它有一个 Gallery 小部件和两个 TextView 作为子项。

为了设置应用程序的背景,我正在创建一个应用程序,它允许两个或多个设备通过蓝牙相互连接,并将每个设备的照片流式传输到其连接的设备。现在,只是为了实现的缘故,每个设备都表示在一个可滚动的列表视图中,其中包含画廊小部件(所有设备的图像都可以水平滚动)和它下方的两个 TextView 小部件,用于识别发送者。

ListView 的布局如下:

<LinearLayout ...>
    <Gallery .../>
    <LinearLayout>
        <TextView .../>
        <TextView .../>
    </LinearLayout>
</LinearLayout>

图像发送和接收不是问题,我已经反复测试过它们。

问题似乎在于自定义 ArrayAdapter 的notifyDataSetChanged()方法没有按预期运行。当我在 ListView (在我的 main Activity)中创建一个新的 ImageHolderClass 对象时,我这样做如下mImageHolderAdapter.add(new ImageHolderClass(this, "Me", mBtAdapter.getAddress(), mLocalImageList));:知道add()适配器的方法应该是调用notifyDataSetChanged(),它对创建和添加的第一个对象按预期工作。但是当我添加另一个对象或向对象添加任何新图像时imageList,它们会创建存储在第一个对象中的图像的精确副本。

现在,有趣的是每个中的两个 TextView 变量都ImageHolderClass设法更新了,但 Gallery 中的图像似乎保持完全相同。

我尝试绕过(with a ) 方法add()中的方法,然后仅在添加其他图像时强制 a ,这似乎显示其他图像(但不显示所有图像),但不是仅当设备并且没有连接其他设备。ImageHolderAdapter()addItem()notifyDataSetChanged()

我的自定义 ArrayAdapter 如下:

public class ImageHolderAdapter extends ArrayAdapter<ImageHolderClass>{
private ArrayList<ImageHolderClass> objects;

public ImageHolderAdapter(Context context, int layoutResourceId, ArrayList<ImageHolderClass> objects) {
    super(context, layoutResourceId, objects);
    this.objects = objects;
}

public static class ViewHolder {
    public Gallery gallery;
    public TextView deviceName;
    public TextView deviceAddress;
    public ArrayList imageList;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Assign the view we are converting to a local variable
    View v = convertView;
    ViewHolder holder;

    // first check to see if the view is null. If it is, then we have to inflate it.
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.imageholder, null);
        holder = new ViewHolder();
        holder.gallery = (Gallery)v.findViewById(R.id.gallery);
        holder.gallery.setAdapter(new ImageAdapter(getContext(), objects.get(position).imageList));
        holder.deviceName = (TextView)v.findViewById(R.id.deviceName);
        holder.deviceAddress = (TextView)v.findViewById(R.id.deviceAddress);
        v.setTag(holder);
    } else {
        holder = (ViewHolder)v.getTag();
    }

    final ImageHolderClass imageHolderClass = objects.get(position);

    if (imageHolderClass != null) {
        holder.gallery = imageHolderClass.getGallery();
        holder.deviceName.setText(imageHolderClass.getDeviceName());
        holder.deviceAddress.setText(imageHolderClass.getDeviceAddress());
    }

    return v;
}

public class ImageAdapter extends BaseAdapter {
    int mGalleryItemBackground;
    private Context mContext;
    ArrayList list;

    public ImageAdapter(Context c, ArrayList list) {
        mContext = c;
        this.list = list;
        TypedArray attr = mContext.obtainStyledAttributes(R.styleable.TestbedActivity);
        mGalleryItemBackground = attr.getResourceId(R.styleable.TestbedActivity_android_galleryItemBackground, 0);
        attr.recycle();
    }

    public int getCount() {
        return list.size();
    }

    public Object getItem(int position) {
        return list.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(mContext);

        imageView.setImageBitmap((Bitmap)list.get(position));
        imageView.setLayoutParams(new Gallery.LayoutParams(180, 150));
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        imageView.setBackgroundResource(mGalleryItemBackground);

         return imageView;
    }
}

}

和上面使用的ImageHolderClass如下:

public class ImageHolderClass {
public Gallery gallery;
public String deviceName;
public String deviceAddress;
public ArrayList imageList;

public ImageHolderClass() {
    super();
}

public ImageHolderClass(Context c, String deviceName, String deviceAddress, ArrayList imageList) {
    super();
    this.gallery = new Gallery(c);
    this.deviceName = deviceName;
    this.deviceAddress = deviceAddress;
    this.imageList = imageList;
}

public Gallery getGallery() {
    return gallery;
}

public void setGallery(Gallery gallery) {
    this.gallery = gallery;
}

public String getDeviceName() {
    return deviceName;
}

public void setDeviceName(String deviceName) {
    this.deviceName = deviceName;
}

public String getDeviceAddress() {
    return deviceAddress;
}

public void setDeviceAddress(String deviceAddress) {
    this.deviceAddress = deviceAddress;
}

public void setImageList(ArrayList list) {
    this.imageList = list;
}

public ArrayList getImageList() {
    return imageList;
}

}

生成的图像(两个 ListView 对象具有相同的图像(但不应该))可以在下图中看到:http: //i.stack.imgur.com/koL2Q.jpg

我试过Gallery用 custom 换掉小部件HorizontalListView,但这给了我完全相同的结果,所以我知道这不是由于Gallery小部件的实现。

更新

我修改了我的代码,将每个图像单独添加到ImageHolderAdapter. 之前,我会创建一个ArrayList,将我所有的图像存储在其中,然后在ImageHolderAdapter. 下面的方法显示了我如何“批量”添加图像

public void loadImages(String userName, String deviceAddress, ArrayList imageList) {
    mImageHolderAdapterList.add(new ImageHolderClass(this, userName, deviceAddress, imageList));
    mImageHolderAdapter.notifyDataSetChanged();
}

现在,我ImageHolderClass在填充imageList. 然后我从ImageHolderAdapter(通过使用mImageHolderAdapter.getItem(position))中获取特定对象,imageList从那个和add()ArrayList. mImageHolderAdapter.notifyDataSetChanged()然后,每当我进行任何修改时,我都会打电话。

但是,如果我单独填充图像,现在不会显示任何图像。我得到的只是图像应该在的黑屏。

4

2 回答 2

1

您应该在 if 语句之外设置画廊的适配器。

if (v == null) {
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v = inflater.inflate(R.layout.imageholder, null);
    holder = new ViewHolder();
    holder.gallery = (Gallery)v.findViewById(R.id.gallery);        
    holder.deviceName = (TextView)v.findViewById(R.id.deviceName);
    holder.deviceAddress = (TextView)v.findViewById(R.id.deviceAddress);
    v.setTag(holder);
} else {
    holder = (ViewHolder)v.getTag();
}

holder.gallery.setAdapter(new ImageAdapter(getContext(), objects.get(position).imageList));
于 2012-04-24T13:55:52.230 回答
0

适配器数据更改时更新列表视图

尝试使视图或适配器无效 (notifyDataSetChanged() ) ...

于 2012-04-24T13:59:02.557 回答