android - tesis - Calcule el tamaño de una vista de lista o cómo decirle que se expanda por completo
tesis sobre youtube pdf (12)
Actualmente estoy tratando de usar un ListView dentro de ScrollView. Sé por lo que he leído que esto es menospreciado, pero estoy tratando de expandir completamente el ListView al mostrar todas sus filas, por lo que no es necesario desplazarse. Sin embargo, he estado luchando con la forma de decirle al ListView que se expanda por completo para mostrar todas sus filas, ya que necesita una altura definida. ¿Alguien sabe de una manera de calcular la altura de un ListView completamente expandido antes de que se dibuje?
Este problema se debe principalmente al hecho de que no puede poner una vista desplazable dentro de otra vista desplazable. Estoy de acuerdo con el hecho de que ListView no podrá desplazarse, siempre que pueda expandirlo para mostrar todas sus filas. No puedo hacer esto, sin embargo, sin poder darle una altura definida, que parece que necesitaría calcular.
Consulte la URL a continuación para ver un boceto (soy un usuario nuevo, así que no puedo publicar uno). Muestra que mi diseño completo es demasiado grande para la pantalla "física" y necesita desplazarse para mostrar el resto de la lista y los botones en la parte inferior. Estoy tratando de comunicar que la pantalla "virtual" es demasiado grande para caber en una pantalla incluso sin el ListView allí.
¡Atención! La forma correcta de calcular la altura no es
params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0);
Tenemos que agregar la altura de cada (menos uno) altura del divisor.
if(oldCount > 0 && getCount() > 0)
params.height = getCount()
* (getChildAt(0).getHeight() + getDividerHeight())
- getDividerHeight();
else
params.height = 0;
Bueno, gracias a Rudy, sus sugerencias fueron muy útiles. Aquí es cómo se puede implementar.
1) Crea una nueva clase que extienda ListView:
package com.example.android.views;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ListView;
public class ExpandedListView extends ListView {
private android.view.ViewGroup.LayoutParams params;
private int old_count = 0;
public ExpandedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
if (getCount() != old_count) {
old_count = getCount();
params = getLayoutParams();
params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0);
setLayoutParams(params);
}
super.onDraw(canvas);
}
}
2) ... y finalmente agrega la nueva vista a tu archivo de diseño xml:
<com.example.android.views.ExpandedListView
android:id="@+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:padding="0px"
/>
He estado investigando sobre cómo hacer esto, y aunque la pregunta ya ha sido respondida, me gustaría ofrecer una solución que creo que es mejor:
Al mirar el código fuente de ListView, puede ver lo siguiente dentro del código onMeasure (...):
if (heightMode == MeasureSpec.AT_MOST) {
// TODO: after first layout we should maybe start at the first visible position, not 0
heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
}
Así que simplemente llame a la medida listView y pase MeasureSpec.AT_MOST para la altura en lugar de MeasureSpec.UNSPECIFIED habitual.
Hago lo siguiente para medir una vista de lista y colocarla dentro de una ventana emergente:
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels, MeasureSpec.AT_MOST);
mCatalogView.measure(widthMeasureSpec, heightMeasureSpec);
mPopup.setWidth(mCatalogView.getMeasuredWidth());
mPopup.setHeight(mCatalogView.getMeasuredHeight());
La forma correcta de calcular la altura es precisamente:
int height = 0;
for (int i = 0; i < listView.getChildCount(); i++) {
height += listView.getChildAt(i).getMeasuredHeight();
height += listView.getDividerHeight();
}
No debe colocar su ListView en un ScrollView. ListView ya puede desplazarse.
ListView debe expandirse completamente de manera predeterminada, si es lo único en el diseño.
Si no es lo único en el diseño, y desea que ListView se expanda para ocupar todo el espacio disponible, establezca el layout_weight en el ListView en 1, donde todos los demás layout_weight = 0.
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" orientation="vertical">
<TextView id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ListView id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
Editar: El ListView está diseñado para ser desplazable ... el diseño de pantalla que tienes en tu captura de pantalla no parece realmente el "camino de Android".
Sin embargo, si realmente quiere eludir eso, puede intentar inflar una de las filas, obtener su minHeight y multiplicarlo por la cantidad de elementos en el adaptador ListView.
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.label_value_row, null, false);
int height = adapter.getCount() * view.getMinHeight();
Sé que es tarde y ya hay una respuesta, pero si realmente quieres hacer esto, hay una manera fácil:
Crear la vista de lista Artículo con una altura definida
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal" >
<ImageView
android:id="@+id/lvItemSurpriseMeImgRestaurant"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="5dp"
android:contentDescription="@string/restaurantImageDescriptionColon" />
</LinearLayout>
Ahora sabemos que el artículo tiene 100dp
alto, y si conocemos la cantidad de artículos, entonces es muy simple
establece la altura de ListView
literalmente en el valor de NoOfItems
* Height
+ 10dp
extra
Nunca cambiará ya que todas las unidades están en dp
.
Si tiene más de 1 tipo de elemento, calcúlelo con matemática básica y configúrelo
<ListView
android:id="@+id/menuListView"
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_weight="1.0"
tools:ignore="NestedScrolling"
tools:listitem="@layout/menu_item" >
</ListView>
Si quieres un ListView que no se desplace, ¿no podrías usar LinearLayout?
Si tiene artículos con diferentes alturas, necesita usar este método:
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
float px = 300 * (listView.getResources().getDisplayMetrics().density);
item.measure(
View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int height = item.getMeasuredHeight();
totalItemsHeight += height;
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
listView.setLayoutParams(params);
listView.requestLayout();
}
}
funciona bien con cualquier ListView con cualquier elemento
Terminé anulando onDraw()
de ListView y calculando la altura promedio de las filas visibles en la vista y luego estimando la altura real de la lista en función de cuántos elementos hay en el adaptador. Esta estimación ocurre un par de veces hasta que todas las filas sean visibles.
Tomé la función de la respuesta de djunod (la función en clase estática)
calcular el tamaño de la lista
y cambie el método ondraw de la siguiente manera. funciona después de eliminar las operaciones con éxito.
aquí está mi última clase
class ExpandedListView extiende ListView {
private android.view.ViewGroup.LayoutParams params;
private int old_count = 0;
public ExpandedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
if (getCount() != old_count) {
params = getLayoutParams();
old_count = getCount();
int totalHeight = 0;
for (int i = 0; i < getCount(); i++) {
this.measure(0, 0);
totalHeight += getMeasuredHeight();
}
params = getLayoutParams();
params.height = totalHeight + (getDividerHeight() * (getCount() - 1));
setLayoutParams(params);
}
super.onDraw(canvas);
}
}
ahora mi lista de lista se expande después de insertar fila sin desplazamiento. y después de la fila, eliminar este código calcula el tamaño correcto para la vista de lista. no sé cómo está funcionando. pero está funcionando. BR
usar esto será trabajado:
public class ListViewEx extends ListView {
public ListViewEx(Context context) {
super(context);
}
/**
* @param context
* @param attrs
*/
public ListViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 设置不滚动
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return ev.getAction()==MotionEvent.ACTION_MOVE||super.dispatchTouchEvent(ev);
}
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
if (this.isExpanded) {
final int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
final ViewGroup.LayoutParams params = this.getLayoutParams();
params.height = this.getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}