Невозможно отобразить элементы в listView (с использованием ResourceCursorAdapter и SQLite)

Я новичок в Android, извините, если основной вопрос

я пытаюсь заполнить listView из SQLite, используя курсор, заполненный данными из адаптера (класс, который наследуется от ResourceCursorAdapter).

Я прочитал и попробовал несколько примеров, но не могу заставить listView показывать какую-либо строку.

что я вижу при отладке, так это то, что метод «bindView» «PedidosAdapter» (производный от ResourceCursorAdapter) НИКОГДА не вызывается ... не уверен, почему.

может кто-нибудь помочь мне решить это?

что я делаю: - я создал таблицу с полем _id (иначе ошибка) - я получил основную активность от listActivity и активности, и на обоих ничего не отображается...

Я загрузил тестовый код на https://www.dropbox.com/s/g1dlff4esafgeiy/PedidosLH.zip, если хотите проверить это напрямую, не читая вставленный здесь код...

LAYOUT -- "activity_main.xml"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.i4.pedidoslh.MainActivity">

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/list_view" />

</LinearLayout>

Код основной активности:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        PedidosSQLiteHelper pdb =
                new PedidosSQLiteHelper(this, PedidosSQLiteHelper.DATABASE_NAME, null, 1);

        SQLiteDatabase db = pdb.getWritableDatabase();
        // Generate example data...
        if(db != null)
        {
            //Insertamos 5 usuarios de ejemplo
            for(int i=1; i<=5; i++)
            {
                //Generamos los datos de prueba
                int cod_mov_cc = i;
                int nr_comprob = 10000+i;
                int nro_clie = 5000+i;

                //Insertamos los datos en la tabla ENCPEDID
                db.execSQL(
                        "INSERT INTO " + PedidosSQLiteHelper.TABLE_ENCPEDID + " ("
                                + PedidosSQLiteHelper.KEY_ENCPEDID_COD_MOV_CC + ", "
                                + PedidosSQLiteHelper.KEY_ENCPEDID_NR_COMPROB + ", "
                                + PedidosSQLiteHelper.KEY_ENCPEDID_NRO_CLIE + ") " +
                        "VALUES (" + cod_mov_cc + "," + nr_comprob + "," + nro_clie + ")");

                db.execSQL(
                        "INSERT INTO " + PedidosSQLiteHelper.TABLE_ITMPEDID + " ("
                                + PedidosSQLiteHelper.KEY_ITMPEDID_NRO_ITEM + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_COD_MOV_CC + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_NR_COMPROB + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_COD_PROD + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_CANTIDAD + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_PENDIENTE + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_PORC_CUMPL + ", "
                                + PedidosSQLiteHelper.KEY_ITMPEDID_DESCRIP + ") " +
                        "VALUES ("
                                + i + ","
                                + cod_mov_cc + ","
                                + nr_comprob + ",'"
                                + "prd" + i + "',"
                                + i + ","
                                + i + ","
                                + "0" + ","
                                + "'" + "desc" + i + "'" + ")");
            }

            //Cerramos la base de datos
            db.close();
        } // db != null

        fillData();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {      ...     }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) { ... }

    private void fillData() {

        PedidosSQLiteHelper pdb =
                new PedidosSQLiteHelper(this, PedidosSQLiteHelper.DATABASE_NAME, null, 1);

        SQLiteDatabase db = pdb.getReadableDatabase();

        String sql = "SELECT _id, cod_mov_cc, nr_comprob FROM ENCPEDID";
        Cursor c = db.rawQuery(sql, null);

        if (c.getCount() == 0) android.util.Log.w("deb", "fillData COUNT = 0");
        startManagingCursor(c);

        // ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.id.listPessoas, PESSOAS);
        PedidosAdapter pa = new PedidosAdapter(MainActivity.this, c);

        ListView lv = (ListView) findViewById(R.id.list_view);
        lv.setAdapter(pa); // setListAdapter(pa) if listActivity...

        stopManagingCursor(c);
        c.close();
    }

    private class PedidosAdapter extends ResourceCursorAdapter {

        public PedidosAdapter(Context context, Cursor cur) {
            super(context, R.layout.row_pedidos, cur);
            //mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View newView(Context context, Cursor cur, ViewGroup parent) {
            LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            return li.inflate(R.layout.row_pedidos, parent, false);
            //View item = mInflater.inflate(R.layout.row_pedidos, null);
        }

        @Override // this method is never called!!
        public void bindView(View view, Context context, Cursor cur) {

            TextView txtPedido = (TextView) view.findViewById(R.id.txtPedido);
            TextView txtCliente = (TextView) view.findViewById(R.id.txtCliente);
            //CheckBox cbListCheck = (CheckBox) view.findViewById(R.id.list_checkbox);

            txtPedido.setText(
                    cur.getString(cur.getColumnIndex("PEDIDO")));

            txtCliente.setText(
                    cur.getString(cur.getColumnIndex(PedidosSQLiteHelper.KEY_ENCPEDID_NRO_CLIE)));

            //cbListCheck.setChecked((cur.getInt(cur.getColumnIndex(Datenbank.DB_STATE))==0?     false:true))));

            //String idname = cur.getString(cur.getColumnIndex("_id"));
            //view.setTag(idname);

        } // bindView
    } // adapter
} // class

row_pedidos.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- android:textColor="@android:color/primary_text_dark" -->
    <TextView android:text="Mensaje principal"
        android:id="@+id/txtPedido"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="@android:style/TextAppearance.Large"
        android:layout_marginTop="5dp"
        />

    <!-- android:textColor="@android:color/secondary_text_dark" -->
    <TextView android:text="mensaje debajo"
        android:id="@+id/txtCliente"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="@android:style/TextAppearance.Small"
        android:singleLine="true"
        android:ellipsize="end"
        android:layout_marginBottom="5dp" />
</LinearLayout>

person FabianSilva    schedule 08.02.2014    source источник


Ответы (1)


Удалите эти строки из fillData():

stopManagingCursor(c);
c.close();

После передачи курсора в ResourceCursorAdapater этот курсор должен оставаться открытым, поскольку именно из него адаптер считывает данные для создания своих представлений при прокрутке списка. Если вы закроете его, он станет недействительным, и у адаптера больше не будет никаких данных для отображения, поэтому ваш ListView будет пустым.

Вызов startManagingCursor позволяет активности позаботиться об управлении жизненным циклом курсора на основе жизненного цикла активности. Если ваша активность остановлена, она автоматически вызовет для нее deactivate(), если ваша активность будет перезапущена, она вызовет для вас requery(), а когда ваша активность будет уничтожена, она будет закрыта для вас. Таким образом, вам не нужны эти две строки кода, потому что система позаботится обо всем этом за вас.

person NigelK    schedule 09.02.2014
comment
вы не знаете, как я безуспешно пытался заставить его работать, никогда не думал, что курсор нужно открывать во время жизненного цикла активности, я не понял, как работает адаптер, не читая слишком много документации об этом, потому что обычно в настольных приложениях приходится получить данные, сохранить в памяти и закрыть соединение... - person FabianSilva; 10.02.2014
comment
БОЛЬШОЕ спасибо за ответ и за то, что рассказали мне о том, что я сделал ОЧЕНЬ неправильно, я боролся с этим более 3 дней. Если вы можете злоупотребить вашей помощью, и вы можете порекомендовать мне какую-нибудь книгу для чтения о программировании для Android, я буду очень признателен: D еще раз спасибо. - person FabianSilva; 10.02.2014
comment
Пожалуйста. То, что вы сделали, не было чем-то неправильным, просто ошибка/недоразумение, и мы все делаем это. Я лично прочитал «Профессиональная разработка приложений для Android 4» Рето Мейера в качестве отправной точки, но имейте в виду, что некоторый контент устаревает. Книг много — ищите на Амазоне, читайте отзывы и выбирайте… - person NigelK; 10.02.2014