[英]Refreshing a ListView with a custom adapter
我正在為Android編寫一個小型的Google Talk客戶端,並且無法正確刷新ListView。
此列表包含聯系人列表,並顯示聯系人的姓名和狀態。 我的偵聽器工作正常,並且可以在日志貓窗口中看到每個聯系人的狀態更改,但是我的ListView沒有刷新...這是一些代碼:
package de.marc.messenger;
// ofc here are the imports
public class RosterActivity extends Activity {
private Roster _roster;
private XMPPConnection _connection;
private List<HashMap<String, String>> _buddies;
private BuddyAdapter _adapter;
private ListView _list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.roster);
_buddies = new ArrayList<HashMap<String, String>>();
_connection = LoginActivity.CONNECTION;
makePauseForRoster();
_roster = _connection.getRoster();
addRosterListener();
fillBuddyList();
sortBuddyList();
initializeListView();
}
/**
* Lets the thread sleep for a second to ensure that the presence of every
* user will be available
*/
private void makePauseForRoster() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Adds a listener to the roster, primarily for changes of presence
*/
private void addRosterListener() {
_roster.addRosterListener(new RosterListener() {
public void presenceChanged(Presence presence) {
String user = presence.getFrom().split("/")[0];
HashMap<String, String> buddy = findBuddyInRoster(user);
String p = getPresenceString(user);
buddy.put("presence", p);
System.out.println(buddy.values().toString()); // this works
_adapter.notifyDataSetChanged(); // this doesn't
_list.invalidate(); // this neither
}
});
}
/**
* Fills the list view with the roster entries
*/
private void initializeListView() {
_adapter = new BuddyAdapter(this, R.layout.roster_item,
_buddies);
_list = (ListView) findViewById(R.id.list_roster);
_list.setAdapter(_adapter);
}
/**
* Fills the buddy list with relevant data from a RosterEntry. Relevant data
* is the users' name, email and presence
*/
private void fillBuddyList() {
// this just fills my list of hashmaps (_buddies)
}
/**
* Get a predefined String depending on the presence of a user
*/
private String getPresenceString(String user) {
// something like "available: away ()" -> "away"
}
/**
* Sorts the buddy list. Only criterion is the presence of the user, because
* we have linear algorithms for this kind of problem.
*/
private void sortBuddyList() {
// move all offline contacts to the end
// move all online contacts to the beginning
// all other kind of contacts will stay in the middle
}
/**
* Finds a specific buddy object for a user via his hashed email
*/
private HashMap<String, String> findBuddyInRoster(String user) {
for (HashMap<String, String> buddy : _buddies) {
if (user.equals(buddy.get("user"))) {
return buddy;
}
}
return null;
}
}
這可以正常工作,一切都可以正確顯示。.唯一的麻煩似乎是在實現onPresenceChanged()的addRosterListener()方法中。
這是我的適配器:
package de.marc.messenger;
// as well some imports
public class BuddyAdapter extends ArrayAdapter<HashMap<String, String>> {
private Context _context;
private List<HashMap<String, String>> _map;
private LayoutInflater _inflater;
public BuddyAdapter(Context context, int id, List<HashMap<String, String>> map) {
super(context, id, map);
_context = context;
_map = map;
_inflater = (LayoutInflater) _context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// find view of a single row in a listview
View row = convertView;
if (convertView == null) {
row = _inflater.inflate(R.layout.roster_item, null);
}
// get data for a specific row
String name = _map.get(position).get("name");
String user = _map.get(position).get("user");
String presence = _map.get(position).get("presence");
// extract views from the row view
TextView nameText = (TextView) row.findViewById(R.id.text_name);
TextView userText = (TextView) row.findViewById(R.id.text_id);
ImageView presenceImg = (ImageView) row
.findViewById(R.id.image_presence);
// set data in extracted views
nameText.setText(name);
userText.setText(user);
int resource = 0;
// something is done with this variable
presenceImg.setImageResource(resource);
return row;
}
}
我有什么想念的嗎?
編輯:我這樣更改了onPresenceChanged方法:
public void presenceChanged(Presence presence) {
String user = presence.getFrom().split("/")[0];
HashMap<String, String> buddy = findBuddyInRoster(user);
_adapter.remove(buddy);
String p = getPresenceString(user);
buddy.put("presence", p);
_adapter.add(buddy);
_adapter.notifyDataSetChanged();
}
它在某種程度上有效:在屏幕上滑動了一點之后,更改了他的狀態的聯系人現在不在列表中:/
構造ArrayAdapter時,它保留傳入的List的引用。如果要傳入作為Activity成員的List,並在以后更改該Activity成員,則ArrayAdapter仍然持有對List的引用。原始清單。 適配器不知道您更改了活動列表。
在我看來,這就是您的工作,因此您需要使用新的列表數據重新創建適配器。
或者,您可以使用ArrayAdapter方法來修改基礎List( add
, insert
, remove
, clear
等),然后notifyDataSetChanged將起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.