BaseExpandableListAdapter с использованием двух курсоров из sqlite db - PullRequest
0 голосов
/ 05 сентября 2011

Я пытаюсь написать BaseExpandableListViewAdapter для моего приложения. Основная проблема в том, что это работает, но совершенно неправильно, и я не могу определить, что не так.

Источником для него являются две таблицы в базе данных sqlite: группы и код:

CREATE TABLE codes (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT COLLATE NOCASE NOT NULL, code TEXT NOT NULL, groupId INTEGER NOT NULL,confirmation INTEGER NOT NULL, FOREIGN KEY(groupId) REFERENCES groups(_id), CHECK(confirmation=1 OR confirmation=0));
CREATE TABLE groups (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT COLLATE NOCASE NOT NULL, icon TEXT NOT NULL, sequence INTEGER NOT NULL);

Так что я подумал, что должен предоставить Cursor, содержащий группы (для которых назначен хотя бы один код), и ArrayList, содержащий курсоры с кодами, принадлежащими группе. Дело в том, что, как я уже говорил, адаптер работает не так, как ожидалось (технически не совсем).

Вот код моего адаптера:

public class MainExpandableListAdapter extends BaseExpandableListAdapter {

public static class ImageTextViewHolder {
    ImageView img;
    TextView text1;
}

public static class TextViewHolder {
    TextView text1;
    TextView text2;
}

private Context context;
private ArrayList<Cursor> childs;
private Cursor groups;
private LayoutInflater inflater;
private String packageName;

private final String drawablesPath = "drawable";

public MainExpandableListAdapter(Context context, ArrayList<Cursor> childs, Cursor groups) {
    super();
    this.context = context;
    this.childs = childs;
    this.groups = groups;

    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    packageName = context.getPackageName();

}

public Object getChild(int groupPosition, int childPosition) {
    return null;
}

public long getChildId(int groupPosition, int childPosition) {
    Cursor temp = childs.get(groupPosition);
    temp.moveToPosition(childPosition);
    return temp.getLong(temp.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_ID));
}

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
        ViewGroup parent) {
    TextViewHolder vh;
    if (convertView == null) {
        vh = new TextViewHolder();
        convertView = inflater.inflate(R.layout.child_view, null);

        vh.text1 = (TextView) convertView.findViewById(R.id.childview_row_title);
        vh.text2 = (TextView) convertView.findViewById(R.id.childview_row_code);

        convertView.setTag(vh);
    } else {
        vh = (TextViewHolder) convertView.getTag();
    }

    Cursor temp = childs.get(groupPosition);

vh.text1.setText(temp.getString(temp.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_NAME)));
    vh.text2.setText(temp.getString(temp.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_CODE)));

    return convertView;
}

public int getChildrenCount(int groupPosition) {
    Cursor temp = childs.get(groupPosition);
    return temp.getCount();
}

public Object getGroup(int groupPosition) {
    return null;
}

public int getGroupCount() {
    return groups.getCount();
}

public long getGroupId(int groupPosition) {
    groups.moveToPosition(groupPosition);
    return groups.getLong(groups.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_ID));
}

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    ImageTextViewHolder vh;
    if (convertView == null) {
        vh = new ImageTextViewHolder();
        convertView = inflater.inflate(R.layout.group_view, null);

        vh.img = (ImageView) convertView.findViewById(R.id.groupview_row_imageview);
        vh.text1 = (TextView) convertView.findViewById(R.id.groupview_row_text);

        convertView.setTag(vh);
    } else {
        vh = (ImageTextViewHolder) convertView.getTag();
    }

    groups.moveToPosition(groupPosition);

    vh.img.setImageResource(context.getResources().getIdentifier(
            packageName + ":" + drawablesPath + "/"
                    + groups.getString(groups.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_ICON)), null, null));
    vh.text1.setText(groups.getString(groups.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_NAME)));

    return convertView;
}

public boolean hasStableIds() {
    return true;
}

public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}

 }  

А вот как я предоставляю данные для него из класса, расширяющего ExpandableListViewActivity:

private void populateExpandableList() {
    SharedPreferences sp = getSharedPreferences(PREFS_NAME, 0);
    sortOrder = sp.getString(CODES_SORT_ORDER, ALPHABETICALY);

    Cursor usedGroupsCursor = managedQuery(UssdCodesProvider.codesUri, new String[]{"distinct("
            + UssdCodesProvider.UssdDbHelper.COLUMN_GROUPID + ")"}, null, null, null);

    if (usedGroupsCursor.moveToFirst() == true) {
        String[] usedGroups = new String[usedGroupsCursor.getCount()];
        int i = 0;
        do {
            usedGroups[i] = String.valueOf(usedGroupsCursor.getInt(0));
            i++;
        } while (usedGroupsCursor.moveToNext());

        String whereClause = UssdCodesProvider.UssdDbHelper.COLUMN_ID + " in ( ?";
        if (usedGroups.length > 1)
            for (i = 1; i < usedGroups.length; i++)
                whereClause += ", ?";
        whereClause += ")";

        Cursor groups = managedQuery(UssdCodesProvider.groupsUri, null, whereClause, usedGroups,
                UssdCodesProvider.UssdDbHelper.COLUMN_SEQUENCE);

        if (groups.moveToFirst())
            do {
                Log.d("groups",groups.getString(groups.getColumnIndexOrThrow("_id"))+" "+groups.getString(groups.getColumnIndexOrThrow("name")));
            } while (groups.moveToNext());

        ArrayList<Cursor> codesArrayList = new ArrayList<Cursor>();
        for (i = 0; i < usedGroups.length; i++) {
            Cursor codes = managedQuery(UssdCodesProvider.codesUri, null,
                    UssdCodesProvider.UssdDbHelper.COLUMN_GROUPID + "='" + Integer.valueOf(usedGroups[i]) +"'", null,
                    sortOrder);
            if (codes.moveToFirst())
                do {
                    Log.d(String.valueOf(i), codes.getString(groups.getColumnIndexOrThrow("_id"))+" "+codes.getString(groups.getColumnIndexOrThrow("name")));
                } while (codes.moveToNext());
            codesArrayList.add(codes);
        }

        MainExpandableListAdapter adapter = new MainExpandableListAdapter(this, codesArrayList, groups);

        setListAdapter(adapter);
    }

EDIT

Конечно: когда я запускаю приложение и есть несколько групп, вот как выглядит список ссылка и после щелчка по группе выдает ошибку в getChildView:

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
    ViewGroup parent) {
TextViewHolder vh;
if (convertView == null) {
    vh = new TextViewHolder();
    convertView = inflater.inflate(R.layout.child_view, null);

    vh.text1 = (TextView) convertView.findViewById(R.id.childview_row_title);
    vh.text2 = (TextView) convertView.findViewById(R.id.childview_row_code);

    convertView.setTag(vh);
} else {
    vh = (TextViewHolder) convertView.getTag();
}

Cursor temp = childs.get(groupPosition);

/*THIS LINE */ vh.text1.setText(temp.getString(temp.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_NAME)));
    vh.text2.setText(temp.getString(temp.getColumnIndexOrThrow(UssdCodesProvider.UssdDbHelper.COLUMN_CODE)));

return convertView;

}

...