I am working on class that extends ViewGroup to arrange the View items for the GridView.
I can easily add a new View item inside it by:
ImageView view = new ImageView(context);
view.setImageBitmap(BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher));
addView(view);
Or removing View item is also easy
removeViewAt(remove_index)
Swapping the item can be done by
addView(new_index, removeViewAt(old_index));
but I want to duplicate the View item when one item is dragged over the another one. I tried to duplicate the the item by
addView(getChildAt(index))
And this shows the exception error
The specified child already has a parent. You must call removeView() on the child's parent first
I also tried to store all the view items in the List, called the method removeAllView() and again added the views in class.
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));
}
This still shows the exception error as above:
The view inflating may work but I want to copy the same view without going for the external resource.
So I want the method to detach that View from parent ViewGroup and make multiple copy (Duplicate) of it inside the class.
Any help is appreciated.
First, you're trying to add that same object again, which doesn't really make sense - the new view has to be a separate object, you'd have to duplicate the original first, e.g. using .clone()
method.
But, unfortunately, even if you did, you couldn't add the cloned view to the ViewGroup
, here's why.
The exception you get is the result of ViewGroup
checking your View
's parent for null
So, in order to add the cloned view, you'd have to set your view's mParent
member to null
, which you can't do directly because the method that does that is not public: View.assignParent()
You could try to clone the View
after you call .removeViewAt()
so that it doesn't have a parent at the time of cloning, then add the original view back to it's position and then proceed with adding the clone to the required place, but as S.D. mentioned you'd have to have some hassle with cloning plus this way is very obscure and will require the ViewGroup
to relayout 2 times.
A better solution is to assign a tag to each view that contains the necessary info to create another View like that and use it when you need to clone.
I would do something like this:
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);
For any additional view or group you'll want to use instead of the single ImageView
thing just create another implementation of ViewCloner
and you're good to go without having to modify your container's behaviour.
Duplicating an object requires a good implementation of clone()
method.
I don't think Android's view classes do this well, so you may need to create a custom type of view that can produce a copy of itself. View
class does have methods to save/restore state: with onSaveInstanceState ()
and onRestoreInstanceState()
which you can use to copy View's state.
Also, you will need to take care of event listeners registered on that view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With