在一个活动中的Android显示光标结果在两个不同的列表视图
关于如何在同一活动中显示光标结果在两个不同的列表视图的任何想法?一个例子是从Whatsapp他们有(我推测)一个“聊天”表和“消息”表。一旦我们在工具栏上键入关键字,我将在1个活动中查询两个表并在两个不同的列表视图中显示。有没有办法做到这一点?或者它们只在1个单一列表视图中显示?请指教。在一个活动中的Android显示光标结果在两个不同的列表视图
谢谢。
是可以做到这一点。为了以简单的方式模拟上述内容,假定数据库有两个表聊天和消息。它们都有两列,分别是文本的唯一标识符和列。
使用SQLiteOpenHelper的子类,我们可以有一个文件名为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个表聊天和消息(按CHATTABLE和MSGTABLE)。
onUpgrade is required but does nothing as yet.
insertRow
可以用于将行添加到任何一个表(因为它们都具有相同的结构)。请注意,它会写入日志,以便插入可以很容易地被确认。
getRows
用于获取包含数据的光标(来自数据库的数据)。这一个方法也可以用于这两个表。它传递一个字符串(如果它的长度大于0)来过滤表(按照在搜索字段中输入的数据)。
活动将需要一个布局指定两个列表视图,在这种情况下,这将是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();
}
}
首先是一些类变量的定义: -
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;
用于使数据库数据适应ListViews。顾名思义,这些都是非常基础的,但会用于演示目的。
onCreate
的前5行非常标准。
接下来的6行基本上都是相同的,即dbhlpr.insertRow(DBHlpr.CHATTABLE, "This is my first chat");
,并调用insertRow方法传递相应的表和要存储的数据。应该注意的是,第一次运行的第一次是创建数据库的时间。注意这些行仅用于提供一些测试数据。
然后我们来(注意代码以下这基本上是重复,但是对信息表) -
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);
第一行获得与各自的数据光标(所有聊天行,为按照第二个参数)。第二到第九行是设置Simple Cursors Adapater的单个命令(第一个参数是上下文,第二个是使用的布局(我们作弊和使用简单的一个),第三个是保存数据的Cursor,第四个是要获取游标中的数据的列,第5个是将要放置数据的视图ID,第6个应该是0)。 最后一行告诉ListView使用适配器。
在此之后,将TextWatcher添加到搜索中。在此使用onTextChanged方法,该方法调用refreshCursors
方法。
refreshCursors
方法使用已更改的搜索数据将数据从数据库中获取到现有游标中,然后通过swapCursor
告知adapter数据已更改。
最后的onDestroy
方法用于在Activity即将结束时关闭游标。
在最初运行: -
在搜索栏中键入˚F后: -
谢谢。 @MikeT。 –