Android: Duplicar el elemento View en el grupo ViewGroup

Estoy trabajando en clase que extiende ViewGroup para organizar los elementos de vista para el GridView.

Puedo agregar fácilmente un nuevo artículo de la visión dentro de él cerca:

ImageView view = new ImageView(context); view.setImageBitmap(BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher)); addView(view); 

O eliminar el elemento de vista también es fácil

 removeViewAt(remove_index) 

Cambiar el elemento puede hacerse

 addView(new_index, removeViewAt(old_index)); 

Pero quiero duplicar el elemento Ver cuando un elemento se arrastra sobre el otro. Traté de duplicar el tema por

 addView(getChildAt(index)) 

Y esto muestra el error de excepción

El niño especificado ya tiene un padre. Debe llamar a removeView () en el padre del niño primero

También intenté almacenar todos los elementos de vista en la lista, llamado el método removeAllView () y de nuevo agregó las vistas en clase.

 ArrayList<View> children = new ArrayList<View>(); for (int i = 0; i < getChildCount(); i++){ children.add(getChildAt(i)); } children.add(getChildAt(index)); // duplicate this item removeAllViews(); for (int i = 0; i < children.size(); i++){ addView(children.get(i)); } 

Esto todavía muestra el error de excepción como anteriormente:

El inflado de vista puede funcionar, pero quiero copiar la misma vista sin ir para el recurso externo.

Así que quiero que el método para separar esa vista de ViewGroup padre y hacer copia múltiple (Duplicar) de ello dentro de la clase.

Cualquier ayuda es apreciada.

En primer lugar, está intentando agregar ese mismo objeto de nuevo, lo que realmente no tiene sentido – la nueva vista tiene que ser un objeto separado, tendría que duplicar el original primero, por ejemplo, utilizando el método .clone() .

Pero, por desgracia, incluso si lo hiciste, no podrías agregar la vista clonada al ViewGroup , aquí es por qué.

La excepción que obtiene es el resultado de ViewGroup verificando el padre de View para null Así que, para agregar la vista clonada, tendría que establecer el miembro mParent su vista en null , lo cual no se puede hacer directamente porque el método Que hace que no es público: View.assignParent ()

Puede intentar clonar la View después de llamar a .removeViewAt() para que no tenga un padre en el momento de la clonación, a continuación, agregue la vista original de nuevo a su posición y luego proceda con la adición del clon al lugar requerido, Pero como SD mencionó que tendría que tener algunos problemas con la clonación además de esta manera es muy oscura y se requiere el ViewGroup a relayout 2 veces.

Una mejor solución es asignar una etiqueta a cada vista que contenga la información necesaria para crear otra Vista como esa y usarla cuando necesite clonar.

Yo haría algo como esto:

 public interface ViewCloner { public View clone(Context context); } public static class ImageViewCloner implements ViewCloner { private int mImgResId; public ImageViewCloner(int imgResourceId) { this.mImgResId = imgResourceId; } @override public View clone(Context context) { ImageView view = new ImageView(context); view.setImageBitmap(BitmapFactory.decodeResource( context.getResources(), mImgResId)); // Add the tag to the clone as well, so it, too, can be cloned view.setTag(new ImageViewCloner(mImgResId)); return view; } } // When creating the original view int resId = R.drawable.ic_launcher; ImageView view = new ImageView(context); view.setImageBitmap(BitmapFactory.decodeResource( getResources(), resId)); view.setTag(new ImageViewCloner(resId)); // When cloning the view ViewCloner vc = (ViewCloner) getChildAt(index).getTag(); View clone = vc.clone(getContext()); addView(clone); 

Para cualquier vista o grupo adicional que desee utilizar en lugar de la única cosa ImageView sólo crear otra aplicación de ViewCloner y que está bien para ir sin tener que modificar el comportamiento de su contenedor.

Duplicar un objeto requiere una buena implementación del método clone() .

No creo que las clases de vista de Android lo hagan bien, por lo que puede que necesite crear un tipo personalizado de vista que pueda producir una copia de sí mismo. View class tiene métodos para guardar / restaurar estado: con onSaveInstanceState () y onRestoreInstanceState() que puede utilizar para copiar el estado de View.

Además, tendrá que cuidar a los oyentes de eventos registrados en esa vista.

Gracias por la respuesta SD e Ivan.

Después de la larga pausa pude encontrar mi propia respuesta manteniendo esas soluciones en mi mente.

El método Clone directamente no se puede agregar en la vista y agregar la interfaz hace más compleja para los códigos.

Incluso mi requisito era clonar la vista para la cual la imagen se agregó dinámicamente y la fuente era desconocida.

Algunos truco debe hacerse sólo para copiar la vista, en primer lugar obtener la otra instancia de vista y copiar las propiedades tales como dibujable, fondo, relleno, etc en el segundo.

La solución fue mucho más fácil usando los siguientes códigos.

 // Create new Instance of imageView ImageView view = new ImageView(context); // Get the original view ImageView org = (ImageView)getChildAt(index); // Copy drawable of that image view.setImageDrawable(org.getDrawable()); // Copy Background of that image view.setBackground(org.getBackground()); // Copy other required properties .... // Lastly add that view addView(view); 
  • Android: fitsSystemWindows no funciona
  • Diferencia real entre TextView y Button
  • Lienzo en no actualizar
  • Ejemplo de uso de ContentLoadingProgressBar
  • Debe ser uno de: View.VISIBLE, View.INVISIBLE, View.GONE
  • Problema con revelación circular y CircularRevealLibrary en Android
  • Circular ImageView
  • Cómo agregar varias vistas al gestor de ventanas en Android
  • ANR en el método SurfaceView "onTouchEvent (...)" en Android
  • ¿Por qué http://schemas.android.com/apk/res-auto "sólo funciona para proyectos de biblioteca?
  • Diferencia entre SurfaceView y ImageView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.