Android显示光标在一个活动中的两个不同列表视图中的结果

时间:2017-09-01 13:10:41

标签: android sqlite whatsapp

关于如何在同一活动中显示光标的任何想法导致两个不同的列表视图?一个例子来自Whatsapp,他们有(我推测)一个“聊天”表和“消息”表。在工具栏上输入关键字后,我将查询两个表并在1个活动中显示两个不同的列表视图。有没有办法做到这一点?或者它们只显示在1个列表视图中?请指教。

谢谢。

Whatsapp

1 个答案:

答案 0 :(得分:1)

是的,这可以做到。为了以简单的方式模仿上述内容,假设数据库有两个表格聊天和消息。它们都有两列唯一标识符和一列文本。

使用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用于获取包含数据的Cursor(数据库中的数据)。同样,这一种方法可以用于两个表。传递一个字符串(如果它的长度大于0)来过滤表格(根据在搜索字段中输入的数据)。

活动将需要一个指定两个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();
    }
}

首先定义一些类变量: -

    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方法传递相应的表和要存储的数据。应该注意的是,第一次运行第一次是创建数据库的时间。请注意,这些行仅用于提供一些测试数据。

然后我们来(注意下面的代码基本上是重复的,但对于消息表): -

    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);

第一行获取带有相应数据的Cursor(所有聊天行,根据第二个参数)。 第2至第9行是设置Simple Cursors Adapater的单个命令(第一个parm是上下文,第二个是使用的布局(我们作弊并使用一个简单的),第三个是保存数据的Cursor,第四个是要获取光标中数据的列,第5个是放置数据的视图ID,第6个应该是0)。 最后一行告诉ListView使用适配器。

在此之后,TextWatcher将添加到搜索中。在此使用onTextChanged方法,该方法调用refreshCursors方法。

refreshCursors方法使用更改后的搜索数据将数据从数据库中获取到现有游标中,然后通过swapCursor告知adpater数据已更改。

最后,onDestroy方法用于在活动即将结束时关闭游标。

最初运行时: -

enter image description here

在搜索字段中输入 f 后: -

enter image description here