Заполнение ExpandableListView из SQL (требуется помощь).

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Ответить
kir_nsk
Сообщения: 3
Зарегистрирован: 28 ноя 2015, 12:15

Заполнение ExpandableListView из SQL (требуется помощь).

Сообщение kir_nsk » 28 ноя 2015, 12:47

Всем привет!
Требуется помощь (пример, подсказка, ссылка...)

Пытаюсь заполнить ExpandableListView из SQL.
База содержит 2 таблицы с родительскими и дочерними элементами.
Понимаю что скорее всего нужно использовать CursorTreeAdapter.

Поиск в сети приводит только на "обрывочные" примеры, но вот как именно их применить опыта не хватает понять.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Заполнение ExpandableListView из SQL (требуется помощь).

Сообщение Foenix » 29 ноя 2015, 00:38

если у тебя только 2 уровня, то подойдет этот ExpandableListView , а если больше - то не подойдет.
Алгоритм действия такой.
Вначале строишь первый уровень, выбирая из таблиц (опять же, ты просишь совета, но никакой информации нет) всех родителей, т.е. при правильной структуре таблиц - всех тех, у кого parent=0.
Затем уже, при клике на ветке дерева, при открытии - выбираешь тех, у кого parent=выбранный элемент id.

А вообще зачем искать в сети? тут урок был. Возможно там реализация всего другая.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

kir_nsk
Сообщения: 3
Зарегистрирован: 28 ноя 2015, 12:15

Re: Заполнение ExpandableListView из SQL (требуется помощь).

Сообщение kir_nsk » 29 ноя 2015, 11:25

Основная загвоздка была с адаптером (какой выбрать и как применить, с ним вроде разобрался, но остается с Loader-ом и LoaderManager. т.е. строки implements LoaderManager.LoaderCallbacks<Cursor>, getLoaderManager().initLoader(0, null, this);, getLoaderManager().getLoader(0).forceLoad(); пока в код добавил на уровне copy-paste).

Касательно кода, получилось нечто следующее:
Может будут какие-то замечания/предложения
ps 1 - swapCursor() в onLoadFinished() - выдавал ошибку, пока не понимаю его предназначение, удалил его , предполагаю что будут проблемы когда дойду до добавления удаления родительских или дочерних элементов.
ps 2 - getSupportLoaderManager().initLoader(0, null, this); getSupportLoaderManager().getLoader(0).forceLoad(); заменил на getLoaderManager().initLoader(0, null, this); getLoaderManager().getLoader(0).forceLoad();, думаю что прав, если ориентироваться на Android не ниже 3 версии.


DB.java

Код: Выделить всё

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;


public class DB {


    private static final String DB_NAME = "mydb";
    private static final int DB_VERSION = 1;
    private static final String DB_TABLE_GROUP = "mytab";

    private static final String DB_TABLE_ITEM = "mytabb";

    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_IDITEM = "_id";

    public static final String COLUMN_TXT = "txt";
    public static final String COLUMN_TXT2 = "txt2";

    public static final String COLUMN_GROUP_ID = "id";

    private static final String DB_CREATE_GROUP =
            "create table " + DB_TABLE_GROUP + " ( " +
                    COLUMN_ID + " integer , " +
                    COLUMN_TXT + " text ) ;";

    private static final String DB_CREATE_ITEM =
            " create table " + DB_TABLE_ITEM + " ( " +
                    COLUMN_IDITEM + " integer primary key autoincrement, " +
                    COLUMN_TXT2 + " text, " +
                    COLUMN_GROUP_ID + " integer ); ";


    private final Context mCtx;


    private DBHelper mDBHelper;
    private SQLiteDatabase mDB;

    public DB(Context ctx) {
        mCtx = ctx;
    }

    public void open() {
        mDBHelper = new DBHelper(mCtx, DB_NAME, null, DB_VERSION);
        mDB = mDBHelper.getWritableDatabase();
    }


    public void close() {
        if (mDBHelper != null) mDBHelper.close();
    }

    public Cursor getGroupData() {

        return mDB.query(DB_TABLE_GROUP, null, null, null, null, null, null);
    }

    public Cursor getItemData(long groupId) {

        return mDB.query(DB_TABLE_ITEM, null, COLUMN_GROUP_ID + " = " + groupId, null, null, null, null);
    }

    
    private class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                        int version) {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            db.execSQL(DB_CREATE_GROUP);
            db.execSQL(DB_CREATE_ITEM);


            for (int i = 1; i < 5; i++) {
                ContentValues cv = new ContentValues();

                cv.put(COLUMN_ID, i);
                cv.put(COLUMN_TXT, "Group " + i);
                db.insert(DB_TABLE_GROUP, null, cv);

                for (int n = 0; n < 3; n++) {
                    ContentValues cv2 = new ContentValues();

                    cv2.put(COLUMN_TXT2, "  - item " + n);
                    cv2.put(COLUMN_GROUP_ID, i);
                    db.insert(DB_TABLE_ITEM, null, cv2);
                }
            }
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
}
MainActivity.java

Код: Выделить всё

import android.app.Activity;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.app.LoaderManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.TextView;

public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor>{

    TextView tvInfo;
    Button btnTest;
    ExpandableListView elvMain;
    DB db;

    SimpleCursorTreeAdapter sctAdapter;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        db = new DB(this);

        db.open();


        Cursor groupData = db.getGroupData();

        getLoaderManager().initLoader(0, null, this);
        getLoaderManager().getLoader(0).forceLoad();

        String[] groupFrom = {db.COLUMN_TXT};
        int[] groupTo = {android.R.id.text1};

        String[] childFrom = {db.COLUMN_TXT2};
        int[] childTo = {android.R.id.text1};


         sctAdapter = new MyAdapter(this,groupData,
                android.R.layout.simple_expandable_list_item_1, groupFrom,
                groupTo, android.R.layout.simple_list_item_1, childFrom,
                childTo);

        elvMain = (ExpandableListView) findViewById(R.id.elvMain);

        elvMain.setAdapter(sctAdapter);

        tvInfo = (TextView)findViewById(R.id.tvInfo);
        btnTest = (Button)findViewById(R.id.btnTest);
        btnTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvInfo.setText(getGroupAndItemListForPrint());
            }
        });
    }
  // проверка заполнения базы
    String getGroupAndItemListForPrint(){

        StringBuilder stringBuilder = new StringBuilder();
        Cursor cursor = db.getGroupData();
        if (cursor != null){
            if (cursor.moveToFirst()){
                do {
                    stringBuilder.append(cursor.getString(cursor.getColumnIndex(db.COLUMN_ID)));
                    stringBuilder.append(" ");
                    stringBuilder.append(cursor.getString(cursor.getColumnIndex(db.COLUMN_TXT)));
                    stringBuilder.append("\n");

                    Cursor cursorItem = db.getItemData(cursor.getLong(cursor.getColumnIndex(db.COLUMN_ID)));
                    if (cursorItem !=null){
                        if (cursorItem.moveToFirst()){
                            do {
                                stringBuilder.append("   ");
                                stringBuilder.append(cursorItem.getString(cursorItem.getColumnIndex(db.COLUMN_GROUP_ID)));
                                stringBuilder.append(" ");
                                stringBuilder.append(cursorItem.getString(cursorItem.getColumnIndex(db.COLUMN_TXT2)));
                                stringBuilder.append("\n");
                            }while (cursorItem.moveToNext());
                        }
                    }

                    Log.d("log", stringBuilder.toString());
                }while (cursor.moveToNext());
            }
        }
        return stringBuilder.toString();
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        db.close();
    }

    @Override
    public android.content.Loader onCreateLoader(int id, Bundle args) {
        return new MyCursorLoader(this,db);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    }

    @Override
    public void onLoaderReset(android.content.Loader loader) {
    }


    static class MyCursorLoader extends CursorLoader{

        DB mDB;
        public MyCursorLoader(Context context, DB db) {
            super(context);
            mDB = db;
        }
        @Override
        public Cursor loadInBackground() {

            Cursor cursor = mDB.getGroupData();

            return cursor;
        }
    }


    class MyAdapter extends SimpleCursorTreeAdapter{

        public MyAdapter(Activity context, Cursor cursor, int groupLayout,
                         String[] groupFrom, int[] groupTo, int childLayout,
                         String[] childFrom, int[] childTo){
            super(context,cursor,groupLayout,groupFrom,groupTo,childLayout,childFrom,childTo);
        }

        protected Cursor getChildrenCursor(Cursor groupCursor){

            int idColumn = groupCursor.getColumnIndex(db.COLUMN_ID);
            return db.getItemData(groupCursor.getInt(idColumn));
        }
    }
}

Ответить