2011-11-26 38 views
42

Tôi đang sử dụng một OnScrollListener để tự động thêm các mục vào một ListView khi người dùng cuộn xuống dưới cùng. Sau khi tôi thêm dữ liệu vào bộ điều hợp và gọi notifyDataSetChanged, ListView sẽ quay trở lại đầu trang. Lý tưởng nhất, tôi muốn giữ lại vị trí trong ListView. Bất kỳ suy nghĩ về cách tôi nên đi về việc này?Giữ lại vị trí trong ListView sau khi gọi notifyDataSetChanged

+0

Hi bạn có thể xin vui lòng chia sẻ cách u đã duy trì và sử dụng trạng thái hiện tại của xem danh sách trong OnScrollListener ... tôi đang làm tương tự, nhưng tôi cập nhật danh sách từ Async nhiệm vụ ..... ... không hoạt động như thế nào – ANUP

+3

Giải pháp đơn giản: http://stackoverflow.com/a/28149739/1468093 –

+0

sử dụng câu trả lời của @KamranAhmed. giải pháp đơn giản và thanh lịch. Infact chính xác ngay cả –

Trả lời

96

Đây có phải là điều bạn muốn không?

// save index and top position 
int index = mList.getFirstVisiblePosition(); 
View v = mList.getChildAt(0); 
int top = (v == null) ? 0 : v.getTop(); 

// notify dataset changed or re-assign adapter here 

// restore the position of listview 
mList.setSelectionFromTop(index, top); 

EDIT 28/09/2017:

API đã thay đổi khá nhiều kể từ năm 2015. Nó là tương tự, nhưng bây giờ nó sẽ là:

// save index and top position 
int index = mList.FirstVisiblePosition; //This changed 
View v = mList.getChildAt(0); 
int top = (v == null) ? 0 : v.Top; //this changed 

// notify dataset changed or re-assign adapter here 

// restore the position of listview 
mList.setSelectionFromTop(index, top); 
+8

Cảm ơn. Nếu bạn muốn thêm các mục vào đầu danh sách mà không thấy cập nhật xảy ra, bạn sẽ cần thêm số mục bạn đã thêm vào chỉ mục int. int index = mList.getFirstVisiblePosition() + NUMBER_OF_ADDED_ITEMS; –

+5

Nếu setSelection không hoạt động ngay lập tức sau khi gọi notifyDataSetChanged, đây là giải pháp thay thế: getListView().postDelayed (Runnable mới() { @Override void void run() { getListView(). setSelection (8); } }, 500); Lỗi Android được cho là đã được gán, vì vậy, lỗi này phải được khắc phục tại một số điểm: https://code.google.com/p/android/issues/detail?id=6741 – d2vid

+4

Làm việc một cách hoàn hảo. Ngoài ra, trong trường hợp nó giúp người khác, điều này đã không làm việc lúc đầu cho tôi. Cho đến khi tôi nhận ra trong một số trí tuệ vô hạn trước đây của tôi, tôi đã thêm 'lv.setTranscriptMode (AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL)'. Đừng làm điều đó ... nó sẽ mạnh mẽ di chuyển đến dưới cùng của listview của bạn cho đến khi bạn đã kéo hầu hết tóc của bạn ra. hah. – wired00

6

Tình hình:

Khi bạn đặt bộ điều hợp cho chế độ xem danh sách, nó sẽ làm mới trạng thái của bộ điều hợp. Vì vậy, bình thường sẽ tự động cuộn lên.

Giải pháp:

Gán một adapter để ListView nếu nó không phải bất kỳ có, nếu không chỉ cập nhật các dữ liệu của các bộ chuyển đổi giao, không tái đặt nó vào listview của bạn.

Hướng dẫn chi tiết được giải thích tại liên kết sau;

Android ListView: Maintain your scroll position when you refresh

Chúc may mắn!

+1

Điều này hoạt động theo cách mà vị trí cuộn không di chuyển nếu tôi thêm một mục bổ sung nhưng danh sách trong chế độ xem nhảy xuống để chứa mục mới. – Simon

+0

Đây là giải pháp đúng, không cần "hack" để có được một cái gì đó đơn giản. – Ethenyl

0

Tôi đã triển khai postDelayed và tôi đã nhận được nhấp nháy khi làm mới. Tôi tìm kiếm một số chi tiết và phát hiện ra rằng tôi đã làm điều sai trái. Về cơ bản tôi không nên tạo ra một bộ chuyển đổi mới mỗi khi tôi muốn thay đổi dữ liệu. Tôi đã làm theo cách này và nó hoạt động:

//goes into your adapter 
public void repopulateData(String[] objects) { 
    this.objects = null; 
    this.objects = objects; 
    notifyDataSetChanged(); 
} 

//goes into your activity or list 
if (adapter == null) { 
    adapter = new Adapter(); 
} else { 
    adapter.repopulateData((String[])data); 
} 

Hy vọng điều này sẽ hữu ích.

0

Tôi đang sử dụng

listView.getFirstVisiblePosition

để duy trì vị trí có thể nhìn thấy trước.

0

Đi với chế độ bảng điểm của chế độ xem danh sách.

0

Hãy thử điều này

 boolean first=true; 
     protected void onPostExecute(Void result) 
     { 

     if (first == true) { 
     listview.setAdapter(customAdapter); 
     first=false; 
     } 
     else 
     customAdapter.notifyDataSetChanged(); 
     } 
Các vấn đề liên quan