studio programacion móviles libro ejemplo dinamico desarrollo curso aplicaciones android listview textview scrollview

programacion - Las filas de ListView de Android en ScrollView no se muestran completamente-recortadas



manual de programacion android pdf (9)

Es una práctica MALA encapsular ListView dentro de un ScrollView porque ListView en sí mismo contiene capacidades de desplazamiento. Debería implementar una solución que no contenga dicha jerarquía de vistas y espero que haga la magia :)

Encontré un problema al insertar un ListView dentro de ScrollView, o al menos es de allí de donde creo que proviene el problema. El elemento ListView es bastante simple:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item_root" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/general_background_list_middle" android:paddingTop="4dp" android:paddingBottom="4dp" android:paddingRight="0dp" android:paddingLeft="0dp"> <ImageView android:id="@+id/chat_friends_avatar" android:layout_width="45dp" android:layout_height="45dp" android:layout_marginLeft="7dp" android:layout_marginRight="8dp" android:paddingRight="0dp" android:paddingLeft="0dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:src="@drawable/friends_icon_avatar_default"/> <TextView android:id="@+id/chat_message_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/chat_friends_avatar" android:layout_alignParentTop="true" android:layout_marginRight="35dp" android:maxLines="10" android:textSize="12dp"/> <TextView android:id="@+id/chat_friend_name" android:layout_width="140dp" android:layout_height="wrap_content" android:layout_marginTop="3dp" style="@style/SubText" android:layout_toRightOf="@id/chat_friends_avatar" android:layout_below="@id/chat_message_text" /> <TextView android:id="@+id/chat_message_time" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginRight="8dp" android:layout_marginTop="3dp" style="@style/SubText" android:layout_alignParentRight="true" android:layout_below="@id/chat_message_text" /> </RelativeLayout>

Sin embargo, cuando incrusto una lista de dichos elementos en un ScrollView, entre algunos otros elementos, las filas no se muestran completamente, sino que se recortan (consulte la imagen a continuación) si el texto está envuelto. ListView se instancia de la siguiente manera en ScrollView:

<ListView android:id="@+id/info_chat_listview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:cacheColorHint="@color/frame_background_color" android:clickable="false" android:divider="@null" android:footerDividersEnabled="false" android:focusable="false" > </ListView>

Si la altura de ListView está configurada en "wrap_content", solo se muestra el primer elemento. Es por eso que estoy usando un método para calcular la altura de las filas de la lista:

private int getCommentsListHeight() { if (mChatAdapter != null && mChatAdapter.getCount() != 0) { if (mChatList != null) {// && mCommentsListItemHeight == 0) { mCommentsListItemHeight = 0; for (int i = 0; i < mChatAdapter.getCount(); i++) { // Get view item height View viewItem = mChatAdapter .getView(i, new View(OnAirActivity.this), mChatList); viewItem.measure(0, 0); Logger.d(LOGTAG, "View " + i + " measured height = " + viewItem.getMeasuredHeight()); mCommentsListItemHeight += viewItem.getMeasuredHeight(); } } //return mChatAdapter.getCount() * mCommentsListItemHeight; return mCommentsListItemHeight; } else { return 0; } }

Desafortunadamente, en el caso de que el texto dentro de TextView esté envuelto, incluso en varias líneas, la altura del elemento de fila devuelto por el método getMeasuredHeight () es constante. Además, getLineCount () llamado en TextView dentro del elemento row devuelve 1 incluso si el texto está envuelto.

Por otro lado, si este ListView está incrustado en LinearLayout, todo funciona bien y la lista completa se muestra sin recorte.

¿Tiene alguna sugerencia sobre qué podría estar mal aquí? Realmente no me gusta la idea de medir manualmente la altura de los elementos de la lista y aparentemente no funciona, pero ¿por qué no puede Android estirar muy bien el ListView dentro del ScrollView para que quepa todo allí?

Lista recortada:


Esto funciona para mí

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/activity_vertical_margin"> <TextView android:id="@+id/tv_status" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="17sp" android:text="@string/text_list_devices" /> <ListView android:id="@+id/lv_paired" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/activity_vertical_margin" android:cacheColorHint="#00000000" android:layout_above="@+id/signup_t" android:layout_below="@id/tv_status" /> <Button android:id="@+id/signup_t" style="?android:textAppearanceSmall" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:textColor="@android:color/white" android:layout_alignParentBottom="true" android:text="Print All Records" android:typeface="sans" android:layout_marginLeft="45dp" android:layout_marginRight="45dp" android:textSize="24sp" android:background="@drawable/selector_for_button" android:textStyle="bold" /> </RelativeLayout>


Puedo ver que ListView está dentro de ViewPager; Otro enfoque simple para resolver este problema es agregar la app:layout_behavior="@string/appbar_scrolling_view_behavior" a ViewPager en su diseño xml como se ve a continuación.

<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

Para evitar el mismo comportamiento en la parte inferior de la lista, también puede agregar android:layout_marginBottom="?attr/actionBarSize" a ViewPager como tal

<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_marginBottom="?attr/actionBarSize"/>

Esto llega tarde, pero espero que ayude a cualquier otra persona.


Tomé la recomendación de no usar un elemento ListView dentro de ScrollView to heart y decidí usar un método de fuerza ligeramente bruta para lograr lo que necesito. Como hay una cantidad constante de hasta cinco filas de listas que deben mostrarse, eliminé la instanciación de ListView del archivo xml y la reemplacé con cinco instancias de filas:

<include android:id="@+id/info_comment_1" layout="@layout/chat_single_message" /> <include android:id="@+id/info_comment_2" layout="@layout/chat_single_message" /> <include android:id="@+id/info_comment_3" layout="@layout/chat_single_message" /> <include android:id="@+id/info_comment_4" layout="@layout/chat_single_message" /> <include android:id="@+id/info_comment_5" layout="@layout/chat_single_message" />

En la clase Activity, declaro cinco marcadores de posición para estas vistas:

private RelativeLayout mChatMessages[] = new RelativeLayout[COMMENTS_NUMBER];

e inicializarlos con:

mChatMessages[0] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_1); mChatMessages[1] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_2); mChatMessages[2] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_3); mChatMessages[3] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_4); mChatMessages[4] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_5);

Luego, cada vez que se recibe un nuevo mensaje, utilizo ChatAdapter (el mismo que utilicé para ListView anteriormente) y llamo a su método getView ():

protected void updateChatMessages() { int msgCount = mChatAdapter.getCount(); for (int i = 0; i < COMMENTS_NUMBER; i++) { if (msgCount <= i) { mChatMessages[i].setVisibility(View.GONE); } else { mChatMessages[i] = (RelativeLayout) mChatAdapter.getView(i, mChatMessages[i], null); mChatMessages[i].setVisibility(View.VISIBLE); } } }

No vuelvo a inflar las vistas pariculat una vez más, ya que lo único que cambia es el contenido de cada fila, no el diseño. Esto significa que no hay una penalización de rendimiento aquí.

Esto es básicamente una implementación manual de un ListView con un número máximo limitado de elementos. Esta vez, sin embargo, ScrollView puede caber muy bien y no se recorta nada.

Para un número dinámico de filas, el enfoque sugerido por Layko podría emplearse con las vistas que se instanciaron programáticamente y se agregaron a LinearLayout dentro de ScrollView.


Tuve el mismo problema en mi proyecto. Necesita crear LinearLayout simple dentro de ScrollView . Después de eso, necesita crear una nueva Vista con su elemento de vista de lista xml usando LayoutInflater . Después de la creación, ponga todos los datos en la nueva Vista y agregue a LinearLayout como vista secundaria :

linearLayot.addView(newView, position_you_need).

Espero que te ayude!


Tuve un problema similar. tengo un

RelativeLayout listView includeLayout

donde incluyo un poco de navegación inferior debajo de la listaVer con esto

<include android:id="@+id/includeLayout" layout="@layout/bottom_nav_bar"

y mi listView fue recortado, sin tomar la altura completa disponible entre el encabezado y el navegador inferior. Probé varias configuraciones xml sugeridas en este y otros hilos, pero lo que funcionó para mí fue agregar

android:layout_alignBottom="@+id/includeLayout"

a mi listaVer. Eso pareció llevar el listView a la parte superior del navegador inferior, de modo que el listView ahora usa la altura completa disponible (y se desplaza según sea necesario).


Utilice este método creado por https://.com/users/205192/dougw

public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); }


pruébalo ... después de crear toda la vista, agrega la siguiente línea para la ubicación de ScrollView en la pantalla (x, y)

ScrollView scrollView = (ScrollView)findViewById(R.id.scrollView); scrollView.smoothScrollTo(0,0);// top location zero index


Aquí recurso de diseño principal con ScrollView:

<ScrollView android:layout_height="fill_parent" android:layout_width="fill_parent"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/parentLayout"/> </ScrollView>

Aquí el código para insertar elementos:

parentLayout.removeAllViews(); LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); for (int i = comments.size() - 1; i >= 0; i--) { CommentInfo comment = comments.get(i); View view = inflater.inflate(your_resource_id, null, false); TextView commentsContent =(TextView)view.findViewById(R.id.commentContent); if (commentsContent != null) { String data = String.format("%s (by %s, %s)", comment.getCommentText(), comment.getUserName(), commentsContent.setTextSize(st.getTextSize()); commentsContent.setText(data); } parentLayout.addView(view, 0); }