我面临着ExpandableListView的一个大问题。 我的目标是让用户将项目的位置更改为此单一选择可扩展列表视图:
当用户点击某个项目时,该项目将被选中并显示上下文操作栏。 因此,用户可以通过这种方式向上或向下移动项目:
我实现的上移/下移功能工作正常(它基于ArrayList上的交换位置,这是我的BaseExpandableListAdapter的数据源,并通知对UI的更改)。不幸的是,当我移动一个已检查的项目时,它会丢失已检查的状态...并且如果我将项目移出可见边界(在示例中,在“已锁定”之后或“附加”视图之前),则expandablelistview不会滚动到新职位。
我如何实现这一目标?
下面,我的“moveDownFocusedItem()”编码到我的自定义适配器类中:
//This class is ok!
//Contains Group and Child position of an ExpandableListView
public class Position{
int GroupPosition;
int ChildPosition;
public boolean isChild(){
return (ChildPosition != AbsListView.INVALID_POSITION);
}
public Position getPreviousPosition(){
if(ChildPosition==AbsListView.INVALID_POSITION)
if(GroupPosition>0)
return new Position(GroupPosition-1);
else
return null;
else
if(ChildPosition>0)
return new Position(GroupPosition, ChildPosition-1);
else
return null;
}
public Position getNextPosition(){
if(ChildPosition==AbsListView.INVALID_POSITION)
if(GroupPosition<_fieldConfigurationList.size()-1)
return new Position(GroupPosition+1);
else
return null;
else
if(ChildPosition<_fieldConfigurationList.get(GroupPosition).getChildren().size()-1)
return new Position(GroupPosition, ChildPosition+1);
else
return null;
}
public Position(int groupPosition){
this.GroupPosition = groupPosition;
this.ChildPosition = AbsListView.INVALID_POSITION;
}
public Position(int groupPosition, int childPosition){
this.GroupPosition = groupPosition;
this.ChildPosition = childPosition;
}
}
public void moveDownFocusedItem(){
//This function returns the next position to move to
//(_focusedPosition is the current checked item position)
Position nextPosition = this._focusedPosition.getNextPosition();
//Swap ArrayList (This works!)
if(nextPosition!=null){
Collections.swap(this._fieldConfigurationList, //that's my datasource
this._focusedPosition.GroupPosition, //Start position for swapping
nextPosition.GroupPosition); //Destination position for swapping
//Set the new focused position (This works!)
this._focusedPosition = nextPosition;
//TODO:
//Now i have to call "SetItemChecked()" method to uncheck old focused position and check the new one.
//How to do it? How can i get the required "position" argument from _focusedPosition.GroupPosition and _focusedPosition.ChildPosition?
//And also...if the focused view has moved to an invisible position (such as the end of the expandablelistview) how can i scroll
//to this position?
//Notify changes (This works!)
this.notifyDataSetChanged();
}
}
答案 0 :(得分:1)
在研究了expandablelistview背后的代码之后,我发现了一种非常简单的方法来完成所需的任务。我将发布我的适配器的一部分,它允许检查列表视图项并上下移动它。 记得: 1)确保您的expandablelistview处于“单选”模式(ExpandableListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);)
2)你的自定义行视图有android:descendantFocusability =“blocksDescendants”
我已经对android J.B做了几次测试,似乎没有错误或内存泄漏正常工作。 如果有错误,请发布改进或修复。 这是我的代码:
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
}
}