android - 如何在 GridView 适配器中保持视图状态?
问题描述
我正在尝试制作来自不同房间/地方的图片库。这些由id标记,我想在不同的网格上显示它们(相同的 GridView 但我只是更改数据集并调用notifyDataSetChanged()
)。单个项目也有CheckBox
哪些用户可以检查(但每个网格只有一个),然后他可以使用新数据集进入下一个“页面”。但是在下一页CheckBox
已经检查了相同的内容,或者在按“上一个”时未检查,或者两者都被检查或其他混乱的情况。我尝试了很多解决方案:保留这些复选框的表格,保留他们的 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;
//}
}
创建 GridView:
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
。我正在保存position
使用CheckBox
首选项键"RoomNumber" + roomNumber
,然后我根据房间号阅读它。SharedPreferences
即使在应用程序关闭后也能工作。
推荐阅读
- c++ - 类定义中的“错误:'a'没有命名类型”
- c# - 如何在从数据库“对象或列名丢失或为空”加载数据时修复运行时错误。
- php - mysqli_query() 和 mysqli_fetch_array() 至少需要 2 个参数
- python - 视频播放时间
- javascript - 如何创建带有折扣的计算功能?
- telegram - 如何使用 python-telegram-bot 删除群聊中超过 2 天的消息?
- java - 如何在 Java 中获取 while 输入(用户输入 0 终止程序时除外)?
- rspec - 用于分页的 Rspec
- php - 如果 iframe 中没有 url,如何隐藏空的 div 文件?
- python - 在 django cbv 中保存模型表单后重定向