在研究了可扩展列表视图背后的代码之后,我找到了一种相当简单的方法来完成所需的任务。我将发布我的适配器的一部分,它允许检查列表视图项目并上下移动它。请记住:1)确保您的可扩展列表视图处于“单选”模式(ExpandableListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);)
2)您的自定义行视图有 android:descendantFocusability="blocksDescendants"
我已经对 android JB 进行了几次测试,并且似乎可以正常工作,没有错误或内存泄漏。如果出现错误,请发布改进或修复。这是我的代码:
public class MyAdapter extends BaseExpandableListAdapter {
//protected ArrayList<Object> _list; //TODO: Replace with your datasource
private ExpandableListView _expandableListView;
private long _checkedPosition;
public long getCheckedPosition(){
return _checkedPosition;
}
public void setCheckedPosition(int groupPosition){
long packedPosition = ExpandableListView.getPackedPositionForGroup(groupPosition);
this.setCheckedPosition(packedPosition);
}
public void setCheckedPosition(int groupPosition, int childPosition){
long packedPosition = ExpandableListView.getPackedPositionForChild(groupPosition, childPosition);
this.setCheckedPosition(packedPosition);
}
public void setCheckedPosition(long position){
final int flatPosition;
//Gets flat position
flatPosition = _expandableListView.getFlatListPosition(position);
//Set the new position, checked and focused
_expandableListView.setItemChecked(flatPosition , true);
_checkedPosition = position;
//If it's out of bounds, set focus on it and force scroll (postpone because row's views may not exists yes)
if(flatPosition<_expandableListView.getFirstVisiblePosition() ||
flatPosition>_expandableListView.getLastVisiblePosition())
_expandableListView.post(new Runnable() {
@Override
public void run() {
_expandableListView.setSelection(flatPosition);
}
});
}
public void clearCheckedPosition(){
final int flatPosition;
flatPosition = _expandableListView.getFlatListPosition(getCheckedPosition());
_expandableListView.setItemChecked(flatPosition , false);
}
private long getPreviousPosition(long position){
int group = ExpandableListView.getPackedPositionGroup(position);
int child = ExpandableListView.getPackedPositionChild(position);
if(child==-1)
if(group>0)
return ExpandableListView.getPackedPositionForGroup(group-1);
else
return -1;
else
if(child>0)
return ExpandableListView.getPackedPositionForChild(group, child-1);
else
return -1;
}
private long getNextPosition(long position){
int group = ExpandableListView.getPackedPositionGroup(position);
int child = ExpandableListView.getPackedPositionChild(position);
if(child==-1)
if(group<getGroupCount()-1)
return ExpandableListView.getPackedPositionForGroup(group+1);
else
return -1;
else
if(child<getChildrenCount(group)-1)
return ExpandableListView.getPackedPositionForChild(group, child+1);
else
return -1;
}
public boolean canMoveUpCheckedItem(){
if(getCheckedPosition()!=-1)
if(getPreviousPosition(getCheckedPosition())!=-1)
return true;
return false;
}
public boolean canMoveDownCheckedItem(){
if(getCheckedPosition()!=-1)
if(getNextPosition(getCheckedPosition())!=-1)
return true;
return false;
}
public void moveUpFocusedItem(){
long prevPosition = this.getPreviousPosition(getCheckedPosition());
if(prevPosition!=-1L){
//Swap position
switch(ExpandableListView.getPackedPositionType(getCheckedPosition())){
case ExpandableListView.PACKED_POSITION_TYPE_GROUP:
//Collapse group if expanded
_expandableListView.collapseGroup(ExpandableListView.getPackedPositionGroup(getCheckedPosition()));
//TODO:Implement group swap
/*Collections.swap(this._list,
ExpandableListView.getPackedPositionGroup(getCheckedPosition()),
ExpandableListView.getPackedPositionGroup(prevPosition));*/
break;
case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
//TODO:Implement child swap
/**Collections.swap(this._list.get(ExpandableListView.getPackedPositionGroup(getCheckedPosition())).getChildren(),
ExpandableListView.getPackedPositionChild(getCheckedPosition()),
ExpandableListView.getPackedPositionChild(prevPosition));**/
break;
}
//Set new focused position
this.setCheckedPosition(prevPosition);
//Notify changes
this.notifyDataSetChanged();
}
}
public void moveDownFocusedItem(){
long nextPosition = this.getNextPosition(getCheckedPosition());
if(nextPosition!=-1L){
switch(ExpandableListView.getPackedPositionType(getCheckedPosition())){
case ExpandableListView.PACKED_POSITION_TYPE_GROUP:
//Collapse group if expanded
_expandableListView.collapseGroup(ExpandableListView.getPackedPositionGroup(getCheckedPosition()));
//TODO:Implement group swap
/*Collections.swap(this._list,
ExpandableListView.getPackedPositionGroup(getCheckedPosition()),
ExpandableListView.getPackedPositionGroup(nextPosition));*/
break;
case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
//TODO:Implement child swap
/*Collections.swap(this._list.get(ExpandableListView.getPackedPositionGroup(getCheckedPosition())).getChildren(),
ExpandableListView.getPackedPositionChild(getCheckedPosition()),
ExpandableListView.getPackedPositionChild(nextPosition));*/
break;
}
//Set new focused position
this.setCheckedPosition(nextPosition);
//Notify changes
this.notifyDataSetChanged();
}
}
@Override
public Object getChild(int groupPosition, int childPosition) {
//TODO: Implement
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return ExpandableListView.getPackedPositionForChild(groupPosition, childPosition);
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
//TODO: Implement
}
@Override
public int getChildrenCount(int groupPosition) {
//TODO: Implement
}
@Override
public Object getGroup(int groupPosition) {
//TODO: Implement
}
@Override
public int getGroupCount() {
//TODO: Implement
}
@Override
public long getGroupId(int groupPosition) {
return ExpandableListView.getPackedPositionForGroup(groupPosition);
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
//TODO: Implement your getGroupView
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
//TODO: Implement
}
@Override
public boolean hasStableIds() {
//TODO: Implement
}
}