![]() |
|
Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android |
«
Tema Anterior
|
Siguiente tema
»
|
Herramientas |
#1
|
||||
|
||||
![]()
Invoco a @kriogeN y @mocelet !! jaja
Buenas tardes compañeros, hace un tiempo me ayudásteis mucho en el hilo: http://www.htcmania.com/showthread.php?t=1052875 Me han pedido un pequeño cambio pero me cuesta tanto que llevo todo el día modificando cosas y no logro hacerlo funcionar. El problema que encuentro es que tengo un custom ArrayAdapter, gracias al cual creo una línea con varios campos cada vez que el usuario pulsa un botón para añadir "Conceptos". Todo esto se basa en algo que me enseñásteis, y es en el modelo vista controlador, así que tengo un xml que es el que modela los campos que se muestran, luego el adapter en sí que controla la lógica, y un array donde se contienen realmente los datos. Esta es la parte donde se maneja el comportamiento de uno de los campos, el que contiene el nombre del concepto: [php]final AutoCompleteTextView concepto = (AutoCompleteTextView) item.findViewById(R.id.conceptoId); item.setTag(concepto); concepto.setText(datos.get(pos).getNombre()); concepto.addTextChangedListener(new TextWatcher() { @override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @override public void onTextChanged(CharSequence s, int start, int before, int count) { } @override public void afterTextChanged(Editable s) { datos.get(pos).setNombre(concepto.getText().toStri ng()); if (datos.get(pos).getNombre().equals("")) { if (datos.size() > 1) { datos.remove(pos); notifyDataSetChanged(); } } } }); [/php]No tengo problemas en editar el adapter para manejar los datos como quiera, de hecho tengo un AutoCompleteTextView en uno de los campos y al seleccionar un item de la lista autocompleto otros campos recuperando datos de una base de datos. Sin embargo lo sé cómo actar sobre el campo en sí mismo. Esta es la lógica que controla esto último [php]//Catch selected producto to fill details concepto.setOnItemClickListener(new AdapterView.OnItemClickListener() { @override //ATTENTION: This position variable can easily confuse with the main one. "pos" is the position from main getView, "position" is the relative to this function public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Getting the selected item to seek for other information of the producto String producto = adapter.getItem(position); //Log.d(TAG, "Estoy dentro del click!!"); Cursor cursorProducto = db.getFromProducto(producto); if (cursorProducto != null && cursorProducto.moveToFirst()) { datos.get(pos).setId(Integer.parseInt(cursorProduc to.getString(cursorProducto.getColumnIndex("id"))) ); datos.get(pos).setCantidad(1); datos.get(pos).setNombre(cursorProducto.getString( cursorProducto.getColumnIndex("nombre"))); datos.get(pos).setDescripcion(cursorProducto.getSt ring(cursorProducto.getColumnIndex("nombre"))); //Copying nombre to descripcion by default datos.get(pos).setPrecio(Double.parseDouble(cursor Producto.getString(cursorProducto.getColumnIndex(" precio_publico")))); notifyDataSetChanged(); } } }); return(item); }[/php] Qué quiero conseguir: Tras seleccionar uno de los items, y por tanto autocompleto otros datos, bloquear ese campo para que ya no sea editable. He tratado en la parte del programa que véis al final hacer: Código:
concepto.setEnabled(false); Agradezco de antemano cualquier ayuda ![]() Última edición por Godlike Día 24/01/16 a las 16:36:52 |
|
#2
|
||||
|
||||
Cuando en Android buscas por identificador solo te devuelve una view. Y si buscas dentro de una fila (item.findView...) no te va a devolver views que estén en otras filas.
Así que el concepto.setEnabled(false) que mencionas se estará ejecutando en todas las filas porque la comprobación de la condición para que esté enabled o no será incorrecta. |
Gracias de parte de: | ||
#3
|
||||
|
||||
Cita:
El problema que me encuentro es exactamente el que mencionas, me he explicado quizá un poco mal pero has comprendido el problema perfecto. ¿De qué manera podría entonces acceder a ese campo en concreto? porque entiendo que se debe poder no? no sé cómo harán si no muchos juegos Android jaja Gracias de nuevo |
#4
|
||||
|
||||
Me pierdo un poco entre conceptos, items y campos.
Ya que haces un notifyDataSetChanged() al autocompletar los datos a partir de la base de datos, se va a ejecutar otra vez el getView del adaptador. Es ahí donde tendrás que ver si llamar al setEnabled con true o con false. Esto es igual que cuando pones el texto, no buscas el campo, actualizas los datos y el campo refleja la información. Si no tienes información suficiente en el array de datos para determinar si hay que habilitar o no la edición tendrás que añadir otro método del tipo setAutocompleted(true/false) para saber si esos datos los ha metido el usuario o se han generado automáticamente y no pueden editarse. Cuando sea por autogeneración haces un datos.get(pos).setAutocompleted(true) y cuando sea por el usuario lo mismo con false. Así cuando tengas que pintar la celda en getView después de autocompletar lees el valor del boolean y ya sabes si hay que habilitar la edición o no. |
Gracias de parte de: | ||
#5
|
||||
|
||||
Cita:
muchas gracias por tu ayuda. Siento el lío, no quiero inundarte con código porque demasiado que ayudas a tanta gente, pero por favor si lo prefieres para poder entender mejor lo que es cada cosa sólo dímelo. De todas formas el tema es justo el que comentas, es decir, para mi el problema no es saber en qué momento lanzar la acción de establecer el campo como setEnabled(false), sino precisamente cómo actuar sobre ese campo. Comentas que "Es ahí donde tendrás que ver si llamar al setEnabled con true o con false. Esto es igual que cuando pones el texto, no buscas el campo, actualizas los datos y el campo refleja la información." Pero es exactamente ahí donde fallo, es decir, yo sé cómo modificar ese array "datos" porque lo tengo, y cuando leo ymodifico el valor de cualquier posición de este array de datos, la aplicación los muestra en la vista tras indicarle que se ha actualizado (notifyDataSetChanged()), pero si accedo a un dato de esta lista no puedo establecer setEnabled(false) porque no tiene sentido sobre un valor, sino sobre la vista en sí, pero no sé cómo modificar el campo, la vista (el getView) estando dentro del adapter. Probablemente sea una chorrada pero es eso justo lo que me falla, es decir, supongamos que tengo suficiente información en los datos como para determinar el setEnabled a true o false (en principio me basta con el evento en que el usuario selecciona una opción de la lista del AutoComplete), pero no sé cómo ejecutar esta tarea: "Así cuando tengas que pintar la celda en getView después de autocompletar lees el valor del boolean y ya sabes si hay que habilitar la edición o no" Suponiendo que sé perfectamente si tengo que habilitar la edición o no, no sé cómo habilitarla sólo para ese campo. No sé si te refieres a que no es tipo un evento sino que cada vez que pinta tendrá que comprobar si ese campo es apto para ser establecido a setEnabled(true) o no, y no hacerlo como si fuera un evento como pretendo. Si te refieres a esto último... comentas de hacer "datos.get(pos).setAutocompleted(true)", esto utilizará este método para cada valor de la lista y por tanto al dibujar y seguir la lógica de establecer a true o false el setEnabled para cada uno?, pensaba que al hacer esta sentencia se aplicaba a todos a la vez, pero tal vez simplemente se aplica a todos uno detrás de otro porque no hay filtro que determine qué hacer. Muchas gracias por tanta ayuda, un saludo! |
#6
|
||||
|
||||
Cita:
En vez de buscar la vista directamente y cambiarla, añade en algún sitio a los datos que ciertos atributos no pueden cambiarse porque han sido autogenerados. Así cuando la lista se refresque con el notifyDataSetChanged (y se llame al getView de cada fila) ya sabes para cada fila qué hay que tener activado o desactivado. Si actualizas la vista "a pelo" pero no guardas nada en ningún sitio, con que el usuario haga scroll y se recicle una fila ya se ha liado porque pierdes el estado y aparecerán campos deshabilitados que no deberían y viceversa. El enabled a true o false de las cosas que puedan cambiar hazlo en el getView. |
Gracias de parte de: | ||
#7
|
||||
|
||||
Cita:
Ahora si que entiendo a lo que te refieres! Me he puesto a ello, te comento los cambios: Al objecto "Concepto" le he añadido un par método como el que comentabas [php]//Others public boolean getAutocompleted (){ return this.autoGenerated; } public void setAutocompleted (boolean estado){ this.autoGenerated = estado; }[/php] Luego en el adapter lo que tengo es [php] private final ArrayList <Concepto> datos;[/php] De forma que una vez clica el usuario sobre un elemento del AutoCompleteTextView... [php] //Catch selected producto to fill details concepto.setOnItemClickListener(new AdapterView.OnItemClickListener() { @override //ATTENTION: This position variable can easily confuse with the main one. "pos" is the position from main getView, "position" is the relative to this function public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Getting the selected item to seek for other information of the producto String producto = adapter.getItem(position); //Log.d(TAG, "Estoy dentro del click!!"); Cursor cursorProducto = db.getFromProducto(producto); if (cursorProducto != null && cursorProducto.moveToFirst()) { datos.get(pos).setId(Integer.parseInt(cursorProduc to.getString(cursorProducto.getColumnIndex("id"))) ); datos.get(pos).setCantidad(1); datos.get(pos).setNombre(cursorProducto.getString( cursorProducto.getColumnIndex("nombre"))); datos.get(pos).setDescripcion(cursorProducto.getSt ring(cursorProducto.getColumnIndex("nombre"))); //Copying nombre to descripcion by default datos.get(pos).setPrecio(Double.parseDouble(cursor Producto.getString(cursorProducto.getColumnIndex(" precio_publico")))); datos.get(pos).setAutocompleted(true); notifyDataSetChanged(); } } }); [/php] Donde se ve que hago datos.get(pos).setAutocompleted(true); La declaración del getView es esta: [php]public View getView(final int position, View convertView, ViewGroup parent){[/php] Bueno pues aunque a continuación, o fuera del setOnItemClickListener (pero aún dentro del getView) haga: [php]View row = convertView; if (datos.get(pos).getAutocompleted) row.setEnabled(false); [/php] No sucede nada, no crashea pero no hace nada de lo que debería hacer... algo se me escapa, ¿podrías echarme una mano por favor? Te lo agradezco muchísimo. Un saludo! |
#8
|
||||
|
||||
El enabled en todo caso tendrás que hacerlo a cada uno de los cuadros de texto que quieras deshabilitar, no a la convertview (row) que sólo es un grupo de vistas.
Y el estado lo tienes que actualizar siempre, tanto para true como para false. Si no se quedará un valor antiguo al reciclar la fila. Última edición por mocelet Día 22/01/16 a las 14:04:02 |
Gracias de parte de: | ||
#9
|
||||
|
||||
Cita:
Cita:
Mil gracias de nuevo |
#10
|
||||
|
||||
Funciona!!!!
Creo que esto resume lo que me decías que hiciera: [php] if (datos.get(pos).getAutocompleted()) concepto.setEnabled(false); else concepto.setEnabled(true); notifyDataSetChanged(); [/php] donde concepto es [php]final AutoCompleteTextView concepto = (AutoCompleteTextView) item.findViewById(R.id.conceptoId);[/php] Qué alegría!!! muchísimas gracias, tu ayuda es inestimable ![]() |
#11
|
||||
|
||||
Solucionado entonces?
Si es asi puedes marcarlo como solucionado ![]() |
Gracias de parte de: | ||
#12
|
||||
|
||||
Hecho! ;)
|
Gracias de parte de: | ||
Respuesta |
![]() |
||||||
|
«
Tema Anterior
|
Siguiente tema
»
|
|
Hora actual: 14:38:47 (GMT +2)
HTCMania: líderes desde el 2007