Android 在两个不同的列表视图中显示光标结果 Activity
Android Display Cursor Result In Two Different Listview In One Activity
知道如何在同一个 activity 中的两个不同列表视图中显示光标结果吗?一个例子来自 Whatsapp,他们有(我假设)"Chats" table 和 "Messages" table。一旦我们在工具栏上键入关键字,我将查询两个 table 并在 1 activity 中的两个不同列表视图中显示。有什么办法吗?或者它们只显示在 1 个列表视图中?请指教。
谢谢。
是的,这是可以做到的。为了以简单的方式模仿上述内容,假设数据库有两个 tables 聊天和消息。它们都有两列,一个唯一标识符和一个文本列。
使用 SQLiteOpenHelper 的子class,我们可以得到一个名为 DBHlpr.java 的文件:-
public class DBHlpr extends SQLiteOpenHelper {
static final String DBNAME = "mydb";
static final String CHATTABLE = "chats";
static final String MSGTABLE = "messages";
static final String TEXTCOL = "textdata";
static final String IDCOL = "_id";
DBHlpr(Context context) {
super(context,DBNAME,null,1);
}
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + CHATTABLE + " (" + IDCOL + " INTEGER PRIMARY KEY, " + TEXTCOL + " TEXT)");
db.execSQL("CREATE TABLE " + MSGTABLE + " (" + IDCOL + " INTEGER PRIMARY KEY, " + TEXTCOL + " TEXT)");
}
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
}
public void insertRow(String table, String text) {
ContentValues cv = new ContentValues();
cv.put(TEXTCOL,text);
long id = this.getWritableDatabase().insert(table,null,cv);
Log.d("DBHLP-INSRT","Added row with ID=" + Long.toString(id));
}
public Cursor getRows(String table, String srchstr) {
SQLiteDatabase db = getWritableDatabase();
String whereclause = null;
if (srchstr.length() > 0) {
whereclause = TEXTCOL + " LIKE '%" + srchstr + "%' ";
}
return db.query(
table,
null,whereclause,null,null,null,null);
}
}
onCreate
方法将创建 2 个 table,即 chats 和 messages(根据 CHATTABLE和 MSGTABLE)。
onUpgrade is required but does nothing as yet.
insertRow
可用于向 table 添加一行(因为它们具有相同的结构)。请注意,它将写入日志,以便可以轻松确认插入。
getRows
用于获取包含数据的Cursor(来自数据库的数据)。同样,这一个方法可以用于两个 tables。它传递一个字符串,用于(如果它的长度大于 0)过滤 tables(根据在搜索字段中输入的数据)。
activity 将需要指定两个 ListView 的布局,在本例中它将是 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so45787986.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search" />
<EditText
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chats" />
<ListView
android:id="@+id/chats"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Messages" />
<ListView
android:id="@+id/messages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
</LinearLayout>
没有什么特别的,它是一个非常简单的布局,一个用于搜索条件的 EditText 一个用于聊天列表标题的 TextView(以下 ListView),然后是另一个用于消息的 TextView 和 ListView。
MainActivity.java 可能是:-
public class MainActivity extends AppCompatActivity {
DBHlpr dbhlpr = new DBHlpr(this);
Cursor chatcursor;
Cursor msgcursor;
TextWatcher tx;
EditText search;
ListView chatlist;
ListView msglist;
SimpleCursorAdapter chat_sca;
SimpleCursorAdapter msg_sca;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search = (EditText) findViewById(R.id.search);
chatlist = (ListView) findViewById(R.id.chats);
msglist = (ListView) findViewById(R.id.messages);
// Add some data for testing
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my first chat");
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my second chat");
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my third chat");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "First Message");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "Second Message");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "Third Message");
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,"");
chat_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
chatcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
chatlist.setAdapter(chat_sca);
msgcursor = dbhlpr.getRows(DBHlpr.MSGTABLE,"");
msg_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
msgcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
msglist.setAdapter(msg_sca);
search.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
refreshCursors();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
private void refreshCursors() {
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,search.getText().toString());
chat_sca.swapCursor(chatcursor);
msgcursor = dbhlpr.getRows(DBHlpr.MSGTABLE,search.getText().toString());
msg_sca.swapCursor(msgcursor);
}
@Override
public void onDestroy() {
super.onDestroy();
chatcursor.close();
msgcursor.close();
}
}
首先定义了一些class变量:-
DBHlpr dbhlpr = new DBHlpr(this);
Cursor chatcursor;
Cursor msgcursor;
与数据库相关。第一个创建 DBHlpr 的实例,另外两个用于 2 个游标(聊天和消息)。
TextWatcher tx;
EditText search;
ListView chatlist;
ListView msglist;
用于处理视图。 TextWatcher 用于检测搜索的变化。
SimpleCursorAdapter chat_sca;
SimpleCursorAdapter msg_sca;
用于使数据库数据适应 ListView。顾名思义,这些都是非常基本的,但可以用于演示目的。
onCreate
中的前 5 行非常标准。
接下来的 6 行基本相同,即 dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my first chat");
并调用 insertRow 方法传递相应的 table 和要存储的数据。应该注意的是,第一次是 运行 是创建数据库的时间。请注意,这些行仅用于提供一些测试数据。
然后我们来到(注意下面的代码基本上是重复的,但是对于消息table):-
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,"");
chat_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
chatcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
chatlist.setAdapter(chat_sca);
第一行获取带有相应数据的游标(所有聊天行,根据第二个参数)。
第 2-9 行是设置简单游标适配器的单个命令(第 1 个参数是上下文,第 2 个要使用的布局(我们欺骗并使用一个简单的),第 3 个是保存数据的游标,第 4 个是要获取游标中数据的列,第 5 位是放置数据的视图 ID,第 6 位应为 0)。
最后一行告诉 ListView 使用适配器。
随后将 TextWatcher 添加到搜索中。在此使用 onTextChanged 方法,它调用 refreshCursors
方法。
refreshCursors
方法使用更改后的搜索数据从数据库中获取数据到现有游标中,然后通过 swapCursor
告诉适配器数据已更改。
最后onDestroy
方法用于在Activity即将结束时关闭游标。
最初 运行 :-
在搜索字段中输入 f 后:-
知道如何在同一个 activity 中的两个不同列表视图中显示光标结果吗?一个例子来自 Whatsapp,他们有(我假设)"Chats" table 和 "Messages" table。一旦我们在工具栏上键入关键字,我将查询两个 table 并在 1 activity 中的两个不同列表视图中显示。有什么办法吗?或者它们只显示在 1 个列表视图中?请指教。
谢谢。
是的,这是可以做到的。为了以简单的方式模仿上述内容,假设数据库有两个 tables 聊天和消息。它们都有两列,一个唯一标识符和一个文本列。
使用 SQLiteOpenHelper 的子class,我们可以得到一个名为 DBHlpr.java 的文件:-
public class DBHlpr extends SQLiteOpenHelper {
static final String DBNAME = "mydb";
static final String CHATTABLE = "chats";
static final String MSGTABLE = "messages";
static final String TEXTCOL = "textdata";
static final String IDCOL = "_id";
DBHlpr(Context context) {
super(context,DBNAME,null,1);
}
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + CHATTABLE + " (" + IDCOL + " INTEGER PRIMARY KEY, " + TEXTCOL + " TEXT)");
db.execSQL("CREATE TABLE " + MSGTABLE + " (" + IDCOL + " INTEGER PRIMARY KEY, " + TEXTCOL + " TEXT)");
}
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
}
public void insertRow(String table, String text) {
ContentValues cv = new ContentValues();
cv.put(TEXTCOL,text);
long id = this.getWritableDatabase().insert(table,null,cv);
Log.d("DBHLP-INSRT","Added row with ID=" + Long.toString(id));
}
public Cursor getRows(String table, String srchstr) {
SQLiteDatabase db = getWritableDatabase();
String whereclause = null;
if (srchstr.length() > 0) {
whereclause = TEXTCOL + " LIKE '%" + srchstr + "%' ";
}
return db.query(
table,
null,whereclause,null,null,null,null);
}
}
onCreate
方法将创建 2 个 table,即 chats 和 messages(根据 CHATTABLE和 MSGTABLE)。
onUpgrade is required but does nothing as yet.
insertRow
可用于向 table 添加一行(因为它们具有相同的结构)。请注意,它将写入日志,以便可以轻松确认插入。
getRows
用于获取包含数据的Cursor(来自数据库的数据)。同样,这一个方法可以用于两个 tables。它传递一个字符串,用于(如果它的长度大于 0)过滤 tables(根据在搜索字段中输入的数据)。
activity 将需要指定两个 ListView 的布局,在本例中它将是 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so45787986.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search" />
<EditText
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chats" />
<ListView
android:id="@+id/chats"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Messages" />
<ListView
android:id="@+id/messages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
</LinearLayout>
没有什么特别的,它是一个非常简单的布局,一个用于搜索条件的 EditText 一个用于聊天列表标题的 TextView(以下 ListView),然后是另一个用于消息的 TextView 和 ListView。
MainActivity.java 可能是:-
public class MainActivity extends AppCompatActivity {
DBHlpr dbhlpr = new DBHlpr(this);
Cursor chatcursor;
Cursor msgcursor;
TextWatcher tx;
EditText search;
ListView chatlist;
ListView msglist;
SimpleCursorAdapter chat_sca;
SimpleCursorAdapter msg_sca;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search = (EditText) findViewById(R.id.search);
chatlist = (ListView) findViewById(R.id.chats);
msglist = (ListView) findViewById(R.id.messages);
// Add some data for testing
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my first chat");
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my second chat");
dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my third chat");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "First Message");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "Second Message");
dbhlpr.insertRow(DBHlpr.MSGTABLE, "Third Message");
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,"");
chat_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
chatcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
chatlist.setAdapter(chat_sca);
msgcursor = dbhlpr.getRows(DBHlpr.MSGTABLE,"");
msg_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
msgcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
msglist.setAdapter(msg_sca);
search.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
refreshCursors();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
private void refreshCursors() {
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,search.getText().toString());
chat_sca.swapCursor(chatcursor);
msgcursor = dbhlpr.getRows(DBHlpr.MSGTABLE,search.getText().toString());
msg_sca.swapCursor(msgcursor);
}
@Override
public void onDestroy() {
super.onDestroy();
chatcursor.close();
msgcursor.close();
}
}
首先定义了一些class变量:-
DBHlpr dbhlpr = new DBHlpr(this);
Cursor chatcursor;
Cursor msgcursor;
与数据库相关。第一个创建 DBHlpr 的实例,另外两个用于 2 个游标(聊天和消息)。
TextWatcher tx;
EditText search;
ListView chatlist;
ListView msglist;
用于处理视图。 TextWatcher 用于检测搜索的变化。
SimpleCursorAdapter chat_sca;
SimpleCursorAdapter msg_sca;
用于使数据库数据适应 ListView。顾名思义,这些都是非常基本的,但可以用于演示目的。
onCreate
中的前 5 行非常标准。
接下来的 6 行基本相同,即 dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my first chat");
并调用 insertRow 方法传递相应的 table 和要存储的数据。应该注意的是,第一次是 运行 是创建数据库的时间。请注意,这些行仅用于提供一些测试数据。
然后我们来到(注意下面的代码基本上是重复的,但是对于消息table):-
chatcursor = dbhlpr.getRows(DBHlpr.CHATTABLE,"");
chat_sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
chatcursor,
new String[]{DBHlpr.TEXTCOL},
new int[]{android.R.id.text1},
0
);
chatlist.setAdapter(chat_sca);
第一行获取带有相应数据的游标(所有聊天行,根据第二个参数)。 第 2-9 行是设置简单游标适配器的单个命令(第 1 个参数是上下文,第 2 个要使用的布局(我们欺骗并使用一个简单的),第 3 个是保存数据的游标,第 4 个是要获取游标中数据的列,第 5 位是放置数据的视图 ID,第 6 位应为 0)。 最后一行告诉 ListView 使用适配器。
随后将 TextWatcher 添加到搜索中。在此使用 onTextChanged 方法,它调用 refreshCursors
方法。
refreshCursors
方法使用更改后的搜索数据从数据库中获取数据到现有游标中,然后通过 swapCursor
告诉适配器数据已更改。
最后onDestroy
方法用于在Activity即将结束时关闭游标。
最初 运行 :-
在搜索字段中输入 f 后:-