我正在尝试处理'检查/取消选中' CustomArrayAdapter中的一组复选框。
要求是当我检查'一个复选框,其他复选框应根据特定条件保持选中/取消选中。
我计划的方法是,我将存储所有的复选框' ArrayList中的对象,并使用' gson'将它们添加到我的SharedPreferences文件中。当我检查'我将检索每一个复选框,并根据我的标准更改复选框的状态。
出于某种原因存储“复选框”' SharedPreferences中的对象将编译器发送到无限循环,我得到以下堆栈日志:
09-05 07:52:20.186 1560-1600/millennia.sniffbt I/OpenGLRenderer: Initialized EGL, version 1.4
09-05 07:52:20.187 1560-1600/millennia.sniffbt D/OpenGLRenderer: Swap behavior 1
09-05 07:52:44.803 1560-1565/millennia.sniffbt I/art: Do partial code cache collection, code=124KB, data=100KB
09-05 07:52:44.804 1560-1565/millennia.sniffbt I/art: After code cache collection, code=124KB, data=100KB
09-05 07:52:44.804 1560-1565/millennia.sniffbt I/art: Increasing code cache capacity to 512KB
09-05 07:52:46.339 1560-1567/millennia.sniffbt W/art: Suspending all threads took: 16.280ms
09-05 07:52:48.700 1560-1571/millennia.sniffbt I/art: Background partial concurrent mark sweep GC freed 284903(5MB) AllocSpace objects, 20(1932KB) LOS objects, 37% free, 26MB/42MB, paused 4.525ms total 115.535ms
09-05 07:52:49.627 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 517140(8MB) AllocSpace objects, 31(3MB) LOS objects, 25% free, 31MB/42MB, paused 5.249ms total 97.072ms
09-05 07:52:49.976 1560-1567/millennia.sniffbt W/art: Suspending all threads took: 15.674ms
09-05 07:52:50.410 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 368915(6MB) AllocSpace objects, 20(2MB) LOS objects, 16% free, 35MB/42MB, paused 5.346ms total 90.929ms
09-05 07:52:50.804 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 293352(5MB) AllocSpace objects, 17(2MB) LOS objects, 13% free, 36MB/42MB, paused 5.083ms total 93.860ms
09-05 07:52:51.226 1560-1571/millennia.sniffbt I/art: Background partial concurrent mark sweep GC freed 333422(5MB) AllocSpace objects, 19(2MB) LOS objects, 29% free, 37MB/53MB, paused 6.722ms total 178.796ms
09-05 07:52:51.813 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 602192(10MB) AllocSpace objects, 30(3MB) LOS objects, 23% free, 40MB/53MB, paused 6.137ms total 117.126ms
09-05 07:52:52.374 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 506509(8MB) AllocSpace objects, 24(3MB) LOS objects, 19% free, 42MB/53MB, paused 6.292ms total 112.676ms
09-05 07:52:52.605 1560-1567/millennia.sniffbt W/art: Debugger attempted to resume all threads without having suspended them all before.
09-05 07:52:52.615 1560-1567/millennia.sniffbt I/art: Debugger is no longer active
这是我的CustomArrayAdapter
CustomArrayAdapter.java:
public class CustomArrayAdapter extends ArrayAdapter<Row> {
Row[] rowItems = null;
Context context;
SharedPreferences appPrefs;
public CustomArrayAdapter(MyInterface fragmentActivity, Context context, Row[] resource) {
super(context, R.layout.row_with_cb, resource);
this.rowItems = resource;
this.context = context;
cf = new CommonFunctions();
appPrefs = getContext().getSharedPreferences(getContext().getString(R.string.app_shared_pref_filename), Context.MODE_PRIVATE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity)this.context).getLayoutInflater();
convertView = inflater.inflate(R.layout.row_with_cb, parent, false);
TextView name = (TextView)convertView.findViewById(R.id.row_with_cb_Txt);
CheckBox cb = (CheckBox)convertView.findViewById(R.id.row_with_cb_ChkBox);
// Add Checkboxes into ArrayList and store em away
ArrayList<CheckBox> arrCheckBoxes = new ArrayList<>();
arrCheckBoxes.add(cb);
SharedPreferences.Editor prefEditor = appPrefs.edit();
Gson gson = new Gson();
String json;
Type typeOfObject = new TypeToken<ArrayList<CheckBox>>(){}.getType();
json = gson.toJson(arrCheckBoxes, typeOfObject); // MY COMPILER GOES INTO INFINITE LOOP HERE
prefEditor.putString("ListOfChkBoxes", json);
prefEditor.apply();
// Create a onClickListener when a checkbox is selected
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
rowItems[position].setCB(cb.isChecked());
}
});
return convertView;
}
我有两个问题:
答案 0 :(得分:0)
如果Checkbox对象是指Checkobox,View子类 - 不能将它们存储在SharedPreferences中。你甚至不应该在你自己的适配器中保留指向它们的引用。您可以做的是将其状态保留在某个集合中,并将其填入onBindViewHolder()
。然后,您可以使用JSON或您选择的任何序列化格式将此基元集合存储在SharedPreferences中。
答案 1 :(得分:0)
解决方案比我预期的要简单得多。感谢@Himani的评论。
我在getView函数中创建的ArrayList是活动的,即使选中了另一个复选框,我也可以操作复选框。
以下是代码:
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity)this.context).getLayoutInflater();
convertView = inflater.inflate(R.layout.row_with_cb, parent, false);
TextView name = (TextView)convertView.findViewById(R.id.row_with_cb_Txt);
CheckBox cb = (CheckBox)convertView.findViewById(R.id.row_with_cb_ChkBox);
arrCheckBoxes.add(cb); // THIS ARRAY ALWAYS REMAINS UPDATED INSIDE ONCLICKLISTENER
// Create a onClickListener when a checkbox is selected
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
rowItems[position].setCB(cb.isChecked());
if(cb.isChecked()) {
for(int iCnt = 0; iCnt < arrCheckBoxes.size(); iCnt++) {
if (rowItems[iCnt].isCBChecked() && !rowItems[iCnt].getDeviceAddress().equals(rowItems[position].getDeviceAddress())) {
if (rowItems[iCnt].getDeviceMajorClass() == rowItems[position].getDeviceMajorClass()) {
arrCheckBoxes.get(iCnt).setChecked(false); // THIS IS WHERE ANOTHER CHECKBOX GETS UNCHECKED IF THE CONDITION GETS SATISFIED
rowItems[iCnt].setCB(false);
notifyDataSetChanged();
}
}
}
}
}
});
也感谢其他答案。