2011-11-29 8 views
5

Tengo un LinearLayout que contiene tanto un ListView como un EditText. Cuando se inicia el teclado en pantalla tocando EditText, el ListView cambia de tamaño para que solo queden los primeros elementos visibles.manteniendo el elemento inferior de ListView visible cuando aparece el teclado

El contexto en el que se usa ListView tiene los últimos elementos visualmente más relevantes que la parte superior, por lo que me gustaría que cambie de tamaño para que la parte inferior permanezca visible, en lugar de la parte superior. ¿Alguna sugerencia?

(Por cierto, la solución actual que estoy usando implica el uso de smoothScrollToPosition, pero el comportamiento de desplazamiento lag hace que este indeseable)

+0

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

Respuesta

-1

Usted debe agregar este atributo en el manifiesto para su actividad y escoger el valor correcto para él (probablemente va a recoger "adjustResize"):

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

No, esto no soluciona el problema: la ventana ya está configurada en el modo adjustResize; es el comportamiento de cambio de tamaño de ListView que no se comporta como se desea. – chrisjrn

+0

chrisjrn, ¿resuelves el problema? –

+0

He probado tu respuesta pero no funciona – FtheBuilder

1

Acabo de resolver un problema similar esta mañana, y pensé que había puesto mi resultado aquí en beneficio de los futuros investigadores. Mi problema era que desplazarme hacia abajo no ayudaba porque lo llamaba antes de que la vista realmente cambiara de tamaño. ¿La solución? Esperar hasta que lo hace el tamaño de cambio mediante el uso de un GlobalLayoutListener

Pasos: 1) aplicar el método siguiente en la actividad de la celebración de la vista de lista

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

2) crear la siguiente clase

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) En su actividad, implemente la interfaz de esta clase. Luego, en su actividad, crear una instancia de esta OnGlobalLayoutListener y configurarlo como el oyente para su Listview

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

4) En su actividad, antes de hacer cambios que afectarán el tamaño de la vista de lista, como mostrar y ocultando otros puntos de vista o añadir cosas a la vista de lista, simplemente dejar que el oyente sabe disposición para desplazarse en la próxima oportunidad

listViewLayoutListener.scrollToBottomAtNextOpportunity(); 
0

Es posible lograr esto con setSelectionFromTop() y anulando onSizeChanged() en una vista de lista personalizada. En su diseño, debe tener un RelativeLayout con un contenedor principal y colocar la vista de lista sobre el texto de edición.

Al crear su propia vista de lista y reemplazar onSizeChange(), podrá obtener la posición del último elemento visible antes del cambio de tamaño de la vista de lista y obtener su nueva altura, para finalmente establecer la posición "anterior" de la lista con un desplazamiento de su altura

Cómo funciona: Su lista colocará el último elemento visible anterior en su parte superior y agregará los píxeles para desplazarlo en su parte inferior, justo encima de su texto de edición.

reemplazar el método y mostrarlo con un desplazamiento, haga lo siguiente:

@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 es un poco de solución, porque no he encontrado cómo conseguir la altura del último artículo antes de que onSizeChanged se llama .Entonces, en el caso de que su vista de lista contenga muchos tipos de elementos (sin la misma altura), prefiero obtener la altura seleccionada cuando ocurre un evento, justo antes de que se abra el Teclado.

Así que en la vista de lista personalizada, tiene esta variable global:

int lastItemHeight = 0; 

Y en la actividad (o un fragmento, lo que sea), se actualiza este valor en 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(); 
       } 
      } 
     }); 
    } 
}); 

Nota: there is another possible solution pero debe establecer android:stackFromBottom="true" en la vista de lista, que apila su contenido desde la parte inferior. En cambio, esta solución aquí puede mostrar un elemento específico sin forzar que el contenido comience desde la parte inferior, con el comportamiento predeterminado de la vista de lista.

Segunda nota: (por si acaso) no olvide agregar android:windowSoftInputMode="adjustResize" en el manifiesto.

Cuestiones relacionadas