ギャラリーウィジェットと2つのTextViewを子として持つMy ListViewのカスタムArrayAdapterがギャラリーウィジェットとそのコンテンツを更新しないという問題が発生しています。カスタムArrayAdapterが子ウィジェットを更新しない
アプリケーションの背景を設定するには、2つ以上のデバイスをBluetoothで接続し、各デバイスの写真を接続されたデバイスにストリームするアプリケーションを作成します。今のところ、実装のために、各デバイスはスクロール可能なリストビューで表され、ギャラリーウィジェット(すべてのデバイスのイメージを水平にスクロール可能)とその下に2つのTextViewウィジェットがあり、送信者を識別します。次のように
ListViewコントロールのレイアウトは次のとおりです。
<LinearLayout ...>
<Gallery .../>
<LinearLayout>
<TextView .../>
<TextView .../>
</LinearLayout>
</LinearLayout>
送信側と受信側の画像が問題ではないと私はかなり繰り返し、それらをテストしています。
問題はカスタムArrayAdapterのnotifyDataSetChanged()
メソッドが期待どおりに動作していないことが原因です。 ListView(私のメインActivity
)に新しいImageHolderClassオブジェクトを作成すると、次のようになります。mImageHolderAdapter.add(new ImageHolderClass(this, "Me", mBtAdapter.getAddress(), mLocalImageList));
アダプタのadd()
メソッドがnotifyDataSetChanged()
を呼び出す必要があることがわかっている場合、作成されて追加された最初のオブジェクトに対して期待通りに機能します。しかし、別のオブジェクトを追加するか、オブジェクトのimageList
に新しいイメージを追加すると、最初のオブジェクトに格納されているイメージの正確なコピーが作成されます。
興味深いことに、各ImageHolderClass
の2つのTextView変数が更新されますが、ギャラリーの画像はまったく同じように見えます。
私は方法(addItem()
で)ImageHolderAdapter()
にadd()
方法を迂回しようとした、その後、他の画像は他の画像を表示するように思われる、追加された(しかし、それらのすべてが表示されない場合にのみ、notifyDataSetChanged()
を強制しました)が、デバイスと他のデバイスが接続されていない場合には表示されません。
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を:次のように
私のカスタムArrayAdapterは
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
私は、カスタムHorizontalListView
でGallery
ウィジェットをスワップアウトしようとしたが、それは私にまったく同じ結果を与えたので、私はそれがGallery
ウィジェットの実装によるものではなかった知っています。
更新
私はImageHolderAdapter
に個別に画像を追加するために自分のコードを修正しました。以前はArrayList
を作成し、すべての画像を保存してからImageHolderAdapter
に新しいオブジェクトを作成しました。以下の方法は、私はimageList
を移入する前に
public void loadImages(String userName, String deviceAddress, ArrayList imageList) {
mImageHolderAdapterList.add(new ImageHolderClass(this, userName, deviceAddress, imageList));
mImageHolderAdapter.notifyDataSetChanged();
}
は今、私はImageHolderClass
オブジェクトを作成し、「大量に」画像を追加する方法を示しています。私はImageHolderAdapter
(mImageHolderAdapter.getItem(position)
を使って)特定のオブジェクトをつかみ、そのからを取得し、add()
をArrayList
にします。私はmImageHolderAdapter.notifyDataSetChanged()
に電話します。
ただし、イメージを個別に設定すると、イメージは表示されません。私が得るのは、画像があるはずの黒いスクリーンです。
...ビューまたはアダプタ(notifyDataSetChangedを())無効にしてください。 –