【问题标题】:Custom listview with empty arraylist带有空数组列表的自定义列表视图
【发布时间】:2015-03-29 00:38:18
【问题描述】:

带有图像和两个文本视图的列表视图。如果没有要打印或显示的对象,它会在我第一次进入时崩溃。如果arraylist为空,它不能得到一个空白的listview。

public contactoAdapter(Context context, ArrayList<contactoAgenda> datos) {
                super(context, R.layout.listview_item, datos);
                // Guardamos los par�metros en variables de clase.
                this.context = context;
                this.datos = datos;
            }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View item = convertView; 
            contactoHolder holder;

            if (item == null) {
                item = LayoutInflater.from(context).inflate(R.layout.listview_item,
                        null);

                holder = new contactoHolder();
                holder.imgContacto = (ImageView) item.findViewById(R.id.imagenContacto);
                holder.tvMail = (TextView) item.findViewById(R.id.tvMail);
                holder.tvNombre = (TextView) item.findViewById(R.id.tvNombre);

                // Almacenamos el holder en el Tag de la vista.
                item.setTag(holder);
            }

            holder = (contactoHolder) item.getTag();

           holder.imgContacto.setImageResource(datos.get(position).getDrawableImageID());

            holder.tvNombre.setText(datos.get(position).getNombre());
            holder.tvMail.setText(datos.get(position).getDireccion());


            return item;
        }

我用一张表中的所有联系人填充数组列表。所以第一次表格是空的,直到你填写一些联系人。

public ArrayList<contactoAgenda> recuperarTodosContactos() {
        SQLiteDatabase db = getReadableDatabase();
        ArrayList<contactoAgenda> lista_contactos = new ArrayList<contactoAgenda>();
        String[] valores_recuperar = {"nombre","direccion","telefono","email","miembrofacebook","miembrotwitter","miembrogoogle","miembrolinkedin","sexo","tipocontacto","imagen"};
        Cursor c = db.query("contactos", valores_recuperar, null, null, null, null, null, null);
        c.moveToFirst();
        do {
            contactoAgenda contactos = new contactoAgenda(c.getString(0), c.getString(1), c.getString(2), c.getString(3),c.getInt(4), c.getInt(5), c.getInt(6), c.getInt(7),c.getInt(8), c.getString(9), c.getInt(10));
            lista_contactos.add(contactos);
        } while (c.moveToNext());


        db.close();
        c.close();
        return lista_contactos;
    }

我把它叫做使用全局变量,重要的是我得到一个联系人数组列表来显示在你的适配器中。除了特定的情况外,每种情况都可以正常工作。第一次arraylist 为空。我尝试了一个包含联系人的列表视图并将其删除,我可以将列表视图变为空白......不知道原因。如果arraylist为空,它必须显示一个空白的listview:

AgendaGlobal.getInstance().miAgenda = BaseDatosGlobal.getInstance(this).agendaBaseDatos.recuperarTodosContactos();

                Toast.makeText(getApplicationContext(),"Hasta aqui ya no", Toast.LENGTH_LONG).show();

                adapter = new contactoAdapter(this, AgendaGlobal.getInstance().miAgenda);

                lvContactos = (ListView) findViewById(R.id.lvItems);
                // Asignamos el Adapter al ListView, en este punto hacemos que el
                // ListView muestre los datos que queremos.


                lvContactos.setAdapter(adapter);

logcat:请注意,在我在全局变量中有一个数组列表之前,同样的事情发生了……如果我得到一个包含空数据的数组列表,它就会崩溃。 Not 仅与数据库相关。

01-29 18:53:43.425: E/AndroidRuntime(1712): FATAL EXCEPTION: main
01-29 18:53:43.425: E/AndroidRuntime(1712): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.informacion/com.example.informacion.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.os.Looper.loop(Looper.java:137)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread.main(ActivityThread.java:4424)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at java.lang.reflect.Method.invokeNative(Native Method)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at java.lang.reflect.Method.invoke(Method.java:511)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at dalvik.system.NativeStart.main(Native Method)
01-29 18:53:43.425: E/AndroidRuntime(1712): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:400)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at com.example.informacion.BaseDatosContactos.recuperarTodosContactos(BaseDatosContactos.java:295)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at com.example.informacion.MainActivity.onCreate(MainActivity.java:68)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.Activity.performCreate(Activity.java:4465)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
01-29 18:53:43.425: E/AndroidRuntime(1712):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
01-29 18:53:43.425: E/AndroidRuntime(1712):     ... 11 more

【问题讨论】:

  • 你能发布你的 logcat 吗?
  • 假设就足够了:01-29 18:53:43.425: E/AndroidRuntime(1712): FATAL EXCEPTION: main 01-29 18:53:43.425: E/AndroidRuntime(1712): java. lang.RuntimeException:无法启动活动 ComponentInfo{com.example.informacion/com.example.informacion.MainActivity}:android.database.CursorIndexOutOfBoundsException:请求索引 0,大小为 0
  • 看我的回答,第4点修复那个错误

标签: android sqlite listview arraylist android-arrayadapter


【解决方案1】:

不确定问题是什么,你放在那里的代码没有显示问题,但有些事情可能会有所不同:

  1. 从 BaseAdapter 扩展您的适配器,您不需要在构造函数中调用 super()。
  2. 您应该覆盖适配器中的 getCount()、getItem(int position) 和 getItemId(int position)。这很重要,getCount() 方法告诉 getView() 它将被调用多少次,如果您的列表为空,则 getView() 将永远不会被调用。在你的情况下应该是这样的:

    @Override
    public int getCount() {
        return datos.size();
    }
    
    @Override
    public String getItem(int position) {
        return datos.get(position);
    }
    
    @Override
    public long getItemId(int position) {
        return position;
    }
    
  3. 这与您的问题无关,但这是一个很好的做法:直接使用 View convertView 而不是创建新的 View 项,这样很好,但是您正在使用内存来实例化您不使用的新项不需要。

  4. 这是一个最重要的建议:当您从数据库加载游标时,在进行循环之前要求 getCount() > 0。像这样的:

    Cursor c = db.query("contactos", valores_recuperar, null, null, null, null, null, null);
    
    if (c.getCount() > 0) {
        c.moveToFirst();
        while (cursor.moveToNext()) {
            contactoAgenda contactos = new contactoAgenda(c.getString(0), c.getString(1), c.getString(2), c.getString(3),c.getInt(4), c.getInt(5), c.getInt(6), c.getInt(7),c.getInt(8), c.getString(9), c.getInt(10));
            lista_contactos.add(contactos);
        }
    }
    c.close();
    

不知道这是否对您有帮助,但请看一下。如果您发布更多信息(logcat,更多代码),我们可以准确找到问题。希望对你有帮助

编辑:

好的,你粘贴的 logcat 错误在这一行: com.example.informacion.BaseDatosContactos.recuperarTodosContactos(BaseDatosContactos.java:295)

并且是 CursorOutOfBounds 错误,此答案的第 4 点应修复该错误。问题是您正在尝试创建一个循环,并且您正在向空游标询问项目,这就是为什么我告诉您,当您在游标上循环时要求计数高于 0,因此你放在那里的问题解决方案是替换你在recuperarContactos中的代码:

    Cursor c = db.query("contactos", valores_recuperar, null, null, null, null, null, null);

    if (c.getCount() > 0) {
        c.moveToFirst();
        while (cursor.moveToNext()) {
            contactoAgenda contactos = new contactoAgenda(c.getString(0), c.getString(1), c.getString(2), c.getString(3),c.getInt(4), c.getInt(5), c.getInt(6), c.getInt(7),c.getInt(8), c.getString(9), c.getInt(10));
            lista_contactos.add(contactos);
        }
    }
    c.close();

【讨论】:

  • 好吧,看看它...假设错误来自适配器中的获取视图...如果我传递一个空的数组列表,那么它会崩溃...令人惊讶的是,如果我放置一些联系人并输入listview,如果我删除联系人直到 0,它会出现一个空白的 listview....但是第一次它不能从一个空的 arraylist 生成一个空白的 listview...也许一个空数组发送空指针或者我可以得到它的东西
  • 有什么想法吗?我粘贴了一个 logcat,但我认为问题出在适配器中,当我传递一个空的 arraylist 时会崩溃。
  • 你得到的错误是一样的吗?您粘贴的 logcat 中的该错误与在空光标上进行循环有关,如果您更改该错误应该是另一个错误。您可以将一个空数组传递给适配器(空而不是空!!)并且适配器将正常工作,当调用 getCount() 时将返回 0,因此永远不会调用 getView。检查您得到的错误是否相同,如果没有显示 logcat 和适配器的完整代码。
【解决方案2】:

示例:在 rellenarArrayList 中,我必须在 miAgenda 中放置一些联系人,这是 contactoAgenda 的 ArrayList。如果 arraylist 为空,则适配器崩溃。所以你的笔记在 sqlite 案例中很有用,但不是这里的问题..我猜

rellenarArrayList();


                adapter = new contactoAdapter(this, AgendaGlobal.getInstance().miAgenda);

                lvContactos = (ListView) findViewById(R.id.lvItems);
                // Asignamos el Adapter al ListView, en este punto hacemos que el
                // ListView muestre los datos que queremos.


                lvContactos.setAdapter(adapter);
                // Asignamos el Listener al ListView para cuando pulsamos sobre uno de
                // sus items.

以防万一这里又是自定义列表视图的适配器。

public contactoAdapter(Context context, ArrayList<contactoAgenda> datos) {
                super(context, R.layout.listview_item, datos);
                // Guardamos los par�metros en variables de clase.
                this.context = context;
                this.datos = datos;
            }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View item = convertView; 
            contactoHolder holder;

            if (item == null) {
                item = LayoutInflater.from(context).inflate(R.layout.listview_item,
                        null);

                holder = new contactoHolder();
                holder.imgContacto = (ImageView) item.findViewById(R.id.imagenContacto);
                holder.tvMail = (TextView) item.findViewById(R.id.tvMail);
                holder.tvNombre = (TextView) item.findViewById(R.id.tvNombre);

                // Almacenamos el holder en el Tag de la vista.
                item.setTag(holder);
            }

            holder = (contactoHolder) item.getTag();

           holder.imgContacto.setImageResource(datos.get(position).getDrawableImageID());

            holder.tvNombre.setText(datos.get(position).getNombre());
            holder.tvMail.setText(datos.get(position).getDireccion());


            return item;
        }

【讨论】:

  • 你确定 AgendaGlobal.getInstance().miAgenda 是一个空数组列表而不是 null 吗??
  • 编辑了答案看看,让我知道它是否有效,如果没有,则需要更多有关错误的数据,但是您粘贴的 logcat 中的那个应该通过我放入的更改来修复回答。
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多