¿Cuál es la forma más rápida de agregar varias vistas a un LinearLayout?
Tengo una vista LinearLayout
que ya contiene varios elementos. Quiero agregar mucho más vistas a él, programmatically. Y debido a que esto está dentro de un ScrollView
, todo se desplazará.
Así que lo que hago es ir a través de mi lista, y añadir nuevas instancias de mi personalizado Ver a ella. Esa vista personalizada infla un diseño XML y añade algunos métodos.
- ¿Es posible usar inflador de vista para inflar artículos individuales?
- El niño especificado ya tiene un error de padre en la vista inflado
- ¿Cómo agregar vista como fondo a la superficie?
- Biblioteca de soporte de Android SearchView xml atributos queryHint e iconifiedByDefault no funciona
- Cómo configurar un mapa de bits como fondo para una vista Android API 10-18?
Este enfoque funciona bien. El problema es que es súper lento, incluso sin ningún código loco … una lista con 10 elementos tarda unos 500 ms para crear instancias. Como punto de vista de la experiencia del usuario, esto es difícil de tragar.
Mi pregunta es, ¿es este el enfoque correcto / mejor? Android parece tardar mucho tiempo en inflar el diseño, aunque "R.layout.my_list_item" es super simple. Me pregunto si hay una manera de tal vez para reutilizar "inflado" diseños de vistas adicionales, un poco de almacenamiento en caché el análisis más complejo?
He intentado hacer esto con un ListView
(y el adaptador y un envoltorio) y parece ser mucho más rápido. El problema es que no puedo usar un ListView
simple; mi diseño es más complejo que una simple lista (el propio LinearLayout
contiene iconos personalizados adicionales y tiene otro padre con vistas aún más antes de que esté envuelto por el ScrollView
).
¿Pero hay una manera de utilizar un adaptador para un LinearLayout? ¿Sería eso más rápido que intentar agregar las vistas yo mismo?
Cualquier ayuda es apreciada. Me encantaría hacer esto más rápido.
El código sigue.
Actividad principal:
// The LinearLayout that will contain everything lineList = (LinearLayout) findViewById(R.id.lineList); // Add a lot of items for testing for (int i = 0; i < 10; i++) { addListItem("Item number " + i); } protected void addListItem(String __title) { MyListItem li; li = new MyListItem(this); li.setTitle(__title); lineList.addView(li); }
MyListItem:
public class MyListItem extends RelativeLayout { protected TextView textTitle; public MyListItem(Context __context) { super(__context); init(); } public MyListItem(Context __context, AttributeSet __attrs) { super(__context, __attrs); init(); } public MyListItem(Context __context, AttributeSet __attrs, int __attrsdefStyle) { super(__context, __attrs, __attrsdefStyle); init(); } protected void init() { // Inflate the XML layout LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.my_list_item, this); // Create references textTitle = (TextView)findViewById(R.id.textTitle); } public void setTitle(String __text) { textTitle.setText(__text); } }
Lo que estoy tratando de lograr es esto. Considere esta disposición:
Este diseño es un FrameLayout
(cuadro exterior) que contiene un ImageView
(en gris), un TextView
(rectángulo interior, en la parte superior) y un LinearLayout
(rectángulo interior, en la parte inferior). Este rectángulo LinearLayout
es el que estoy poblando dinámicamente con unos pocos elementos.
Después de que lo MyListItem
, quiero que el resultado final sea este (donde cada nuevo rectángulo es una nueva instancia de MyListItem
):
Es decir, todo es desplazable (la imagen de fondo, por ejemplo, está alineada en la parte superior). El LinearLayout
no es desplazable por sí mismo (todo lo demás sigue) por lo que un ListView
, de lo que sé, no funcionaría muy bien en mi caso.
- Actualizar vista en tiempo de ejecución en Android
- GetActionView () de mi MenuItem return null
- ¿Hay una manera de crear el stackoverfow "Etiquetas" EditText / Campo de entrada en Android?
- Android: Elementos de interfaz de usuario sobre capa de lienzo
- OnMeasure (): wrap_content, ¿cómo puedo saber el tamaño para envolver?
- ¿Por qué obtengo un error al intentar establecer el contenido de un tabspec en android?
- Android Multiple SurfaceViews
- Cómo hacer que SearchView pierda el foco y se contraiga al hacer clic en otra parte de la actividad
3 Opciones:
-
Reemplace todo con un ListView, con el otro padre y los iconos personalizados como una vista de encabezado para el ListView. ListView es más rápido, ya que sólo crea Vistas según las necesidades.
-
Programe crear el contenido de my_list_item en lugar de inflar, podría ser más rápido
-
El uso de ViewStubs puede permitirle cargar vistas bajo demanda.
-
Tal vez no es la carga de las vistas, pero los datos? en cuyo caso preparar los datos en un hilo de fondo.
Un ListView
es el camino a seguir.
Usted dice que su diseño es demasiado complejo. Pero está completamente bien inflar un diseño complejo como un niño. Por ejemplo un diseño que tiene texto y luego un icono:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
Se podría inflar en su adaptador como tal:
@Override public View getView(final int position, View convertView, ViewGroup parent) { LinearLayout root = null; ImageView editImageView; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); root = (LinearLayout)inflater.inflate(R.layout.item, null); } else { root = (LinearLayout)convertView; } }
También puede ser un poco más inteligente con el fin de apoyar una cabecera. Simplemente agregue un cheque si el índice es la raíz e infla una vista diferente. Dado que el encabezado es el único que es diferente que todavía se aprovechan de todas las otras filas que se reutilizan. Incluso puede pre-inflar y almacenar el encabezado y reutilizarlo para deshacerse completamente de la inflación.
Sólo usa un ListView!
Es el más fácil de configurar y más fácil de mantener. Defina un diseño XML para la Lista-Fila y un diseño XML para la Vista que contiene toda la Lista. El ListAdapter hace el resto para usted.
Sólo cree un:
List<HashMap<String, String>> services = new ArrayList<HashMap<String, String>>();
… y recorra sus datos para agregar tantos elementos como desee al mapa. A continuación, establezca este mapa en su ListAdapter. Ya sea 10 elementos o 100 elementos, el ListAdapter creará una lista con muchos elementos.
Ejemplo:
public void updateProductList(String searchTerm) { createOrOpenDB(this); Cursor cursor = (searchTerm!=null)? dbAdapter.fetchWhere(TBL_NAME, KEY_NAME+" LIKE '%"+searchTerm+"%'") : dbAdapter.fetchAll(TBL_NAME); int rows = cursor.getCount(); if (rows<=0) return; services.clear(); //clear current list for (int i=0; i<rows; i++) { HashMap<String, String> map = new HashMap<String, String>(); cursor.moveToPosition(i); map.put(KEY_NAME, "" + cursor.getString(cursor.getColumnIndex(KEY_NAME))); map.put(KEY_DESC, "" + cursor.getString(cursor.getColumnIndex(KEY_DESC))); map.put(KEY_COST, "" + cursor.getDouble(cursor.getColumnIndex(KEY_COST))); services.add(map); } cursor.close(); closeDB(); ListAdapter adapter = new SimpleAdapter(this, services, R.layout.products_view_row, new String[] {KEY_NAME, KEY_DESC, KEY_COST}, new int[] {R.id.listViewText1, R.id.listViewText2, R.id.listViewText3}); setListAdapter(adapter); }
- FragmentPagerAdapter problemas y problemas: Constructor Undefined
- ¿Dónde están las opciones de línea de comandos adicionales en Android Studio versión 1.5.1 para el emulador