2011-11-29 91 views
5

我有一個LinearLayout同時包含ListViewEditText。當通過觸摸EditText啓動屏幕鍵盤時,ListView調整大小,以便只有最上面的幾個元素保持可見。當鍵盤出現時保持ListView的底部元素可見

ListView正在使用的上下文有底部的幾個元素比頂部視覺上更相關,所以我希望它調整大小,使底部保持可見,而不是頂部。任何指針?

(順便說一句,我使用的是當前的修復包括使用smoothScrollToPosition,但laggy滾動行爲使這種不良)

+0

嘗試 http://stackoverflow.com/questions/16133706/push-listview-when-keyboard-appears-without-adjustpan http://stackoverflow.com/questions/9351509/keeping-the -last-visible-item-of-listview-when-the-size-of-listview-change – MSaudi

回答

-1

你應該在清單中添加這個屬性爲您的活動,並挑選了正確的值(也許你會選擇「adjustResize」):

<activity android:name="package.yourActivity" android:windowSoftInputMode="adjustResize"/> 
+0

不,這不能解決問題 - 窗口已經在adjustResize模式下設置;這是ListView的行爲調整不符合要求的行爲。 – chrisjrn

+0

chrisjrn,你解決問題了嗎? –

+0

我已經測試過你的答案但它不起作用 – FtheBuilder

1

我今天早上剛解決了類似的問題,我想我會在這裏發佈我的結果對未來搜索的好處。我的問題是,在視圖實際更改大小之前,我一直在調用它,所以滾動到底部並沒有幫助。解決方案?等待,直到它通過使用GlobalLayoutListener

步驟確實變化大小: 1)實現在活動以下方法保持列表視圖

public void scrollToBottom(){ 
    //I think this is supposed to run on the UI thread 
    listView.setSelection(mAdapter.getCount() - 1); 
} 

2)創建了以下類

public class OnGlobalLayoutListenerWithScrollToBottom implements OnGlobalLayoutListener{ 

    private boolean scroll; 
    private OnScrollToBottomListener listener; 
    public interface OnScrollToBottomListener{ 
     public void scrollToBottom(); 
    } 

    public OnGlobalLayoutListenerWithScrollToBottom(OnScrollToBottomListener listener){ 
     this.listener = listener; 
    } 

    @Override 
    public void onGlobalLayout() { 
     if(scroll){ 
      listener.scrollToBottom(); 
      scroll = false; 
     } 
    } 

    /** 
    * Lets the listener know to request a scroll to bottom the next time it is layed out 
    */ 
    public void scrollToBottomAtNextOpportunity(){ 
     scroll = true; 
    } 

}; 

3 )在你的活動中,實現這個類的接口。然後,在你的活動,創建這個OnGlobalLayoutListener的一個實例,並將其設置爲監聽你的ListView

//make sure your class implements OnGlobalLayoutListenerWithScrollToBottom.OnScrollToBottomListener 
    listViewLayoutListener = new OnGlobalLayoutListenerWithScrollToBottom(this); 
    listView.getViewTreeObserver().addOnGlobalLayoutListener(listViewLayoutListener); 

4)在你的活動,你做出改變,這將影響到列表視圖的大小,如顯示前和隱藏其他視圖或添加東西到ListView,乾脆讓聽者佈局知道下次有機會

listViewLayoutListener.scrollToBottomAtNextOpportunity(); 
0

您可能會setSelectionFromTop()並通過自定義列表視圖重寫onSizeChanged()實現這個滾動。在你的佈局中,你應該有一個RelativeLayout有一個父容器,並將該列表視圖放在edittext上方。

通過創建自己的列表視圖並覆蓋onSizeChange(),您將能夠在listview調整大小並獲取其新高度之前獲取最後一個可見項目的位置,以最終設置列表的「上一個」位置與偏移量的高度。

工作原理:您的列表將把上一個最後一個可見項放置在其頂部,您將添加像素以將其滾動到底部,即在edittext上方。

要覆蓋的方法,並與偏移顯示,執行如下:

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    // get last visible item's position before resizing 
    int lastPosition = super.getLastVisiblePosition(); 
    // call the super method to resize the listview 
    super.onSizeChanged(w, h, oldw, oldh); 
    // after resizing, show the last visible item at the bottom of new listview's height 
    super.setSelectionFromTop(lastPosition, (h - lastItemHeight)); 
} 

lastItemHeight是一點點的解決辦法,因爲我沒有找到如何在這之前onSizeChanged被稱爲得到最後一個項目的高度。然後,在listview包含許多類型的項目(沒有相同高度)的情況下,我更願意在發生事件時(即在SoftKeyboard打開之前)獲取選定的高度。

所以在自定義列表視圖,你有這樣的全局變量:

int lastItemHeight = 0; 

而在活動(或片段,等等),您更新OnClickListener這個值:

edittext.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     // set a new Thread 
     listview.post(new Runnable() { 
      @Override 
      public void run() { 
       // get last visible position of items 
       int lastPosition = listview.getLastVisiblePosition() - 1; 
       // if the view's last child can be retrieved 
       if (listview.getChildAt(lastPosition) != null) { 
        // update the height of the last child in custom listview 
        listview.lastItemHeight = listview.getChildAt(lastPosition).getHeight(); 
       } 
      } 
     }); 
    } 
}); 

注意: there is another possible solution但您必須在列表視圖上設置android:stackFromBottom="true",該列表視圖從底部堆疊其內容。相反,這裏的解決方案可以顯示特定的項目,而不會強迫內容從底部開始,並使用默認的列表視圖的行爲。

備註:(爲了以防萬一)不要忘記在清單中添加android:windowSoftInputMode="adjustResize"

相關問題