2013-01-14 114 views
2

我面临着ExpandableListView的一个大问题。 我的目标是让用户改变项目的位置到这个单一的选择扩展列表视图:将选中的项目移动到可扩展列表视图

enter image description here

当用户点击一个项目,该项目成为检查,并显示上下文操作栏。 所以用户可以向上或向下移动一个项目这样:

enter image description here

工作正常(它是基于在一个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(); 

    } 
} 

回答

1

研究expandablelistview后面的代码后,我发现了一个相当简单的方式所需的任务。我将发布我的适配器的一部分,它允许检查列表视图项并上下移动它。 记住: 1)确保你的expandablelistview是 “单选” 模式(ExpandableListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);)

2)您的自定义列视图有机器人: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 
} 

}

相关问题