如何在 GridView Adapter 中保持视图状态?
How to keep View state inside GridView Adapter?
我正在尝试制作来自不同 rooms/places 的图片库。这些由 id 标记,我想在不同的网格上显示它们(相同的 GridView 但我只是更改数据集并调用 notifyDataSetChanged()
)。此外,单个项目有 CheckBox
用户可以检查(但每个网格只有一个),然后他可以使用新数据集转到下一个 "page"。但是在下一页相同的 CheckBox
已经被选中,或者在按下 "previous" 时它没有被选中,或者两者都被选中或其他混乱的情况。我已经尝试了很多解决方案:保留 table 个复选框,保留它们的 ID,保留之前选中的 CheckBox
但这还不是全部,但没有任何效果。
这是我的代码:
适配器:
public class GalleryGridAdapter extends BaseAdapter {
private Context context;
private ArrayList<PhotosPOJO> galleryList;
private static String[] checkTab;
private static int[] checkBoxNumberTab;
//private static int[] selectedTab;
//private static CheckBox prevSelected;
private int roomNumber;
public GalleryGridAdapter(Context context, ArrayList<PhotosPOJO> list) {
this.context = context;
this.galleryList = list;
//prevSelected = null;
checkTab = new String[12];
checkBoxNumberTab = new int[12];
//selectedTab = new int[12];
for (int i = 0; i < 12; i++) {
checkTab[i] = null;
checkBoxNumberTab[i] = -1;
//selectedTab[i] = NO_ID;
}
}
public void setRoomNumber(int roomNumber) {
this.roomNumber = roomNumber;
}
@Override
public int getCount() {
return galleryList.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(final int i, View view, final ViewGroup viewGroup) {
final String photo = galleryList.get(i).getAbsolutePath();
if (view == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(context);
view = layoutInflater.inflate(R.layout.grid_item_gallery, null);
}
final PhotoView photoView = (PhotoView) view.findViewById(R.id.gallery_photo_view);
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.gallery_checkbox);
final ImageView ivTrash = (ImageView) view.findViewById(R.id.gallery_iv_trash);
checkBox.bringToFront();
ivTrash.bringToFront();
Glide.with(context)
.load(photo)
.into(photoView);
ivTrash.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_restore_from_trash));
for (int k = 0; k < viewGroup.getChildCount(); k++) {
if (viewGroup.getChildAt(k) instanceof CheckBox) {
((CheckBox) viewGroup.getChildAt(k)).setChecked(false);
}
}
if (checkBoxNumberTab[roomNumber] != -1) {
((CheckBox) viewGroup.getChildAt(checkBoxNumberTab[roomNumber]).findViewById(R.id.gallery_checkbox)).setChecked(true);
}
/*checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (prevSelected != null) {
prevSelected.setChecked(false);
((CheckBox) view).setChecked(true);
prevSelected = (CheckBox) view;
checkTab[roomNumber] = photo;
} else {
((CheckBox) view).setChecked(true);
prevSelected = (CheckBox) view;
}
}
});*/
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
if (checkTab[roomNumber] != null) {
//prevSelected.setChecked(false);
for (int k = 0; k < viewGroup.getChildCount(); k++) {
if (compoundButton == viewGroup.getChildAt(k)) {
checkBoxNumberTab[roomNumber] = k;
}
}
compoundButton.setChecked(true);
//selectedTab[roomNumber] = compoundButton.getId();
//prevSelected = (CheckBox)compoundButton;
checkTab[roomNumber] = photo;
} else {
compoundButton.setChecked(true);
checkTab[roomNumber] = photo;
//selectedTab[roomNumber] = compoundButton.getId();
//prevSelected = (CheckBox)compoundButton;
}
} else {
checkTab[roomNumber] = null;
checkBoxNumberTab[roomNumber] = -1;
//selectedTab[roomNumber] = NO_ID;
//prevSelected = null;
}
}
});
ivTrash.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
galleryList.remove(i);
notifyDataSetChanged();
}
});
return view;
}
public void setData(ArrayList<PhotosPOJO> newPhotos) {
this.galleryList = newPhotos;
notifyDataSetChanged();
}
//public int[] getTabValue(int roomNumber) {
// return checkTab;
//}
}
正在创建网格视图:
gv = (GridView) findViewById(R.id.galleryGridView); // my GridView
galleryAdapter = new GalleryGridAdapter(this, galleryList);
galleryAdapter.setRoomNumber(roomNumber);
gv.setAdapter(galleryAdapter);
正在更新网格:
private void updateView() {
galleryList = new ArrayList<>();
galleryList = dbPhotos.getPhotosByRoom(roomNumber);
galleryAdapter.setData(galleryList);
galleryAdapter.setRoomNumber(roomNumber);
Toast.makeText(GalleryActivity.this, String.valueOf(roomNumber), Toast.LENGTH_SHORT).show();
}
调用方式:(待更新)
private void setListeners() {
fabLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (roomNumber > 0) {
--roomNumber;
fabRight.show();
}
if (roomNumber == 0) {
fabLeft.hide();
} else {
fabLeft.show();
}
updateView();
}
});
fabRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (roomNumber < 11) {
++roomNumber;
fabLeft.show();
}
if (roomNumber == 11) {
fabRight.hide();
} else {
fabRight.show();
}
updateView();
}
});
}
我被困在这里了。也许我遗漏了什么,但我真的不知道如何解决这个问题
好的,
所以我使用 SharedPreferences
解决了这个问题。我正在使用首选项键 "RoomNumber" + roomNumber
保存 CheckBox
的 position
,然后根据房间号读取它。感谢 SharedPreferences
即使在应用程序关闭后也能正常工作。
我正在尝试制作来自不同 rooms/places 的图片库。这些由 id 标记,我想在不同的网格上显示它们(相同的 GridView 但我只是更改数据集并调用 notifyDataSetChanged()
)。此外,单个项目有 CheckBox
用户可以检查(但每个网格只有一个),然后他可以使用新数据集转到下一个 "page"。但是在下一页相同的 CheckBox
已经被选中,或者在按下 "previous" 时它没有被选中,或者两者都被选中或其他混乱的情况。我已经尝试了很多解决方案:保留 table 个复选框,保留它们的 ID,保留之前选中的 CheckBox
但这还不是全部,但没有任何效果。
这是我的代码:
适配器:
public class GalleryGridAdapter extends BaseAdapter {
private Context context;
private ArrayList<PhotosPOJO> galleryList;
private static String[] checkTab;
private static int[] checkBoxNumberTab;
//private static int[] selectedTab;
//private static CheckBox prevSelected;
private int roomNumber;
public GalleryGridAdapter(Context context, ArrayList<PhotosPOJO> list) {
this.context = context;
this.galleryList = list;
//prevSelected = null;
checkTab = new String[12];
checkBoxNumberTab = new int[12];
//selectedTab = new int[12];
for (int i = 0; i < 12; i++) {
checkTab[i] = null;
checkBoxNumberTab[i] = -1;
//selectedTab[i] = NO_ID;
}
}
public void setRoomNumber(int roomNumber) {
this.roomNumber = roomNumber;
}
@Override
public int getCount() {
return galleryList.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(final int i, View view, final ViewGroup viewGroup) {
final String photo = galleryList.get(i).getAbsolutePath();
if (view == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(context);
view = layoutInflater.inflate(R.layout.grid_item_gallery, null);
}
final PhotoView photoView = (PhotoView) view.findViewById(R.id.gallery_photo_view);
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.gallery_checkbox);
final ImageView ivTrash = (ImageView) view.findViewById(R.id.gallery_iv_trash);
checkBox.bringToFront();
ivTrash.bringToFront();
Glide.with(context)
.load(photo)
.into(photoView);
ivTrash.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_restore_from_trash));
for (int k = 0; k < viewGroup.getChildCount(); k++) {
if (viewGroup.getChildAt(k) instanceof CheckBox) {
((CheckBox) viewGroup.getChildAt(k)).setChecked(false);
}
}
if (checkBoxNumberTab[roomNumber] != -1) {
((CheckBox) viewGroup.getChildAt(checkBoxNumberTab[roomNumber]).findViewById(R.id.gallery_checkbox)).setChecked(true);
}
/*checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (prevSelected != null) {
prevSelected.setChecked(false);
((CheckBox) view).setChecked(true);
prevSelected = (CheckBox) view;
checkTab[roomNumber] = photo;
} else {
((CheckBox) view).setChecked(true);
prevSelected = (CheckBox) view;
}
}
});*/
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
if (checkTab[roomNumber] != null) {
//prevSelected.setChecked(false);
for (int k = 0; k < viewGroup.getChildCount(); k++) {
if (compoundButton == viewGroup.getChildAt(k)) {
checkBoxNumberTab[roomNumber] = k;
}
}
compoundButton.setChecked(true);
//selectedTab[roomNumber] = compoundButton.getId();
//prevSelected = (CheckBox)compoundButton;
checkTab[roomNumber] = photo;
} else {
compoundButton.setChecked(true);
checkTab[roomNumber] = photo;
//selectedTab[roomNumber] = compoundButton.getId();
//prevSelected = (CheckBox)compoundButton;
}
} else {
checkTab[roomNumber] = null;
checkBoxNumberTab[roomNumber] = -1;
//selectedTab[roomNumber] = NO_ID;
//prevSelected = null;
}
}
});
ivTrash.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
galleryList.remove(i);
notifyDataSetChanged();
}
});
return view;
}
public void setData(ArrayList<PhotosPOJO> newPhotos) {
this.galleryList = newPhotos;
notifyDataSetChanged();
}
//public int[] getTabValue(int roomNumber) {
// return checkTab;
//}
}
正在创建网格视图:
gv = (GridView) findViewById(R.id.galleryGridView); // my GridView
galleryAdapter = new GalleryGridAdapter(this, galleryList);
galleryAdapter.setRoomNumber(roomNumber);
gv.setAdapter(galleryAdapter);
正在更新网格:
private void updateView() {
galleryList = new ArrayList<>();
galleryList = dbPhotos.getPhotosByRoom(roomNumber);
galleryAdapter.setData(galleryList);
galleryAdapter.setRoomNumber(roomNumber);
Toast.makeText(GalleryActivity.this, String.valueOf(roomNumber), Toast.LENGTH_SHORT).show();
}
调用方式:(待更新)
private void setListeners() {
fabLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (roomNumber > 0) {
--roomNumber;
fabRight.show();
}
if (roomNumber == 0) {
fabLeft.hide();
} else {
fabLeft.show();
}
updateView();
}
});
fabRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (roomNumber < 11) {
++roomNumber;
fabLeft.show();
}
if (roomNumber == 11) {
fabRight.hide();
} else {
fabRight.show();
}
updateView();
}
});
}
我被困在这里了。也许我遗漏了什么,但我真的不知道如何解决这个问题
好的,
所以我使用 SharedPreferences
解决了这个问题。我正在使用首选项键 "RoomNumber" + roomNumber
保存 CheckBox
的 position
,然后根据房间号读取它。感谢 SharedPreferences
即使在应用程序关闭后也能正常工作。