ギャラリー ウィジェットと子として 2 つの TextView を持つ ListView のカスタム ArrayAdapter が、ギャラリー ウィジェットとそのコンテンツを更新しないという問題があります。
アプリケーションの背景を設定するために、2 つ以上のデバイスを Bluetooth 経由で相互に接続し、各デバイスの写真を接続されたデバイスにストリーミングできるようにするアプリケーションを作成しています。現時点では、実装のために、各デバイスはスクロール可能なリスト ビューで表されます。このビューには、ギャラリー ウィジェット (そのデバイスのすべての画像が水平方向にスクロール可能) と、その下に送信者を識別する 2 つの 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
と、最初のオブジェクトに保存されている画像の正確なコピーが作成されます。
ここで興味深いことに、それぞれの 2 つの 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()
その後、変更を加えるたびに呼び出します。
ただし、画像を個別に入力すると、画像が表示されなくなりました。私が得るのは、画像があるはずの黒い画面だけです。