将两个 SQL 列加载到列表视图中但只需要显示第一列 Android
Posted
技术标签:
【中文标题】将两个 SQL 列加载到列表视图中但只需要显示第一列 Android【英文标题】:Loading two SQL columns into a listview but only need to display the first column Android 【发布时间】:2019-08-18 16:30:55 【问题描述】:我正在使用 sqllite 数据库来存储电话名称和电话号码两列。我正在使用 arrayList 遍历数据并在正在工作的列表视图中显示电话名称,但我还需要遍历同一列表视图下的电话号码列。我只需要在列表视图中显示电话名称。
这是因为当用户在列表视图中选择了项目时,它会显示所选的电话名称和电话号码,目前它仅显示电话名称并且出于明显的原因显示为空白的电话号码。
DataDBAdapter
public long insert(String phonename, String phonenumber)
ContentValues cv = new ContentValues();
cv.put(COl_MYTABLE_PHONENAME,phonename);
cv.put(COL_MYTABLE_PHONENUMBER,phonenumber);
return mDB.insert(TBL_MYTABLE,null,cv);
//---------------------------------------------------------------------------
// Iterating through the database
//---------------------------------------------------------------------------
public ArrayList<String> getAllRowsAsList()
Cursor csr = mDB.query(TBL_MYTABLE,null,null,null,null,null,null);
ArrayList<String> rv = new ArrayList<>();
while (csr.moveToNext())
rv.add(csr.getString(csr.getColumnIndex(COl_MYTABLE_PHONENAME)));
return rv;
选择调制解调器片段
private void manageListView(Context context)
thelist = dbHelper.getAllRowsAsList(); // Extract the list, just the phone names
// Only setup the adapter and the ListView if the adapter hasn't been setup
if(arrayAdapter == null)
// Instantiate the adapter
arrayAdapter = new ArrayAdapter<>(context,android.R.layout.simple_list_item_1,thelist); //<<<<<<<<<< list included
display_contacts1.setAdapter(arrayAdapter); //<<<<<<<<<< Tie the adpater to the ListView
// Set the ListViews OnItemClick Listener
display_contacts1.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
String namedisplay = arrayAdapter.getItem(position); //<<<<<<<<<< this gets the phone name
namedisplay = arrayAdapter.getItem(position);
Toast.makeText(view.getContext(), namedisplay + " Selected for Communication", Toast.LENGTH_SHORT).show();
Toast.makeText(view.getContext(), phoneNo, Toast.LENGTH_SHORT).show();
);
【问题讨论】:
【参考方案1】:问题
使用 ArrayAdapter 只允许传递单个项目,因此除非您使用复杂/杂乱/低效的方法,否则 ArrayAdapter 仅适用于单个值。
修复
您可以使用 ArrayList,其中 your_object 具有所有必需值的成员。即电话号码和电话名称。请注意,除非您使用自定义适配器,否则您应该重写 toString 方法来提取要显示的数据,因为这是标准 ArrayAdapter 使用的。
替代方案(使用 CursorAdapter)
另一种方法是使用光标适配器(例如 SimpleCursorAdapter),然后您可以返回光标并直接使用它。但是,CursorAdapter 需要一个专门命名为 _id 的列(可以使用 BaseColumns._ID)。
Cursor 适配器的一个明显优势是传递给 onItemClick/onItemLongClick 的第四个参数是行的 id(如果使用正确)允许单个值随后获取/更新/删除/传递相应的选定行。
因此,我建议为 ListView 使用 Cursor Adapter,从而获得更全面的答案。你可能认为我没有这样的专栏。但是,您可以使用通常隐藏的 rowid 列并动态创建名为 _id 的列。
您可以在数据库助手 (DataDBAdapter) 中有一个方法,例如:-
public Cursor getAllRowsAsCursor()
String[] columns = new String[]"rowid AS " + BaseColumns._ID,"*"
return = mDB.query(TBL_MYTABLE,null,null,null,null,null,null)
ManageList 方法可以是:-
private void manageListView(Context context)
myCursor = dbhelper.getAllRowsAsCursor();
// Only setup the adapter and the ListView if the adapter hasn't been setup
if(arrayAdapter == null)
// Instantiate the adapter
arrayAdapter = new SimpleCursorAdapter(context,android.R.layout.simple_list_item_1,myCursor,new String[]DataAdapter.COl_MYTABLE_PHONENAME,newint[]android.R.id.text1,0);
display_contacts1.setAdapter(arrayAdapter); //<<<<<<<<<< Tie the adpater to the ListView
// Set the ListViews OnItemClick Listener
display_contacts1.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
String namedisplay = arrayAdapter.getItem(position); //<<<<<<<<<< this gets the phone name
String phonenumber = myCursor,getString(myCursor.getColumnIndex(DataAdapter.COL_MYTABLE_PHONENUMBER);
Toast.makeText(view.getContext(), namedisplay + " Selected for Communication", Toast.LENGTH_SHORT).show();
Toast.makeText(view.getContext(), phonenumber, Toast.LENGTH_SHORT).show();
);
else
arrayAdapter.swapCursor(myCursor);
注意事项
MyCursor 将被声明为类变量,例如Cursor MyCursor;
代替
ArrayAdapter<String> arrayAdapter;
你会有
SimpleCursorAdapter arrayAdapter;
以上为原理代码,未经测试,可能存在错误和/或遗漏。
工作示例
以下是基于上一个问题中的代码的代码(这似乎是后续问题)。它有两个旧的 ListView 和一个使用 SimpleCursorAdapter 的新 ListView。单击项目会显示电话号码和 ID。 Lon 单击一个项目会删除该项目(刷新两个 ListView)。
DataDBAdapter.java 有两个新方法(所以添加这些):-
//<<<<<<<<<< ADDED
public Cursor getAllRowsAsCursor()
return mDB.query(TBL_MYTABLE,null,null,null,null,null,null);
public int delete(long id)
String whereclause = COL_MYTABLE_ID + "=?";
String[] whereargs = new String[]String.valueOf(id);
return mDB.delete(TBL_MYTABLE,whereclause,whereargs);
SelectModemFragment.java 现在是:-
public class SelectModemFragment extends Fragment
private SelectModemViewModel mViewModel;
ListView display_contacts1;
ArrayAdapter<String> arrayAdapter;
ArrayList<String> thelist;
DataDBAdapter dbhelper;
//<<<<<<<<<< ADDED
ListView display_contacts2;
SimpleCursorAdapter sca;
Cursor MyCursor;
public static SelectModemFragment newInstance()
return new SelectModemFragment();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.select_modem_fragment, container, false);
display_contacts1 = view.findViewById(R.id.lv001); //<<<<<<<<<< top listview ArrayAdapter<String>
display_contacts2 = view.findViewById(R.id.lv002);
dbhelper = new DataDBAdapter(view.getContext());
AddSomeData();
manageListView(view.getContext());
manageListView2();
return view;
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(SelectModemViewModel.class);
// TODO: Use the ViewModel
//Sets up the ListView if not already setup
private void manageListView(Context context)
thelist = dbhelper.getAllRowsAsList(); //<<<<<<<<<< extract the list (just the phone names) from the database
// Only setup the adapter and the ListView if the adapter hasn't been setup
if (arrayAdapter == null)
// Instantiate the adapter
arrayAdapter = new ArrayAdapter<>(context,android.R.layout.simple_list_item_1,thelist); //<<<<<<<<<< list included
display_contacts1.setAdapter(arrayAdapter); //<<<<<<<<<< Tie the adpater to the ListView
// Set the ListViews OnItemClick Listener
display_contacts1.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
String name = arrayAdapter.getItem(position); //<<<<<<<<<< this gets the phone name
Toast.makeText(view.getContext(),"You clicked the phone named " + name,Toast.LENGTH_SHORT).show();
);
else
//<<<<<<<<<< MODIFIED to cope with changes (needs to rebuild the array within the adpater)
arrayAdapter.clear();
for (String s: thelist)
arrayAdapter.add(s);
arrayAdapter.notifyDataSetChanged();
//<<<<<<<<<< ADDED FOR CursorAdapter
private void manageListView2()
MyCursor = dbhelper.getAllRowsAsCursor();
if (sca == null)
sca = new SimpleCursorAdapter(
getContext(),
android.R.layout.simple_list_item_1,
MyCursor,
new String[]DataDBAdapter.COl_MYTABLE_PHONENAME,
new int[]android.R.id.text1,
0
);
display_contacts2.setAdapter(sca);
display_contacts2.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
Toast.makeText(view.getContext(),
"You Clicked the phone name " +
MyCursor.getString(MyCursor.getColumnIndex(DataDBAdapter.COl_MYTABLE_PHONENAME)) +
". The phonenumber is " +
MyCursor.getString(MyCursor.getColumnIndex(DataDBAdapter.COL_MYTABLE_PHONENUMBER)) +
". The ID (as passed) is " + String.valueOf(id) +
". The ID (from Cursor) is " + String.valueOf(MyCursor.getLong(MyCursor.getColumnIndex(DataDBAdapter.COL_MYTABLE_ID)))
,
Toast.LENGTH_SHORT).show();
);
//<<<<<<<<<< EXTRA delete row on long click
display_contacts2.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
dbhelper.delete(id);
manageListView2();
manageListView(getContext());
return true;
);
else
sca.swapCursor(MyCursor);
// Add some testing data (only if none already exists)
private void AddSomeData()
if (DatabaseUtils.queryNumEntries(dbhelper.getWritableDatabase(),DataDBAdapter.TBL_MYTABLE) < 1)
dbhelper.insert("Phone 1", "0000000000");
dbhelper.insert("Phone 2", "1111111111");
@Override
public void onResume()
super.onResume();
manageListView2();
manageListView(getContext());
@Override
public void onDetach()
super.onDetach();
MyCursor.close();
【讨论】:
@SahilBora 这是因为错字 myCursor 应该是 MyCursor。附言没有意识到代码来自我的答案。我即将用两个示例来编辑问题,即两个单独的 ListView(ArrayAdapter以上是关于将两个 SQL 列加载到列表视图中但只需要显示第一列 Android的主要内容,如果未能解决你的问题,请参考以下文章
Android OnItemClick 无法将加载的 SQL 数据库加载到列表视图中
如何将显示的 sql 数据加载到 wpf 可滚动列表视图中?大型集合(20k+)而不会遇到内存问题?