#android
#Android
Вопрос:
У меня есть многоколоночный ListView, и я хотел бы динамически добавлять по 10 элементов каждый в список при событии прокрутки. Динамическое добавление освещенных элементов прошло успешно, но при добавлении следующих 10 элементов в listview выбор возвращается к первому элементу списка.
Вот мой код :
public class ViewCheckInCheckOutHistory extends Activity {
ListView historyListView;
ProgressDialog pd;
List<CheckInCheckOutHistory> checkInCheckOutHistoryList = new ArrayList<CheckInCheckOutHistory>();
ArrayList<HashMap<String, String>> historyArrayList;
SimpleAdapter histroyListAdapter;
int itemsPerPage = 10;
boolean loadingMore = false;
int firstItemCount = 0;
int lastItemCount = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_checkin_checkout_history);
pd = ProgressDialog.show(this, "", "Please wait...");
Thread thread = new Thread() {
public void run() {
synchronized (this) {
fetchHistory();
handler.post(new Runnable() {
public void run() {
pd.dismiss();
displayUI();
};
});
}
}
};
thread.start();
}
private void displayUI() {
if ((checkInCheckOutHistoryList != null)
amp;amp; (checkInCheckOutHistoryList.size() > 0)) {
historyArrayList = new ArrayList<HashMap<String, String>>();
histroyListAdapter = new SimpleAdapter(ViewCheckInCheckOutHistory.this,
historyArrayList,
R.layout.multi_colummn_list_text_style_small,
new String[] { "assetTag", "action", "actionTime" }, new int[] {
R.id.list_content_column1,
R.id.list_content_column3,
R.id.list_content_column4});
historyListView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem visibleItemCount;
if((lastInScreen == totalItemCount) amp;amp; !(loadingMore)){
Thread thread = new Thread(null, loadMoreListItems);
thread.start();
}
}
});
}
}
//Runnable to load the items
private Runnable loadMoreListItems = new Runnable() {
@Override
public void run() {
//Set flag so we cant load new items 2 at the same time
loadingMore = true;
HashMap<String, String> historyObjectMap;
System.out.println("firstItemCount : " firstItemCount);
System.out.println("lastItemCount : " lastItemCount);
//Get 10 new listitems
for (int i = firstItemCount; i < lastItemCount; i ) {
System.out.println("i : " i);
CheckInCheckOutHistory checkOutHistoryObj = checkInCheckOutHistoryList.get(i);
historyObjectMap = new HashMap<String, String>();
historyObjectMap.put("assetTag", checkOutHistoryObj.getAssetTag());
historyObjectMap.put("action", checkOutHistoryObj.getAction());
historyArrayList.add(historyObjectMap);
}
runOnUiThread(returnRes);
}
};
//Since we cant update our UI from a thread this Runnable takes care of that!
private Runnable returnRes = new Runnable() {
@Override
public void run() {
//Add the new items to the adapter
if(historyArrayList != null amp;amp; historyArrayList.size() > 0){
histroyListAdapter.notifyDataSetChanged();
}
if (checkInCheckOutHistoryList.size() - lastItemCount > 10) {
firstItemCount = lastItemCount;
lastItemCount = lastItemCount itemsPerPage;
} else {
if (checkInCheckOutHistoryList.size() - firstItemCount > 10) {
firstItemCount = lastItemCount;
lastItemCount = checkInCheckOutHistoryList.size();
} else {
if (checkInCheckOutHistoryList.size() - firstItemCount > 0){
firstItemCount = lastItemCount;
lastItemCount = checkInCheckOutHistoryList.size();
}
}
}
historyListView.setAdapter(histroyListAdapter);
//Done loading more.
loadingMore = false;
}
};
}
‘fetchHistory()’ — это функция, в которой значения добавляются в ‘checkInCheckOutHistoryList’.
Заранее спасибо за любую помощь.
Комментарии:
1. Список отображается с первого элемента, потому что вы снова и снова назначаете адаптер
ListView
. ВызоваnotifyDatasetChanged()
должно быть достаточно. С другой стороны, использованиеAsyncTask
было бы лучшей практикой, чем явное выполнение потоков сRunnables
.
Ответ №1:
В displayUI()
методе вы каждый раз создаете новый адаптер и устанавливаете его в ListView вместо использования Adapter.notifyDataSetChanged()
Комментарии:
1. Я попытался, удалив historyListView.setAdapter(histroyListAdapter); из Runnable RETURNS. Но это не сработало.
2. Не могли бы вы сказать, где я мог бы установить адаптер для ListView?
3. Я сказал вам, что нужно сделать в методе displayUI
4. устанавливайте адаптер только в первый раз, после этого каждый раз, когда вы будете использовать notifyDataSetChanged(), а для проверки первого экземпляра вы можете использовать boolean