我正在尝试扩展BaseExpandableListAdapter,但是当我查看列表并选择要扩展的其中一个元素时,列表的顺序会反转。例如,如果我有一个包含4个元素的列表并选择第1个元素,则顺序(从上到下)现在为4,3,2,1,第4个元素(现在位于顶部)展开。如果我对第4个元素进行了扩展,则该顺序将恢复为1,2,3,4,而不包含扩展元素。
这是我的实施:
public class SensorExpandableAdapter extends BaseExpandableListAdapter {
private static final int FILTER_POSITION = 0;
private static final int FUNCTION_POSITION = 1;
private static final int NUMBER_OF_CHILDREN = 2;
ArrayList<SensorType> mParentGroups;
private Context mContext;
private LayoutInflater mInflater;
public SensorExpandableAdapter(ArrayList<SensorType> parentGroup, Context context) {
mParentGroups = parentGroup;
mContext = context;
mInflater = LayoutInflater.from(mContext);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
if(childPosition == FILTER_POSITION) return "filter";
else return "function";
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = (RelativeLayout)mInflater.inflate(R.layout.sensor_row_list_item, parent, false);
if(childPosition == FILTER_POSITION) {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Filter");
} else {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Function");
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setEnabled(false);
}
}
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return NUMBER_OF_CHILDREN;
}
@Override
public Object getGroup(int groupPosition) {
return mParentGroups.get(groupPosition);
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mParentGroups.size();
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = mInflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
TextView tv = ((TextView)convertView.findViewById(android.R.id.text1));
tv.setText(mParentGroups.get(groupPosition).toString());
}
return convertView;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
`
我只需要使用我自己的SensorType类的简单ArrayList。所有班级的孩子都是一样的,只有两个。
另外,如何在每个组LongClickable中创建父级?我已经尝试使用此getExpandableListView().setOnLongClickableListener() ...
在我的ExpandableListActivity中,并在父TextView上设置了它的OnLongClickableListener,但都不起作用。
非常感谢任何一方的帮助!
答案 0 :(得分:3)
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if(convertView == null)
{
只需注释掉“如果”。这应该有所帮助。
答案 1 :(得分:1)
更新:这个答案来得太晚了;但对于有同样问题的人,这是我的解决方案。
我遇到了同样的问题,并在阅读完chome2phone源代码后设法解决了这个问题。
关键在于这种方法:
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = (RelativeLayout)mInflater.inflate(R.layout.sensor_row_list_item, parent, false);
if(childPosition == FILTER_POSITION) {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Filter");
} else {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Function");
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setEnabled(false);
}
}
return convertView;
}
AS @Dan说,convertView是一个缓存项目,documentation说:
convertView :如果可能,将旧视图重用。 您应该检查此视图是否正确 非null和适当的类型 在使用之前。如果不可能的话 转换此视图以显示 正确的数据,这种方法可以创建一个 新观点。不能保证 convertView将会是 以前创建的 getChildView(int,int,boolean,View, ViewGroup中)。
在我的例子中,传递给getChildView()
的对象可能来自缓存,其顺序与创建顺序完全相反;堆栈可能(LIFO)。
主要有两种解决方案;你要么删除
if(convertView == null)
因此在每次展开/折叠动作或每次方向改变时重新创建孩子,或者(方式更好的表现)做一些事情:
public View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {
RelativeLayout mItemView;
if (null == convertView || !(convertView instanceof RelativeLayout)) {
mItemView = (RelativeLayout)mInflater.inflate(R.layout.sensor_row_list_item, parent, false);
}else{
mItemView = (RelativeLayout) convertView;
}
if(childPosition == FILTER_POSITION) {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Filter");
} else {
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setText("Add Function");
((CheckBox)convertView.findViewById(R.id.chkTextAddFilter)).setEnabled(false);
}
}
return convertView;
这意味着您将使用convertView对象渲染项而不是创建新项。
我希望这也适合你。
答案 2 :(得分:1)
我希望这是您正在寻找的答案
public class Sample extends ExpandableListActivity {
ExpandableListAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mAdapter = new MyExpandableListAdapter();
setListAdapter(mAdapter);
registerForContextMenu(getExpandableListView());
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Sample menu");
menu.add(0, 0, 0, R.string.expandable_list_sample_action);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
String title = ((TextView) info.targetView).getText().toString();
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
Toast.makeText(Sample.this, title + ": Child " + childPos + " clicked in group " + groupPos,
Toast.LENGTH_SHORT).show();
return true;
} else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
Toast.makeText(this, title + ": Group " + groupPos + " clicked", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
/**
* A simple adapter which maintains an ArrayList of photo resource Ids.
* Each photo is displayed as an image. This adapter supports clearing the
* list of photos and adding a new photo.
*
*/
public class MyExpandableListAdapter extends BaseExpandableListAdapter {
// Sample data set. children[i] contains the children (String[]) for groups[i].
private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" };
private String[][] children = {
{ "Arnold", "Barry", "Chuck", "David" },
{ "Ace", "Bandit", "Cha-Cha", "Deuce" },
{ "Fluffy", "Snuggles" },
{ "Goldy", "Bubbles" }
};
public Object getChild(int groupPosition, int childPosition) {
return children[groupPosition][childPosition];
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getChildrenCount(int groupPosition) {
return children[groupPosition].length;
}
public TextView getGenericView() {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 64);
TextView textView = new TextView(Sample.this);
textView.setLayoutParams(lp);
// Center the text vertically
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
textView.setPadding(36, 0, 0, 0);
return textView;
}
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
TextView textView = getGenericView();
textView.setText(getChild(groupPosition, childPosition).toString());
return textView;
}
public Object getGroup(int groupPosition) {
return groups[groupPosition];
}
public int getGroupCount() {
return groups.length;
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
TextView textView = getGenericView();
textView.setText(getGroup(groupPosition).toString());
return textView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public boolean hasStableIds() {
return true;
}
}}
答案 3 :(得分:1)
这是我的第一个stackoverflow.com -answer。
我今天正在努力解决这个问题,并尝试了之前帖子中提供的解决方案。
评论“if”-clause确实解决了问题,但我认为这不是推荐的解决方案。如此ListView视频(http://www.youtube.com/watch?v=wDBM6wVEO70)中所述,在处理大型数据集时,重复使用convertView至关重要。
我的解决方案非常简单,在我的案例中完美运行。我从之前提到的视频中得到了这个想法:
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// 1. Step: check if convertView can be re-used or if it should be created.
if (convertView == null) {
// create the view or inflate the view from xml here
// Note: inlating is expensive process, so do it only if needed
// (it's needed when convertView can not be re-used)
//
// TODO: your code here
}
// 2. Step: populate the convertView with correct data.
// Correct data can be accessed through groupPosition.
//
// TODO: your code here
return convertView;
}
我认为问题中提供的代码中缺少第二步?
我希望这可以帮助有同样问题的人。