安卓SQLite同Verse_id数据合并显示于ListView技术求助
解决SQLite相同verse_id数据合并到ListView同一行的问题
我来帮你搞定这个需求!你现在的问题核心是没有对相同verse_id的数据进行分组合并——不管是用SimpleCursorAdapter直接展示每行数据,还是把所有数据挨个塞进ArrayList,都没法实现同ID合并的效果。下面给你一套完整的实现方案:
第一步:定义数据模型类
先创建一个自定义类来存储每个verse_id对应的合并后数据,这样后续处理起来更清晰:
public class VerseItem { private int verseId; private String combinedArWords; private String combinedBnTrans; public VerseItem(int verseId, String combinedArWords, String combinedBnTrans) { this.verseId = verseId; this.combinedArWords = combinedArWords; this.combinedBnTrans = combinedBnTrans; } // Getter方法 public int getVerseId() { return verseId; } public String getCombinedArWords() { return combinedArWords; } public String getCombinedBnTrans() { return combinedBnTrans; } }
第二步:从数据库查询并分组合并数据
我们需要遍历Cursor,把相同verse_id的words_ar和translate_bn分别拼接起来,最后整理成VerseItem的列表:
private ArrayList<VerseItem> getMergedVerseData() { ArrayList<VerseItem> mergedList = new ArrayList<>(); if (database == null) return mergedList; // 查询数据,按verse_id排序,保证同ID的行连在一起 Cursor cursor = database.query("bywords", new String[]{"verse_id", "words_ar", "translate_bn"}, null, null, null, null, "verse_id ASC"); if (cursor == null || !cursor.moveToFirst()) { cursor.close(); return mergedList; } int currentVerseId = cursor.getInt(cursor.getColumnIndex("verse_id")); StringBuilder arWordsBuilder = new StringBuilder(cursor.getString(cursor.getColumnIndex("words_ar"))); StringBuilder bnTransBuilder = new StringBuilder(cursor.getString(cursor.getColumnIndex("translate_bn"))); while (cursor.moveToNext()) { int verseId = cursor.getInt(cursor.getColumnIndex("verse_id")); String arWord = cursor.getString(cursor.getColumnIndex("words_ar")); String bnTrans = cursor.getString(cursor.getColumnIndex("translate_bn")); if (verseId == currentVerseId) { // 同ID,继续拼接 arWordsBuilder.append(" ").append(arWord); bnTransBuilder.append(" ").append(bnTrans); } else { // ID变化,把之前的合并数据加入列表 mergedList.add(new VerseItem(currentVerseId, arWordsBuilder.toString(), bnTransBuilder.toString())); // 重置当前ID和拼接器 currentVerseId = verseId; arWordsBuilder = new StringBuilder(arWord); bnTransBuilder = new StringBuilder(bnTrans); } } // 把最后一组数据加入列表 mergedList.add(new VerseItem(currentVerseId, arWordsBuilder.toString(), bnTransBuilder.toString())); cursor.close(); return mergedList; }
第三步:自定义ListView Adapter
创建一个自定义Adapter来显示合并后的数据,这样你可以灵活控制每行的布局和内容:
public class VerseAdapter extends ArrayAdapter<VerseItem> { private LayoutInflater inflater; public VerseAdapter(Context context, ArrayList<VerseItem> items) { super(context, 0, items); inflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.verse_list_item, parent, false); holder = new ViewHolder(); holder.tvVerseId = convertView.findViewById(R.id.tv_verse_id); holder.tvArWords = convertView.findViewById(R.id.tv_ar_words); holder.tvBnTrans = convertView.findViewById(R.id.tv_bn_trans); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } VerseItem item = getItem(position); holder.tvVerseId.setText(item.getVerseId() + "."); holder.tvArWords.setText(item.getCombinedArWords()); holder.tvBnTrans.setText(item.getCombinedBnTrans()); return convertView; } static class ViewHolder { TextView tvVerseId; TextView tvArWords; TextView tvBnTrans; } }
第四步:创建ListView的行布局(verse_list_item.xml)
在res/layout下创建这个布局文件,用来展示每行的合并内容:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp" android:borderBottomWidth="1dp" android:borderBottomColor="#cccccc"> <TextView android:id="@+id/tv_verse_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:textStyle="bold"/> <TextView android:id="@+id/tv_ar_words" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> <TextView android:id="@+id/tv_bn_trans" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> </LinearLayout>
第五步:在Activity中绑定数据到ListView
最后在你的Activity里调用上面的方法,把合并后的数据设置给ListView:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main2); mContext = this; // 初始化数据库 ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(this, DB_NAME); database = dbOpenHelper.openDataBase(); // 获取合并后的数据 ArrayList<VerseItem> mergedData = getMergedVerseData(); // 设置Adapter ListView list4 = findViewById(R.id.list4); VerseAdapter adapter = new VerseAdapter(this, mergedData); list4.setAdapter(adapter); }
这样就能实现你想要的效果:每个verse_id对应ListView的一行,该行显示所有同ID的阿拉伯语单词和孟加拉语翻译的合并内容,不同ID自动换行。
内容的提问来源于stack exchange,提问作者Noor Hossain
相关产品推荐
相关产品推荐

