我使用ListView創建圖片列表,並且照片的大小適合屏幕上的2至3張照片。列表視圖管理單元
我遇到的問題是,當用戶停止滾動時,可見列表的第一項會捕捉到屏幕的頂部,例如,如果滾動結束並且小部分首先顯示的圖片,我們向下滾動列表以使圖片始終完全顯示,如果主要顯示圖片,我們向上滾動列表以便下一張圖片完全可見。
有沒有一種方法來實現這個在Android與列表視圖?
我使用ListView創建圖片列表,並且照片的大小適合屏幕上的2至3張照片。列表視圖管理單元
我遇到的問題是,當用戶停止滾動時,可見列表的第一項會捕捉到屏幕的頂部,例如,如果滾動結束並且小部分首先顯示的圖片,我們向下滾動列表以使圖片始終完全顯示,如果主要顯示圖片,我們向上滾動列表以便下一張圖片完全可見。
有沒有一種方法來實現這個在Android與列表視圖?
我已經找到一種方法來做到這一點只是聽時,通過實施ListView.OnScrollListener
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
if (scrolling){
// get first visible item
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop()); // top is a negative value
int bottom = Math.abs(itemView.getBottom());
if (top >= bottom){
((ListView)view).setSelectionFromTop(view.getFirstVisiblePosition()+1, 0);
} else {
((ListView)view).setSelectionFromTop(view.getFirstVisiblePosition(), 0);
}
}
scrolling = false;
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
case OnScrollListener.SCROLL_STATE_FLING:
Log.i("TEST", "SCROLLING");
scrolling = true;
break;
}
}
的變化結束滾動也不是那麼順暢,但它的工作原理進行滾動和改變位置。
除了嘗試代碼上面的一件事情,你應該確保你的listView有一個高度,可以適合你想要顯示的項目的確切數量。 例如 如果您希望在捕捉效果後顯示4個項目,並且您的行高(在其佈局中定義)應該爲列表總高度的1/4。
使用@nininho的溶液,
在onScrollStateChanged
當狀態變爲SCROLL_STATE_IDLE
,記住捕捉並提高標誌的位置:
snapTo = view.getFirstVisiblePosition();
shouldSnap = true;
然後,重寫computeScroll()
方法:
@Override
public void computeScroll() {
super.computeScroll();
if(shouldSnap){
this.smoothScrollToPositionFromTop(snapTo, 0);
shouldSnap = false;
}
}
利用@ nininho解決方案中的一些想法,我得到了我的列表視圖,以平滑的scr而不是突然地去做它。有一點需要注意的是,我只是在帶有文本的基本ListView的Moto X上測試了這個解決方案,但它在設備上運行得非常好。不過,我對這個解決方案充滿信心,並鼓勵您提供反饋意見。
listview.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if (scrollState == SCROLL_STATE_IDLE) {
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop());
int bottom = Math.abs(itemView.getBottom());
int scrollBy = top >= bottom ? bottom : -top;
if (scrollBy == 0) {
return;
}
smoothScrollDeferred(scrollBy, (ListView)view);
}
}
private void smoothScrollDeferred(final int scrollByF,
final ListView viewF) {
final Handler h = new Handler();
h.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
viewF.smoothScrollBy(scrollByF, 200);
}
});
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
我之所以推遲平滑滾動是因爲在我的測試,直接調用該州smoothScrollBy方法改變了回調實際上問題滾動。另外,我沒有預見到一個經過充分測試,強大的解決方案,持有非常多的狀態,在我的解決方案中,我根本沒有任何狀態。此解決方案尚未在Google Play商店中推出,但應作爲一個很好的起點。
當'top> = bottom'時,'scrollBy'等於(** N:在GridView中爲col cols,N爲1爲ListView)'view.getChildAt(view.getFirstVisiblePosition()+ N).getY()'。 – samosaris 2017-08-30 19:18:20
如果您使用RecyclerView,則可以進行更平滑的滾動。 OnScrollListener更好。
我已經在這裏一個例子:https://github.com/plattysoft/SnappingList
注意,smoothScrollBy()
調用後,getFirstVisiblePosition()
可能指向上面的最上面的列表視圖列表項。當view.getChildAt(0).getBottom() == 0
時尤其如此。我不得不打電話view.setSelection(view.getFirstVisiblePosition() + 1)
補救這種奇怪的行爲。
如果你想讓它平滑嘗試使用(((ListView)視圖)。smoothScrollToPosition(POS); – stealthcopter 2012-11-23 13:03:50
這樣做的兩個問題:1)smoothScrollToPosition會導致上述邏輯檢測到另一個滾動並進入一個緊張的循環 - 您可以通過刪除SCROLL_STATE_FLING的情況來避免這種情況,但我不確定這是否是一個很好的解決方法。 2)smoothScrollToPosition不能正確對齊,至少與我的列表。它將指定項目的頂部滾動到列表視圖頂部以上15像素,而不是像setSelection/setSelectionFromTop那樣正確對齊。 – benkc 2013-01-02 21:22:26
任何順利的解決方案? – benkol 2014-02-18 11:11:21