设置模型类和自定义适配器以从 onListItemClick 获取 SQLite DB rowID

Posted

技术标签:

【中文标题】设置模型类和自定义适配器以从 onListItemClick 获取 SQLite DB rowID【英文标题】:Setting up Model Class and Custom Adapter to get SQLite DB rowID from onListItemClick 【发布时间】:2020-06-30 23:34:39 【问题描述】:

我有一个从预先存在的 SQLite 数据库填充的应用程序。我现在需要在单击列表项时获取 rowID (_id)。我认为我没有正确设置我的应用程序以便能够做到这一点。我已经有人向我提供了要做什么的意见,但是在尝试将其应用于我的应用程序时,我似乎无法理解它。有人可以使用我的代码提供一个示例吗?我真的很感激。

这是我的模型类:

package com.mypackage.myapp.model;

import android.database.Cursor;

public class Verse 

private Cursor verseCursor;
private String verseNotificationString;
private String verseTitleString;
private int dBrowIdInt;
private String bookNameString;
private String chapterNumberString;
private String verseNumberString;
private String verseString;

public Verse(Cursor cursor, String bookNameString, String chapterNumberString, String verseNumberString, String verseString) 
    verseCursor = cursor;
    verseTitleString = bookNameString + " " + chapterNumberString + ":" + verseNumberString;
    verseNotificationString = verseString;


public Verse(int dBrowId) 
    dBrowIdInt = dBrowId;


public Cursor getVerseCursor() 
    return verseCursor;


public void setVerseCursor(Cursor verseCursor) 
    this.verseCursor = verseCursor;


public String getVerseTitleString() 
    return verseTitleString;


public String getNotificationString() 
    return verseNotificationString;


public Integer getDbRowId() 
    return dBrowIdInt;


public void setNotificationString(String notificationString) 
    this.verseNotificationString = notificationString;


public void setTitleString(String titleString) 
    this.verseTitleString = titleString;

这是我的自定义适配器:

    package com.mypackage.myapp;

    import android.content.Context;
    import android.content.SharedPreferences;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;

public class VerseAdapter extends ArrayAdapter<String> 

private Context mContext;
private int mResource1;
private int mResource2;
public List<String> mVerses;
private List<Long> mRowId;
private TextView mVerseTextView;
private TextView mVerseNumberTextView;
private TextView mRowIdTextView;
private boolean mNightModeSwitchState;
private boolean mNightModeTwoSwitchState;

public VerseAdapter(Context context, int resource1, List<String> 
verses, List<Long> rowId) 
    super(context, resource1, verses);
    this.mContext = context;
    this.mResource1 = resource1;
    this.mVerses = verses;
    this.mRowId = rowId;



@Override
public int getCount() 
    return mVerses.size();


@Override
public long getItemId(int position) 
    return (position);


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

    View listItem = convertView;
    int pos = position + 1;
    if (listItem == null) 
        listItem = 
LayoutInflater.from(mContext).inflate(mResource1, parent, false);
    

    //mRowIdTextView = (TextView) 
listItem.findViewById(R.id.rowId);
//mRowIdTextView.setText(String.valueOf(getItemId(position)));
    //mRowIdTextView.setText(String.valueOf(mRowId.get(position)));

    mVerseNumberTextView = (TextView) 
listItem.findViewById(R.id.verseNumber);
    mVerseNumberTextView.setText(String.valueOf(pos) + " ");

    mVerseTextView = (TextView) 
listItem.findViewById(R.id.verseWords);
    mVerseTextView.setText(mVerses.get(position));

    SharedPreferences nightModeSwitchState = 
getContext().getSharedPreferences("SettingsActivity", 0);
    mNightModeSwitchState = 
nightModeSwitchState.getBoolean("NightModeSwitchState", false);

    SharedPreferences rowPosition = 
getContext().getSharedPreferences("RowPosition", 0);
    rowPosition.edit().putInt("RowPositionSqlite", 
position).apply();

    return listItem;

这是我需要从中访问 rowID 的类中的 onListItemClick 方法(您可以看到一些我尝试过但没有工作的东西被注释掉了):

mListView.setOnItemClickListener(new 
AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> adapterView, View 
view, int position, long id) 

            String selected = (String) 
mListView.getItemAtPosition(position);
            mVerseTextView = findViewById(R.id.verseWords);
            mVerseNumberTextView = findViewById(R.id.verseNumber);

            mAdapterView = adapterView;
            mPositionForRow = position;
            //mIdLong = id;
            // VerseAdapter verseAdapter = (VerseAdapter) 
adapterView.getAdapter();
            // mSelectedVerse = (VerseForId) 
mListView.getItemAtPosition(position);
            // mDbRowId = mSelectedVerse.getDbRowId();

            //  mIdLong = verseAdapter.getItemId(position);

            //  mRowIdString = String.valueOf(id);

            // VerseAdapter da = (VerseAdapter) 
    adapterView.getAdapter();
            //mRowIdString = 
    String.valueOf(da.mVerses.get(position).getId());
            // Toast.makeText(BibleBookVersesOldTestActivity.this, 
    mRowIdString + " id", Toast.LENGTH_LONG).show();

            mBookCopied = 
mVerseHeaderBookNameTextView.getText().toString();
            mChapterNumberCopied = 
Integer.toString(mChapterSelected + 1);
            mVerseNumberCopied = 
mVerseNumberTextView.getText().toString();
            mPosition = position + 1;
            mCopiedVerseListItem = mBookCopied + " " + 
mChapterNumberCopied + ":" + mPosition + "\n\n" + selected;

            showMenuVerseAction(view);
        
    );

我知道我需要在我的模型类和自定义适配器中进行一些设置,以便能够检索数据库 rowID onlistitemclick。有人可以给我一个使用我的代码的例子吗?感谢您的帮助。

*******Addition.... 这是我的 Databaseaccess 课程.... 其中一部分是我从 SQLite 数据库中的某本书中提取诗句的地方。我已经调整了填充列表的另一个类,因此必须更改以下操作以接收模型类 Verse 而不是列表中的 String ......我遇到的问题是下面的行读取 list.add(cursor .getString(6)) 其中 (6) 指的是从何处拉出诗句的列索引...给出了一个错误,我无法将该 getString 应用于 Verse...我该如何解决这个问题?

public List<Verse> getVersesChapterOne() 
    List<Verse> list = new ArrayList<>();
    Cursor cursor = database.rawQuery("SELECT * FROM bookcombinedfull 
LIMIT 31", null);
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) 
        list.add(cursor.getString(6));
        cursor.moveToNext();
    
    cursor.close();
    return list;

【问题讨论】:

【参考方案1】:

一个想法是将自定义适配器的列表从String 替换为您的模型Verse。通过这种方式,您可以使用.getItem() 从模型类中检索您想要的任何信息。

// public class VerseAdapter extends ArrayAdapter<String> 
public class VerseAdapter extends BaseAdapter 

  public List<String> mVerses;

  // public VerseAdapter(Context context, int resource1, List<String> verses, List<Long> rowId) 
  public VerseAdapter(Context context, int resource1, List<Verse> verses) 
    //...
    mVerses = verses;
    //...

  @Override
  public Object getItem(int i) 
    return (Verse)mList.get(i);
  

// ...
// In your MainActivity.java, do this to get your item:

Verse verse = (Verse) mAdapter.getItem(position);
Log.d(TAG, verse.getVerseTitleString());

【讨论】:

非常感谢 lurker0152。我已经开始进行调整,但现在基于这些更改出现了一个新错误......我已经编辑了我的问题..你能看看它并告诉我你的想法吗?感谢您对此的帮助。这对我来说已经有一段时间了。 发布您的 logcat 详细信息。使用 Log.d() 转储 cursor.getString(x) 的内容。更改 x 值。你期待预期的结果吗?你会在那里找到答案。 再次感谢潜伏者。我的意思是说它在运行之前给出了错误。它用红色突出显示该项目,当我将鼠标悬停在它上面时,它说:列表中的 add(mode.verse) 不能应用于 (java.lang.String)。我认为这与 x 值无关。它不允许我在那里结合 Verse 和 String。 list.add(cursor.getString(6)); 失败,因为list 被声明为List&lt;Verse&gt; list = new ArrayList&lt;&gt;();,意在存储对象列表。要存储字符串列表,请更改为 List&lt;String&gt; list = new ArrayList&lt;&gt;();

以上是关于设置模型类和自定义适配器以从 onListItemClick 获取 SQLite DB rowID的主要内容,如果未能解决你的问题,请参考以下文章

如何将对象类和自定义属性添加到 LDIF 文件?

在 Android 中使用 SearchableSpinner 和自定义适配器

ListView 和自定义适配器在 Kotlin 中不起作用

如何在列表适配器中正确使用 ViewHolder 和自定义视图

ListView 从 EditText 更新

带有复选框和自定义适配器的 ListView,片段无法正常工作