Android:复制视图组中的视图元素

Android:复制视图组中的视图元素,android,android-view,Android,Android View,我正在开发一个类,该类扩展了ViewGroup,以便为GridView安排视图项 我可以通过以下方式轻松在其中添加新的视图项: ImageView view = new ImageView(context); view.setImageBitmap(BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher)); addView(view); 或者删除视图项也很容易 removeViewAt(remove_index

我正在开发一个类,该类扩展了ViewGroup,以便为GridView安排视图项

我可以通过以下方式轻松在其中添加新的视图项:

ImageView view = new ImageView(context);
view.setImageBitmap(BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher));
addView(view);
或者删除视图项也很容易

removeViewAt(remove_index)
交换项目可以通过以下方式完成:

addView(new_index, removeViewAt(old_index));
但我想在将一个项目拖到另一个项目上时复制视图项目。 我试图通过复制该项目

addView(getChildAt(index))
这显示了异常错误

指定的子级已具有父级。必须首先对子级的父级调用removeView()

我还尝试存储列表中的所有视图项,调用方法removeAllView(),并再次在类中添加视图

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));
}
ArrayList children=new ArrayList();
对于(int i=0;i
这仍然显示异常错误,如上所示:

视图膨胀可能有效,但我希望复制相同的视图,而不使用外部资源

因此,我希望该方法将该视图与父视图组分离,并在类内对其进行多个复制(复制)


非常感谢您的帮助。

复制对象需要很好地实现
clone()
方法

我认为Android的视图类在这方面做得不好,所以您可能需要创建一个自定义类型的视图来生成自身的副本<代码>视图
类确实有保存/还原状态的方法:使用
onSaveInstanceState()
onRestoreInstanceState()
可以用来复制视图的状态


此外,您还需要注意在该视图上注册的事件侦听器。

首先,您尝试再次添加相同的对象,这没有意义-新视图必须是一个单独的对象,您必须首先复制原始对象,例如使用
.clone()
方法

但是,不幸的是,即使您这样做了,您也无法将克隆视图添加到
视图组
,原因如下

您得到的异常是
ViewGroup
因此,为了添加克隆视图,您必须将视图的
mParent
成员设置为
null
,您不能直接这样做,因为这样做的方法不是公共的:

您可以在调用
.removeViewAt()
后尝试克隆
视图
,以使其在克隆时没有父视图,然后将原始视图添加回其位置,然后继续将克隆添加到所需位置,但是正如S.D.所提到的,你在克隆方面会遇到一些麻烦,而且这种方法非常模糊,需要
视图组
重新播放两次

更好的解决方案是为每个视图指定一个标记,该标记包含创建另一个类似视图所需的信息,并在需要克隆时使用它

我会这样做:

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);

对于您想要使用的任何其他视图或组,而不是单一的
ImageView
东西,只需创建另一个
ViewCloner
实现,您就可以不用修改容器的行为了。

感谢s.D和Ivan的回答

经过长时间的休息,我可以找到自己的答案,并将这些解决方案牢记在心

克隆方法不能直接添加到视图中,添加接口会增加代码的复杂性

甚至我的要求是克隆动态添加了图像且源未知的视图

为了复制视图,必须采取一些措施, 首先,获取视图的另一个实例,并在第二个实例上复制属性,如drawable、background、padding等

通过使用以下代码,解决方案更加简单

// 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);