天天看點

Android ExpandableListView 長按事件 position問題

長按 ExpandableListView Item 報數組越界異常,斷點 OnItemLongClickListener() 的 onItemLongClick() 方法中,發現position根據所有Group 和 已經展開的 GroupChild 數量計算,需要判斷點選的是 Group 還是 GroupChild,最優解決方法: 在 OnItemLongClick()方法中判斷點選類型。

bmMainListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
        {
            @Override
            public boolean onItemLongClick(AdapterView
   parent, View view, int position, long id)
            {

                if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_GROUP)
                {   
                    long packedPosition = ((ExpandableListView) parent).getExpandableListPosition(position);
                  
                    //目前Group下标
                    int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);
                    //目前GroupChild
                    int childPosition = ExpandableListView.getPackedPositionChild(packedPosition);

                }
                
                /**
                 * 進入ExpandableListView源碼,檢視 PACKED_POSITION_TYPE_GROUP 類型,
                    /**
                     * The packed position represents a group.
                     */
                    public static final int PACKED_POSITION_TYPE_GROUP = 0;
    
                    /**
                     * The packed position represents a child.
                     */
                    public static final int PACKED_POSITION_TYPE_CHILD = 1;
                
                    /**
                     * The packed position represents a neither/null/no preference.
                     */
                    public static final int PACKED_POSITION_TYPE_NULL = 2;
                 /**
                  * 很明顯,同理判斷當長按GroupChild 判斷
                  * if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD)
                  * { 
                  * 
                  * }
                  */
                return true;
            }
        });
           

上面代碼中的 packedPosition 會根據類型獲得不同的值,檢視源碼如下

/**
     * Converts a flat list position (the raw position of an item (child or group)
     * in the list) to a group and/or child position (represented in a
     * packed position). This is useful in situations where the caller needs to
     * use the underlying {@link ListView}'s methods. Use
     * {@link ExpandableListView#getPackedPositionType} ,
     * {@link ExpandableListView#getPackedPositionChild},
     * {@link ExpandableListView#getPackedPositionGroup} to unpack.
     * 
     * @param flatListPosition The flat list position to be converted.
     * @return The group and/or child position for the given flat list position
     *         in packed position representation. #PACKED_POSITION_VALUE_NULL if
     *         the position corresponds to a header or a footer item.
     */
    public long getExpandableListPosition(int flatListPosition) {
        if (isHeaderOrFooterPosition(flatListPosition)) {
            return PACKED_POSITION_VALUE_NULL;
        }

        final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
        PositionMetadata pm = mConnector.getUnflattenedPos(adjustedPosition);
        long packedPos = pm.position.getPackedPosition();
        pm.recycle();
        return packedPos;
    }
           

ExpandableListView 所有坐标存在一個二維清單,packedPosition表示坐标在該清單中的位置。擷取到packedPosition就可以再擷取Group和GroupChild坐标了。