¿Cómo actualizar un GridView?
Tengo un GridView que es bastante similar al tutorial de Google, excepto que quiero agregar el ImageViews en tiempo de ejecución (a través de una subactividad). Los resultados están bien, pero el diseño de la vista está desordenado: El GridView no llena el contenido de su padre, ¿qué debo hacer para diseñarlo correctamente?
Aquí el código de añadir a los niños:
- Android Lollipop Diseño del material Desbordamiento Menú Icon color
- Android.view.InflateException: Archivo XML binario línea # 10: Error al inflar fragmento de clase
- ¿Cómo agregar un grupo de radio a los botones de radio dentro de una tabla?
- CollapsingToolbarLayout | Aspectos de desplazamiento y diseño
- ADT de Android: no fragment_main.xml, sólo activity_main.xml
public void initializeWorkbench(GridView gv, Vector<String> items) { Prototype.workbench.setDimension(screenWidth, divider.height()+workbenchArea.height()); Prototype.workbench.activateWorkbench(); // this measures the workbench correctly Log.d(Prototype.TAG, "workbench width: "+Prototype.workbench.getMeasuredWidth()); // 320 Log.d(Prototype.TAG, "workbench height: "+Prototype.workbench.getMeasuredHeight()); // 30 ImageAdapter imgAdapter = new ImageAdapter(this.getContext(), items); gv.setAdapter(imgAdapter); gv.measure(screenWidth, screenHeight); gv.requestLayout(); gv.forceLayout(); Log.d(Prototype.TAG, "gv width: "+gv.getMeasuredWidth()); // 22 Log.d(Prototype.TAG, "gv height: "+gv.getMeasuredHeight()); // 119 Prototype.workbench.setDimension(screenWidth, divider.height()+workbenchArea.height()); } }
ActivateWorkbench, setDimension y measure en el workbench (LinearLayout sobre GridView):
public void activateWorkbench() { if(this.equals(Prototype.workbench)) { this.setOrientation(VERTICAL); show = true; measure(); } } public void setDimension(int w, int h) { width = w; height = h; this.setLayoutParams(new LinearLayout.LayoutParams(width, height)); this.invalidate(); } private void measure() { if (this.getOrientation() == LinearLayout.VERTICAL) { int h = 0; int w = 0; this.measureChildren(0, 0); for (int i = 0; i < this.getChildCount(); i++) { View v = this.getChildAt(i); h += v.getMeasuredHeight(); w = (w < v.getMeasuredWidth()) ? v.getMeasuredWidth() : w; } if (this.equals(Prototype.tagarea)) height = (h < height) ? height : h; if (this.equals(Prototype.tagarea)) width = (w < width) ? width : w; } this.setMeasuredDimension(width, height); }
El constructor ImageAdapter:
public ImageAdapter(Context c, Vector<String> items) { mContext = c; boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // We can read and write the media mExternalStorageAvailable = mExternalStorageWriteable = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // We can only read the media mExternalStorageAvailable = true; mExternalStorageWriteable = false; } else { // Something else is wrong. It may be one of many other states, but // all we need // to know is we can neither read nor write mExternalStorageAvailable = mExternalStorageWriteable = false; } if (mExternalStorageAvailable && mExternalStorageWriteable) { for (String item : items) { File f = new File(item); if (f.exists()) { try { FileInputStream fis = new FileInputStream(f); Bitmap b = BitmapFactory.decodeStream(fis); bitmaps.add(b); files.add(f); } catch (FileNotFoundException e) { Log.e(Prototype.TAG, "", e); } } } } }
Y el diseño xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:gravity="bottom" android:paddingLeft="0px" android:paddingTop="0px" android:paddingRight="0px"> <com.unimelb.pt3.ui.TransparentPanel android:id="@+id/workbench" android:layout_width="fill_parent" android:layout_height="10px" android:paddingTop="0px" android:paddingLeft="0px" android:paddingBottom="0px" android:paddingRight="0px"> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:columnWidth="90dp" android:numColumns="auto_fit" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" android:gravity="center" /> </com.unimelb.pt3.ui.TransparentPanel> </LinearLayout>
- ¿Cómo obtengo el efecto de rizo para los elementos de menú en mi barra de herramientas personalizada?
- Android: popupBackground no funciona para menús contextuales
- Cómo aumentar el tamaño de transport.dump de 256 bytes a 512 o más bytes en KSOAP2?
- Líneas de alineación izquierda y derecha dentro de Listview?
- Cómo llamar a los colores de los recursos de forma dinámica en Android?
- AutoCompleteTextView fondo / color de primer plano
- Gradle falla: nodo no soportado 'item' en ids.xml
- Cómo crear una tabla en Android con varias columnas?
El GridView tiene un método invalidateViews ().
Cuando se llama a este método: "todas las vistas a reconstruir y volver a dibujar". http://developer.android.com/reference/android/widget/GridView.html
Creo que esto es lo que necesitas
Debe, en primer lugar, indicar al adaptador que notifique que los datos han cambiado y vuelve a ajustar el adaptador a la red
adapter.notifyDataChanged(); grid.setAdapter(adapter);
Esto puede ser útil. Actualizar un gridview de miniaturas de imagen de libro después de una eliminación se ejecuta en un elemento. Utilizando adapter.notifyDataChanged (); Como se mencionó anteriormente no funcionó para mí como se llama en mi adaptador.
//this is a call that retrieves cached data. //your constructor can be designed and used without it. final Object data = getLastNonConfigurationInstance();
Lo esencial es recargar el adaptador y vincularlo a la misma vista.
//reload the adapter adapter = new BooksAdapter(MyBooks.this, MyBooks.this, data, show_collection ); grid.invalidateViews(); grid.setAdapter(adapter);
@flyerz @snagnever
Juntos, ustedes lo tienen. Debería ser:
adapter.notifyDataChanged(); grid.invalidateViews();
Esto marcará el adaptador que sus datos han cambiado, que luego se propagará a la cuadrícula cada vez que se invoque el método invalidateViews ().
Me alegro de haber encontrado esta pregunta porque no pude averiguar cómo agregar elementos a la cuadrícula después de que se haya procesado.
Ninguna de estas respuestas funcionó realmente para mí y tuve que aplastarlas todas juntas. Para obtener realmente el GridView para actualizar, necesita hacer esto:
adapter.notifyDataChanged(); grid.invalidateViews(); grid.setAdapter(adapter);
Espero que esto ayude a cualquiera que no pueda conseguir que las otras soluciones funcionen.
No debe llamar a invalidateViews
y setAdapter
para actualizar su grid view
. Esto no es una buena idea para mantener la grid view
actualizada, si se actualiza de esa manera que costaría mucho tiempo y memoria.
Si tiene la oportunidad de ver el método getView
, verá que convertView
se crea una sola vez. Cuando llama a notifyDataChanged
, actualizará esta vista. Mientras que si llama a invalidateViews
, las vistas creadas anteriormente se recrearán. Esta no es una buena solución.
Su método getView
se llama cuando llama a notifyDataChanged
. Así que su método getView debe ser algo como el código de abajo.
public List list; public class SimpleItemViewHolder extends Object { public TextView textView; public ImageView imageView; } public View getView(int position, View convertView, ViewGroup parent){ View itemView = convertView; SimpleItemViewHolder viewHolder; if(convertView==null) { viewHolder = (SimpleItemViewHolder)itemView.getTag(); }else{ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); itemView = inflater.inflate(R.layout.layout_name, null); TextView labelField = (TextView) itemView.findViewById(R.id.label_field); labelField.setText(list.get(position).Name); //Typeface boldFont = Typeface.createFromAsset(context.getAssets(), "fonts/Font-Bold.ttf"); //labelField.setTypeface(boldFont); ImageView imageView = (ImageView) itemView.findViewById(R.id.image_view); //Bitmap bitmap = init your bitmap here; //imageView.setImageBitmap(bitmap); viewHolder = new SimpleItemViewHolder(); viewHolder.imageView = imageView; viewHolder.textView = labelField; itemView.setTag(viewHolder); } //don't create new views, instead use previous ones and update them. viewHolder.textView.setText(list.get(position).Name); //viewHolder.imageView.setImageBitmap(your_bitmap); return itemView; }
adapter.notifyDataChanged();
Puede que no funcione sólo porque los datos del adaptador están obsoletos (si Actividad o fragmento no se destruyó y se han sentado en la pila trasera, por ejemplo).
Por lo tanto, si en primer lugar actualizar los datos, a continuación, después de que va a trabajar.
Usted está colocando el GridView
dentro de com.unimelb.pt3.ui.TransparentPanel
que es 10px
altura.
- No deberías usar
px
, deberías usardp
. - Cambia el
android:layout_height="10px"
aandroid:layout_height="fill_parent"
En su adaptador:
class MAdapter extends BaseAdapter{ List<Objects> mObjects; ... public void clearAdapter(){ mObjects.clear(); } public void addNewValues(List<Objects> mObjects){ this.mObjects = mObjects; } ... } adapter.clearAdapter(); // clear old values adapter.addNewValues(MObjects); adapter.notifyDataChanged();
- ¿Usando OKHttp, cuál es la diferencia entre la petición síncrona en AsyncTask y la petición asíncrona de OKhttp?
- Acceso a WebView desde otra función en la clase MainActivity