避免重复收件箱的 Listview 项目
Posted
技术标签:
【中文标题】避免重复收件箱的 Listview 项目【英文标题】:Avoid repeating Listview items for inbox 【发布时间】:2015-07-24 08:07:59 【问题描述】:我正在开发一个包含收件箱活动和对话活动的消息传递应用程序。为此,我使用 SQL 数据库来保存所有接收和发送的消息,并将它们附加到收件箱活动的列表视图中。我正在从数据库中获取数据以追加。我不想附加所有具有相同号码但最新消息的消息,因为其他消息正在进入对话。帮我解决这个问题。我已经搜索过了,但在这里找不到它,还有一件事,我只是一个学习者。任何意见将不胜感激!
我想要这个
收件箱活动的代码是
public class ReceiveSMSActivity extends Activity
DBAdapter myDb;
private List<Message> MyMessages = new ArrayList<Message>();
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
openDB();
getResultsAndAppend();
populateListView();
private void getResultsAndAppend()
Cursor cursor = myDb.getAllRows();
if (cursor.moveToFirst())
do
// Process the data:
// String name = cursor.getString(DBAdapter.COL_NAME);
String number = cursor.getString(DBAdapter.COL_NUMBER);
String message = cursor.getString(DBAdapter.COL_MESSAGE);
MyMessages.add(new Message(message, number, true));
while (cursor.moveToNext());
private void populateListView()
ArrayAdapter<Message> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.listViewInbox);
list.setAdapter(adapter);
private class MyListAdapter extends ArrayAdapter<Message>
public MyListAdapter()
super(ReceiveSMSActivity.this, R.layout.inbox_list_item_layout,
MyMessages);
@Override
public View getView(int position, View convertView, ViewGroup parent)
// Make sure we have a view to work with (may have been given null)
View itemView = convertView;
if (itemView == null)
itemView = getLayoutInflater().inflate(
R.layout.inbox_list_item_layout, parent, false);
// Find the Message to work with.
Message currentMessage = MyMessages.get(position);
// Message:
TextView message = (TextView) itemView.findViewById(R.id.tvMessage);
message.setText(currentMessage.getMessage());
// Number:
TextView number = (TextView) itemView.findViewById(R.id.tvNumber);
number.setText(currentMessage.getNumber());
return itemView;
@Override
protected void onDestroy()
super.onDestroy();
closeDB();
private void openDB()
myDb = new DBAdapter(this);
myDb.open();
private void closeDB()
myDb.close();
而 DBAdapter() 是
public class DBAdapter
private static final String TAG = "DBAdapter";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
public static final String KEY_NAME = "name";
public static final String KEY_NUMBER = "number";
public static final String KEY_MESSAGE = "message";
public static final String KEY_ISSELF= "self";
public static final int COL_NAME = 1;
public static final int COL_NUMBER = 2;
public static final int COL_MESSAGE = 3;
public static final int COL_ISSELF = 4;
public static final String[] ALL_KEYS = new String[] KEY_ROWID, KEY_NAME, KEY_NUMBER, KEY_MESSAGE, KEY_ISSELF;
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
public static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_NAME + " text not null, "
+ KEY_NUMBER + " string not null, "
+ KEY_MESSAGE + " string not null,"
+ KEY_ISSELF + " string not null"
+ ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
// Open the database connection.
public DBAdapter open()
db = myDBHelper.getWritableDatabase();
return this;
// Close the database connection.
public void close()
myDBHelper.close();
// Add a new set of values to the database.
public long insertRow(String name, String number, String message, String isself)
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_NUMBER, number);
initialValues.put(KEY_MESSAGE, message);
initialValues.put(KEY_ISSELF, isself);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId)
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
public void deleteAll()
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst())
do
deleteRow(c.getLong((int) rowId));
while (c.moveToNext());
c.close();
// Return all data in the database.
public Cursor getAllRows()
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null)
c.moveToFirst();
return c;
// Get a specific row (by rowId)
public Cursor getRow(long rowId)
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null)
c.moveToFirst();
return c;
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, String number, String message, String isself)
String where = KEY_ROWID + "=" + rowId;
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_NUMBER, number);
newValues.put(KEY_MESSAGE, message);
newValues.put(KEY_ISSELF, isself);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
/////////////////////////////////////////////////////////////////////
// Private Helper Classes:
/////////////////////////////////////////////////////////////////////
/**
* Private class which handles database creation and upgrading.
* Used to handle low-level database access.
*/
private static class DatabaseHelper extends SQLiteOpenHelper
DatabaseHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@Override
public void onCreate(SQLiteDatabase _db)
_db.execSQL(DATABASE_CREATE_SQL);
@Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion)
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
【问题讨论】:
【参考方案1】:一种解决方案可能是在哈希图中解析您的所有消息,该哈希图中将以电话号码作为键和模型“PeopleTexts”,该模型将包含来自同一人(号码)的消息列表,文本数量,等等。
解析后,您只需遍历哈希图而不是数据库行。
这就是逻辑。现在是一些sn-ps代码
public class PeopleTexts
private String phoneNumber;
private String name;
private ArrayList<Message> peopleTexts;
// add setters and getters...
public int textCount()
return peopleTexts.size();
public void addMessage(Message message)
this.peopleTexts.add(message);
现在你只需要在你的do...while()
中做事
//我的消息现在是一个 Hashmap...
if (cursor.moveToFirst())
do
// Process the data:
// String name = cursor.getString(DBAdapter.COL_NAME);
String number = cursor.getString(DBAdapter.COL_NUMBER);
String message = cursor.getString(DBAdapter.COL_MESSAGE);
if(MyMessages.containsKey(number))
MyMessages.put(number, new PeopleTexts(name, number);
MyMessages.get(number).addMessage(new Message(number, message);
while (cursor.moveToNext());
剩下的交给你。
【讨论】:
感谢 Mathieu 的回复。我使用了您的帮助并使用了 MyMessages.haskey(),但出现错误“对于 ListcontainsKey(Object key)
docs.oracle.com/javase/6/docs/api/java/util/HashMap.html
它只有 contains(boolean),我也试过了,但没有工作。仍然显示所有条目。
你在使用 Hashmap以上是关于避免重复收件箱的 Listview 项目的主要内容,如果未能解决你的问题,请参考以下文章
共享收件箱 - 在 Outlook VBA 中跳过非邮件项目