我看不到添加到我的 ListView 的第一个项目

Posted

技术标签:

【中文标题】我看不到添加到我的 ListView 的第一个项目【英文标题】:I can't see the first item added to my ListView 【发布时间】:2018-06-09 02:48:36 【问题描述】:

我有一个使用 OpenSQLiteHelper 制作的数据库,我从中获取一串名称并将其添加到 ListView。我永远看不到数据库中的第一项,而 ListView 仅从数据库中的第二项开始。

我正在从我的数据库中的 COL_2(名称)获取字符串。

ListView 类

public class Castawaylist extends AppCompatActivity 

private static final String TAG = "CastList";
myDbAdapter mydb;
private ListView castview;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_castawaylist);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();

        
    );

    castview = (ListView) findViewById(R.id.listView);
    mydb = new myDbAdapter(this);

    populateCastList();



String score;

private void populateCastList()

    //get the data and append to the list
    Log.d(TAG, "populateCastList: Displaying List of Castaways.");
    Cursor data = mydb.getData();
    //int save = data.getInt(2);

    ArrayList<String> listData = new ArrayList<>();


    while(data.moveToNext())
    
        listData.add(data.getString(1) +
                "                                                                                                  " + data.getInt(2)); //get value from database at column 1, then add it to array list
    



    ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData); //Creates the list adapter and set it
    castview.setAdapter(adapter);




    castview.setOnItemClickListener(new AdapterView.OnItemClickListener() 

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 


            String nametest = "";
            int u = 0;


                while(!adapterView.getItemAtPosition(i).toString().substring(u,u+1).equals(" "))
                
                    nametest = nametest + adapterView.getItemAtPosition(i).toString().substring(u, u+1);
                    u = u + 1;
                



            Log.d(TAG, "onItemClick: You Clicked on " + nametest);

            Cursor data = mydb.getItemID(nametest); //Get the ID associated with that name
            int itemID = -1;
            while(data.moveToNext())
            
                itemID = data.getInt(0);
            
            if(itemID > -1)
            
                Log.d(TAG, "onItemClick: The ID is: " + itemID);
                Intent editCastaway = new Intent(Castawaylist.this, EditCastaway.class);
                editCastaway.putExtra("id", itemID);
                editCastaway.putExtra("name", nametest);
                //editCastaway.putExtra("score", data.getInt(2));
                startActivity(editCastaway);
            else
            
                toastText("No ID associated with that name");
            
        


    );




private void toastText(String text)

    Toast.makeText(this,text, Toast.LENGTH_SHORT).show();

ListView XML 代码

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

<ListView
    android:layout_
    android:layout_
    android:id="@+id/listView"/>
</LinearLayout>

数据库助手类

public class myDbAdapter extends SQLiteOpenHelper


public static final String DATABASE_NAME = "Castaways.db";
public static final String TABLE_NAME = "Survivor_Table";
public static final String COL_1 = "ID";
public static final String COL_2 = "NAME";
public static final String COL_3 = "MARK";

public myDbAdapter(Context context) 
    super(context, DATABASE_NAME, null, 2);


@Override
public void onCreate(SQLiteDatabase db) 
    db.execSQL("create table " + TABLE_NAME +" (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,MARK INTEGER)");


@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
    onCreate(db);


public boolean addData(String name,int score) 
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_2,name);
    contentValues.put(COL_3,score);
    long result = db.insert(TABLE_NAME,null ,contentValues);
    if(result == -1)
        return false;
    else
        return true;


public Cursor getData() 
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
    return res;


public Cursor getItemID(String name)
    SQLiteDatabase db = this.getWritableDatabase();
    String query = "SELECT " + COL_1 + " FROM " + TABLE_NAME +
            " WHERE " + COL_2 + " = '" + name + "'";
    Cursor data = db.rawQuery(query, null);
    return data;



public boolean updateData(String id,String name,String surname,int score) 
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_1,id);
    contentValues.put(COL_2,name);
    contentValues.put(COL_3,score);
    db.update(TABLE_NAME, contentValues, "ID = ?",new String[]  id );
    return true;


public void updateName(String newName, int id, String oldName)
    SQLiteDatabase db = this.getWritableDatabase();
    String query = "UPDATE " + TABLE_NAME + " SET " + COL_2 +
            " = '" + newName + "' WHERE " + COL_1 + " = '" + id + "'" +
            " AND " + COL_2 + " = '" + oldName + "'";
    Log.d(TAG, "updateName: query: " + query);
    Log.d(TAG, "updateName: Setting name to " + newName);
    db.execSQL(query);



public Integer deleteData(String id) 
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete(TABLE_NAME, "ID = ?",new String[] id);


public void deleteName(int id, String name)
    SQLiteDatabase db = this.getWritableDatabase();
    String query = "DELETE FROM " + TABLE_NAME + " WHERE "
            + COL_1 + " = '" + id + "'" +
            " AND " + COL_2 + " = '" + name + "'";
    Log.d(TAG, "deleteName: query: " + query);
    Log.d(TAG, "deleteName: Deleting " + name + " from database.");
    db.execSQL(query);


public void updateScore(int newScore, int id, int oldScore)
    SQLiteDatabase db = this.getWritableDatabase();
    String query = "UPDATE " + TABLE_NAME + " SET " + COL_3 +
            " = '" + newScore + "' WHERE " + COL_1 + " = '" + id + "'" +
            " AND " + COL_3 + " = '" + oldScore + "'";
    Log.d(TAG, "updateName: query: " + query);
    Log.d(TAG, "updateName: Setting name to " + newScore);
    db.execSQL(query);


public void clearData()

    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_NAME,null,null);
    db.close();

感谢您的帮助!

【问题讨论】:

你怎么知道有一行你没有看到? 【参考方案1】:

不确定,但问题似乎在这里: 而(数据。moveToNext()) 可能是 moveToNext() 在离开前一个项目后移动到下一个项目时触发,换句话说,它将在离开项目 #1 后第一次触发) 尝试使用索引循环代替。即for (int i=0; ....

【讨论】:

【参考方案2】:

在这段代码中:

while(data.moveToNext())

   itemID = data.getInt(0);

它将触发 moveToNext() 函数,然后执行 while。所以你可以使用 do while 来解决它

do
   itemID = data.getInt(0);
while(data.moveToNext())

【讨论】:

我也试过了,但出现运行时异常原因:android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 6【参考方案3】:

在我使用光标的研究中,您的初始设置是正确的

while(data.moveToNext())...

光标在行之前开始,初始调用 moveToNext() 将其移动到第一行。

一个明显的问题是您没有关闭光标。

while(data.moveToNext())

    listData.add(data.getString(1) +
            "                                                                                                  " + data.getInt(2)); //get value from database at column 1, then add it to array list

// Close the Cursor here and again after the second one you create
data.close();

我看到的第二个潜在问题是您没有在 onClick 中访问正确的值

// int i might not be 0 at some point
@Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
i--;// maybe try subtracting 1 from i. Alternative is to do that when i is being used
        String nametest = "";
        int u = 0;


      // or subtract here         
while(!adapterView.getItemAtPosition(i-1).toString().substring(u,u+1).equals(" "))
            
                nametest = nametest + adapterView.getItemAtPosition(i-1).toString().substring(u, u+1);
                u = u + 1;
            

【讨论】:

我试过这个并得到一个致命的运行时异常原因:android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 6 在文档中,您可以查找几种不同类型的内容,但如果您遇到 IndexOutOfBoundsException,您可能需要尝试使用其他内容,例如 !data.isLast()。或者您可以在进入while循环之前确保光标位于第一个位置 data.moveToFirst() 嗨,我也试过了,但它仍然给我异常错误,但我注意到我的数据库中有 6 项我正试图放入列表中。当我再添加一个错误更改为 Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 7. 它实际上是添加所有项目还是不添加?使用带有断点的调试检查 listData.add(); 您可能需要尝试使用计数器而不是位置。

以上是关于我看不到添加到我的 ListView 的第一个项目的主要内容,如果未能解决你的问题,请参考以下文章

C# listView,如何将项目添加到第 2、3 和 4 列等?

在 android 中将按钮添加到我的 ListView 后,我的 onitemclick 不起作用?

添加项目后划分Listview

如何在 Flutter 中将 Hero 动画添加到我的 ListView?

Listview 替换第一个项目而不是创建新项目

将项目动态附加到 ListView