[英]How to load child items while click parent item in ExpandableListView
[英]How to check/uncheck CheckedTextView (child items) items inside ExpandableListView?
我的設計:我為我的 ExpandableListView 創建了一個帶有 CheckedTextView 的自定義適配器( SignalsExpandableListAdapter)
。
public class SignalsExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listDataHandler;
private HashMap<String,List<String>> listHashMap;
public SignalsExpandableListAdapter(Context context, List<String> listDataHandler, HashMap<String, List<String>> listHashMap) {
this.context = context;
this.listDataHandler = listDataHandler;
this.listHashMap = listHashMap;
}
然后將數據填充到帶有 HashMap 和 List 的片段中,如下所示。 這很好用。 我可以在我的 ExpandableListView 中看到子元素和父元素。
ArrayList<List<String[]>> deviceMList = new ArrayList<>();
final List<String[]> mList = new ArrayList<>();
deviceMList.add(mList);
我在找什么我:當我 select 任何孩子(可以是多個)時,我想使用 CheckedTextView 用勾號表示該選擇。 而且我想在我 select 任何檢查的子項目時取消選中。 (一個簡單的檢查/取消檢查設計)。 As well when any child is selected another function is called for plotting. 這就是我卡住的地方。 每次我 select 一個孩子時,隨機多個孩子的checkTextViews 也顯示為checked 不僅我select 一個。
經過一番搜索,我嘗試了 3 次嘗試來克服這個問題,並只檢查孩子 I select。 但似乎我的任何嘗試都沒有奏效。 我不確定發生了什么。 我的嘗試如下所述。 我真的很感激對此的任何建議。
我嘗試了嘗試 4(在下面的第 II 節中描述),但似乎仍然沒有實時進行檢查/取消檢查。
嘗試 1:嘗試在 Fragment 中使檢查為真
listAdapter = new SignalsExpandableListAdapter(context,signalsListDataHeader,signalsListHash);
signalsExpandableListView.setAdapter(listAdapter);
signalsExpandableListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
//tickCheckboxes();
signalsExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
CheckedTextView sensorCheckedView = (CheckedTextView) v.findViewById(R.id.sensorsCheckedTextView);
if(!mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))) {
sensorCheckedView.setChecked(true);
try {
if(Plot==null) {
Log.e(LOG_TAG, "Plot is null!");
}
mService.mPlotManager.addSignal(deviceMList.get(groupPosition).get(childPosition), Plot);
} catch (Exception e) {
Log.e(LOG_TAG, "Error! + e);
e.printStackTrace();
}
} else {
mService.mPlotManager.removeSignal(deviceMList.get(groupPosition).get(childPosition));
//signalsExpandableListView.setItemChecked(childPosition,false);
sensorCheckedView.setChecked(false);
}
return true;
}
});
嘗試 2:創建一個不同的 function 並在 Fragment 中調用它。 創建的 function 如下, function 調用在嘗試 1 上方注釋。
//loop through groups and then children
public void tickCheckboxes() {
//CheckedTextView sensorCheckedView = (CheckedTextView) signalsExpandableListView.findViewById(R.id.sensorsCheckedTextView);
for (int i = 0; i < deviceMList.size(); i++) {
for (int j = 0; j < deviceMList.get(i).size(); j++) {
if (mService.mPlotManager.ifPropertyExist(deviceMList.get(i).get(j))) {
signalsExpandableListView.setItemChecked(j, true);
//sensorCheckedView.setChecked(true);
} else {
signalsExpandableListView.setItemChecked(j, false);
//sensorCheckedView.setChecked(false);
}
}
}
}
嘗試 3:使用 ExpandableListView 適配器訪問子元素。 我更新了getChildView()
方法,如下所示。
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
final String childText = (String) getChild(groupPosition,childPosition);
if(view == null){
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.sensors_list_items,null);
}
CheckedTextView txtListChild = (CheckedTextView) view.findViewById((R.id.sensorsCheckedTextView));
txtListChild.setText(childText);
txtListChild.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (txtListChild.isChecked()) {
txtListChild.setChecked(false);
} else {
txtListChild.setChecked(true);
}
}
});
return view;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
列表項目 xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckedTextView
android:id="@+id/sensorsCheckedTextView"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:textColor="@color/black"
android:paddingTop="5dp"
android:paddingBottom="5dp"/>
</LinearLayout>
xml 組:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/deviceNameTextView"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:text="Device Name"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:background="@color/colorAccent"
android:textColor="@color/colorPrimary"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"/>
</LinearLayout>
我在尋找什么 II:對於檢查/取消檢查,我在下面提到的答案的幫助下修改了適配器,如嘗試 4 中所述。 我無法實時看到checked
的標記。 當我單擊一個孩子時,我想向上/向下滾動以直觀地看到復選標記。 與取消選中相同。 它很奇怪。 似乎需要一種“刷新”才能實時查看選中/取消選中 state。 我將不勝感激有關如何擺脫這種情況的任何建議。
謝謝你。
嘗試 4:修改適配器。 這適用於選中/取消選中,但無法實時直觀地看到它。
public class SignalsExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listDataHandler;
private HashMap<String,List<String>> listHashMap;
private MService mService;
private ArrayList<List<String[]>> deviceMList ;
public SignalsExpandableListAdapter(Context context, List<String> listDataHandler, HashMap<String, List<String>> listHashMap,mService service, ArrayList<List<String[]>> dMList ) {
this.context = context;
this.listDataHandler = listDataHandler;
this.listHashMap = listHashMap;
this.mService = service;
this.deviceMList =dMList;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
final String childText = (String) getChild(groupPosition,childPosition);
if(view == null){
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.sensors_list_items,null);
}
CheckedTextView txtListChild = (CheckedTextView) view.findViewById((R.id.sensorsCheckedTextView));
txtListChild.setText(childText);
if(mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))) {
txtListChild.setChecked(true);
} else {
txtListChild.setChecked(false);
}
return view;
}
我假設您的mService帶有一個名為 PlottingService 的 class,然后嘗試對適配器進行以下更改:
public class SignalsExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listDataHandler;
private HashMap<String,List<String>> listHashMap;
private PlottingService mService;
public SignalsExpandableListAdapter(Context context, List<String> listDataHandler, HashMap<String, List<String>> listHashMap, PlottingService ps) {
this.context = context;
this.listDataHandler = listDataHandler;
this.listHashMap = listHashMap;
this.mService = ps;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
final String childText = (String) getChild(groupPosition,childPosition);
if(view == null){
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.sensors_list_items,null);
}
CheckedTextView txtListChild = (CheckedTextView) view.findViewById((R.id.sensorsCheckedTextView));
txtListChild.setText(childText);
// Always set check state according to data.
if(mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))) {
txtListChild.setChecked(true);
} else {
txtListChild.setChecked(false);
}
return view;
}
在 Fragment 內部,嘗試 1,只更改: listAdapter = new SignalsExpandableListAdapter(context,signalsListDataHeader,signalsListHash);
to listAdapter = new SignalsExpandableListAdapter(context,signalsListDataHeader,signalsListHash, mService);
希望有幫助!
更新:-在 Fragment 中,注釋掉 OnChildClickListener 並在適配器中,使用以下 getChildView:
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View view, ViewGroup parent) {
String childText = (String) getChild(groupPosition,childPosition);
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.sensors_list_items,null);
}
CheckedTextView txtListChild = (CheckedTextView) view.findViewById((R.id.sensorsCheckedTextView));
txtListChild.setText(childText);
// Always set check state according to data.
if(mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))) {
txtListChild.setChecked(true);
} else {
txtListChild.setChecked(false);
}
txtListChild.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckedTextView sensorCheckedView = (CheckedTextView)v;
if(!sensorCheckedView.isChecked()) {
sensorCheckedView.setChecked(true);
try {
if(Plot==null) {
Log.e(LOG_TAG, "Plot is null!");
}
mService.mPlotManager.addSignal(deviceMList.get(groupPosition).get(childPosition), Plot);
} catch (Exception e) {
Log.e(LOG_TAG, "Error!" + e);
e.printStackTrace();
}
} else {
mService.mPlotManager.removeSignal(deviceMList.get(groupPosition).get(childPosition));
sensorCheckedView.setChecked(false);
}
}
});
return view;
}
更新 2:-在 Fragment 中,注釋掉 OnChildClickListener 並在適配器中,添加一個內部 class 並使用以下 getChildView:
class Position {
int group, child;
Position(int group, int child) {
this.group = group;
this.child = child;
}
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
String childText = (String) getChild(groupPosition,childPosition);
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.sensors_list_items,null);
}
CheckedTextView txtListChild = (CheckedTextView) view.findViewById((R.id.sensorsCheckedTextView));
txtListChild.setText(childText);
// Always set check state according to data.
if(mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))) {
txtListChild.setChecked(true);
} else {
txtListChild.setChecked(false);
}
txtListChild.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckedTextView sensorCheckedView = (CheckedTextView)v;
int groupPosition = ((Position)v.getTag()).group;
int childPosition = ((Position)v.getTag()).child;
if(!sensorCheckedView.isChecked()) {
sensorCheckedView.setChecked(true);
try {
if(Plot==null) {
Log.e(LOG_TAG, "Plot is null!");
}
mService.mPlotManager.addSignal(deviceMList.get(groupPosition).get(childPosition), Plot);
} catch (Exception e) {
Log.e(LOG_TAG, "Error!" + e);
e.printStackTrace();
}
} else {
mService.mPlotManager.removeSignal(deviceMList.get(groupPosition).get(childPosition));
sensorCheckedView.setChecked(false);
}
}
});
txtListChild.setTag(new Position(groupPosition, childPosition));
return view;
}
如果Updated 2仍然存在多個checked item的問題,那么可能的原因是mService.mPlotManager.ifPropertyExist(deviceMList.get(groupPosition).get(childPosition))
。 與其使用mService來驗證是否選擇了某個項目,不如將listHashMap從HashMap<String, List<String>>
更改為HashMap<String, List<ChildItem>>
[The accepted answer in Values of滾動 ExpendableListView 后計數器發生變化,您需要一個 boolean 字段而不是 integer 字段,數量]。 然后,當單擊子項時,檢查並更新列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.