好的,这是我的问题。我有一个expandableListView和自定义适配器。我能够设置适配器来处理2个不同的子视图类型(一个带有开关,另一个没有)。我也使用ViewHolder来管理视图。ExpandableListView(Android):多个viewTypes - 通过onClickListener在它们之间传递数据?
我正在努力的是如何在没有从具有开关的viewType切换的情况下影响viewType。具体来说,带开关的viewType是一个childHeader,它出现在每个组的开头。当用户切换开关时,我希望能够更改组中其余子项的文本颜色(并禁止选择该行)。
因为切换是在rowType零中膨胀的,所以它只能看到存在于相同viewType中的其他视图。
此外:我需要这些更新通过零视图类型中的切换开关发生。所以当用户切换开关时,所有的视图都会受到影响。
这是我需要在活动中做的事吗?
任何想法如何做到这一点将不胜感激(请不要使用第三方库的建议)。
输出例如:
请参阅下面的示例代码:
适配器代码:
public class NavDrawerExpandableListAdapter extends BaseExpandableListAdapter {
private static final int CHILD_HEADER = 0;
private static final int CHILD_LINE_ITEM = 1;
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
private final Set<Pair<Long, Long>> mToggleSwitchedItems = new HashSet<Pair<Long, Long>>();
public NavDrawerExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
//view holder class to store our textView
private class ViewHolder {
TextView textView;
Switch childHeaderToggle;
}
//number of different types of views we're gonna inflate for the children
@Override
public int getChildTypeCount() {
return 2;
}
//specify which viewType to inflate in the getView method
@Override
public int getChildType (int groupPosition, int childPosition) {
switch(childPosition) {
case 0:
return CHILD_HEADER;
default:
return CHILD_LINE_ITEM;
}
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(groupPosition))
.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//declare our view and viewholder objects
View view = convertView;
ViewHolder viewHolder;
String expandedListText;
//define childType
int childType = getChildType(groupPosition, childPosition);
//define the toggleTag position
Pair<Long, Long> childHeaderToggleTag = new Pair<Long, Long>(getGroupId(groupPosition), getChildId(groupPosition, childPosition));
if (convertView == null) {
viewHolder = new ViewHolder();
switch (childType) {
case CHILD_HEADER:
//inflate our layout and textview then setTag viewholder if the view is null
view = LayoutInflater.from(context).inflate(R.layout.navdrawer_list_item_header, null);
viewHolder.textView = (TextView) view.findViewById(R.id.expandedListItemChildHeader);
viewHolder.childHeaderToggle = (Switch) view.findViewById(R.id.toggle_allDevices);
viewHolder.textView.setText("All Teams");
break;
case CHILD_LINE_ITEM:
expandedListText = (String) getChild(groupPosition, childPosition - 1);
//inflate our layout and textview then setTag viewholder if the view is null
view = LayoutInflater.from(context).inflate(R.layout.navdrawer_list_item, null);
viewHolder.textView = (TextView) view.findViewById(R.id.expandedListItem);
viewHolder.textView.setText(expandedListText);
break;
default:
expandedListText = (String) getChild(groupPosition, childPosition - 1);
//inflate our layout and textview then setTag viewholder if the view is null
view = LayoutInflater.from(context).inflate(R.layout.navdrawer_list_item, null);
viewHolder.textView = (TextView) view.findViewById(R.id.expandedListItem);
viewHolder.textView.setText(expandedListText);
break;
}
view.setTag(viewHolder);
}
else {
//otherwise if the view exists then gettag() our saved view
viewHolder = (ViewHolder) view.getTag();
}
//control the state of the child header toggle switch
if (childPosition == 0) {
viewHolder.childHeaderToggle.setTag(childHeaderToggleTag);
// set switched on if groupId/childId is in switched list
viewHolder.childHeaderToggle.setChecked(mToggleSwitchedItems.contains(childHeaderToggleTag));
// set OnClickListener to handle checked switches
viewHolder.childHeaderToggle.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final Switch cb = (Switch) v;
final Pair<Long, Long> tag = (Pair<Long, Long>) v.getTag();
if (cb.isChecked()) {
mToggleSwitchedItems.add(tag);
} else {
mToggleSwitchedItems.remove(tag);
}
}
});
}
return view;
}
@Override
public int getChildrenCount(int listPosition) {
return (this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size() + 1);
}
@Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
@Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
@Override
public long getGroupId(int listPosition) {
return listPosition;
}
@Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.navdrawer_list_group, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
ExpandableListView expandableListView;
NavDrawerExpandableListAdapter expandableListAdapter;
List<String> expandableListTitle;
HashMap<String, List<String>> expandableListDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
expandableListDetail = ExpandableListDataPump.getData();
expandableListTitle = new ArrayList<String>(expandableListDetail.keySet());
expandableListAdapter = new NavDrawerExpandableListAdapter(this, expandableListTitle, expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
expandableListView.setChoiceMode(expandableListView.CHOICE_MODE_SINGLE);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
//initialize int var
int previousGroup = 0;
@Override
public void onGroupExpand(int groupPosition) {
//this conditional enables only one drop down group to open at a time
if(groupPosition != previousGroup)
expandableListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
if (childPosition == 0) {
Toast.makeText(
getApplicationContext(),
"All Teams", Toast.LENGTH_SHORT
).show();
}
else {
Toast.makeText(
getApplicationContext(),
expandableListTitle.get(groupPosition)
+ " -> "
+ expandableListDetail.get(
expandableListTitle.get(groupPosition)).get(
childPosition - 1), Toast.LENGTH_SHORT
).show();
}
return false;
}
});
}
}
在您的适配器中保留一个SparseArray字段。将groupPosition值作为viewHolder.childHeaderToggle的标记(Integer值)传递。在交换机的监听器中,使用上面的SparseArray并将交换机的状态:* sparseArray.put((Integer)cb.getTag(),cb.isChecked())*。然后进一步修改getChildView()方法,将* else *子句添加到* if(childPosition == 0){... *,您可以根据需要修改其他行,方法是获取此组的开关状态: *布尔switchStatus = sparseArray.valueAt(groupPosition); ... * –
Luksprog
感谢您的快速反应Luksprog。如果我正确理解你的建议,那么除零以外的行中的视图将被更改,但它们不会通过onClickListener更改。我需要在交换机切换时更新这些值。对不起,也许我应该更具体一些,我可以通过使用简单的set()和get()方法来改变值。问题在于文字颜色不会更新,除非我重新打开组(这是getView被再次调用的时候)。 (这是我的错,因为没有在我的原始文章中包括这个 - 对此很抱歉) –
更新后的原始文章包含onClickListener –