指定的子项已有父项。在创建自定义视图类时,必须首先在子级父级上调用removeView()

问题描述 投票:0回答:1

创建自定义视图类并运行时,logcat控制台显示错误。

指定的子项已有父项。你必须在孩子的父亲身上调用removeView()first.at android.view.ViewGroup.addViewInner(ViewGroup.java:4312)

怎么能解决这个问题呢?

这是我的代码:

public class CanvasView extends View {
    ArrayList<Item> alTemp;
    ArrayList<Item> alViews;
    Bitmap bitmap2;
    Bitmap bitmap;
    int frontBack;
    Context mContext;
    Templates mTemplates;
    RelativeLayout root;
    float scale;

    public CanvasView(Context context, float scale, ArrayList<Item> arrayList, Templates templates, int frontBack, Bitmap bitmap, Bitmap bitmap2) {
        super(context);
        this.mContext = context;
        this.scale = scale;
        this.alTemp = arrayList;
        this.mTemplates = templates;
        this.frontBack = frontBack;
        this.bitmap = bitmap;
        this.bitmap2 = bitmap2;
        setData();
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        root.measure(canvas.getWidth(), canvas.getHeight());
        root.layout(0, 0, canvas.getWidth(), canvas.getHeight());
        root.draw(canvas);
        root.setLayerType(1, null);
    }


    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        root.measure(w, h);
        root.layout(0, 0, w, h);
    }

    public void setData() {
        alViews = new ArrayList<>();
        for (int i = 0; i < alTemp.size(); i++) {
            if (frontBack == alTemp.get(i).getFrontback()) {
                alViews.add(alTemp.get(i));
            }
        }
        root = new RelativeLayout(mContext);
        root.setLayoutParams(new LayoutParams(Constants.saveWidth, Constants.saveHeight));
        ImageView imageView = new ImageView(mContext);
        imageView.setLayoutParams(new LayoutParams(Constants.saveWidth, Constants.saveHeight));
        imageView.setScaleType(ScaleType.FIT_XY);
        if (frontBack == 0) {
            if (mTemplates.getFrontTemplatetype() == 2) {
                imageView.setImageBitmap(bitmap);
            } else {
                imageView.setImageBitmap(Functions.setFrontTemplate(mContext, mTemplates, Constants.saveWidth, Constants.saveHeight));
            }
        } else if (mTemplates.getBackTemplatetype() == 2) {
            imageView.setImageBitmap(bitmap2);
        } else {
            imageView.setImageBitmap(Functions.setBackTemplate(mContext, mTemplates, Constants.saveWidth, Constants.saveHeight));
        }
        root.addView(imageView);
        RelativeLayout relativeLayout = new RelativeLayout(mContext);
        relativeLayout.setLayoutParams(new LayoutParams(Constants.saveWidth, Constants.saveWidth));
        root.addView(relativeLayout);

        for (int i = 0; i < alViews.size(); i++) {
            System.out.println("loop " + i);
            RelativeLayout relLayout = new RelativeLayout(mContext);
            ViewGroup.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            relLayout.setX((float) Math.round(alViews.get(i).getRlx() * scale));
            relLayout.setY((float) Math.round(alViews.get(i).getRly() * scale));
            relLayout.setRotation(alViews.get(i).getRlrotation());
            relLayout.setLayoutParams(layoutParams);


            if (alViews.get(i).getType() == 0) {
                CustomTextView customTextView = new CustomTextView(mContext);
                String stringBuilder = " " +
                        alViews.get(i).getText().trim() +
                        " ";
                customTextView.setText(stringBuilder);
                customTextView.setTextColor((alViews.get(i)).getTextcolor());
                customTextView.setTextSize(0, (float) Math.round(((float) alViews.get(i).getTextsize()) * scale));
                customTextView.setGravity(alViews.get(i).getGravity());
                customTextView.setTypeface(alViews.get(i).getTextstyle());
                customTextView.setAlpha(((float) alViews.get(i).getOpacity()) / 100.0f);
                if (alViews.get(i).isTextunderline()) {
                    customTextView.setPaintFlags(customTextView.getPaintFlags() | 8);
                } else {
                    customTextView.setPaintFlags(customTextView.getPaintFlags() & -9);
                }
                if (alViews.get(i).isStroke()) {
                    customTextView.setStroke(true);
                    customTextView.setStrokeColor(alViews.get(i).getStrokeColor());
                    customTextView.setStrokeWidth(Math.round(((float) alViews.get(i).getStrokeWidth()) * scale));
                    customTextView.invalidate();
                }
                if (alViews.get(i).isShadow()) {
                    customTextView.setShadow(true);
                    customTextView.setShadowWidth(Math.round(alViews.get(i).getShadowSize() * scale));
                    customTextView.setShadowX(Math.round(alViews.get(i).getShadowX() * scale));
                    customTextView.setShadowY(Math.round(alViews.get(i).getShadowY() * scale));
                    customTextView.setShadowColor(alViews.get(i).getShadowColor());
                    customTextView.invalidate();
                }
                customTextView.setPadding(0, 0, (int) customTextView.getShadowX(), (int) customTextView.getShadowY());
                customTextView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                relativeLayout.setClipToPadding(true);
                relativeLayout.addView(customTextView);
            } else if (alViews.get(i).getType() == 1 ||alViews.get(i).getType()==2) {
                imageView = new ImageView(mContext);
                imageView.setImageBitmap(alViews.get(i).getImagebitmap());
                imageView.setAlpha(((float) alViews.get(i).getOpacity()) / 100.0f);
                if (alViews.get(i).getColorFilter() != -1) {
                    imageView.setColorFilter((alViews.get(i)).getColorFilter());
                }
                LayoutParams layoutParams2 = new LayoutParams(Math.round((((float) alViews.get(i).getIvSize()) * scale) * alViews.get(i).getScaleW()), Math.round((((float) alViews.get(i).getIvSize()) * scale) * alViews.get(i).getScaleH()));
                layoutParams2.setMargins(Math.round(mContext.getResources().getDimension(R.dimen.image_margin) * scale), Math.round(mContext.getResources().getDimension(R.dimen.image_margin) * scale), Math.round(mContext.getResources().getDimension(R.dimen.image_margin) * scale), Math.round(mContext.getResources().getDimension(R.dimen.image_margin) * scale));
                imageView.setLayoutParams(layoutParams2);
                relativeLayout.addView(imageView);
            }
            root.addView(relativeLayout);

        }
    }
}
java android
1个回答
0
投票

我相信你的问题是你在你的循环中使用relativeLayout变量而不是relLayout

这意味着relativeLayout会在每次循环迭代加循环之前添加到其父级中。

我相信你需要

    ...
    RelativeLayout relativeLayout = new RelativeLayout(mContext);
    relativeLayout.setLayoutParams(new LayoutParams(Constants.saveWidth, Constants.saveWidth));
    root.addView(relativeLayout);

    for (int i = 0; i < alViews.size(); i++) {
        System.out.println("loop " + i);
        RelativeLayout relLayout = new RelativeLayout(mContext);
        ViewGroup.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        relLayout.setX((float) Math.round(alViews.get(i).getRlx() * scale));
        relLayout.setY((float) Math.round(alViews.get(i).getRly() * scale));
        relLayout.setRotation(alViews.get(i).getRlrotation());
        relLayout.setLayoutParams(layoutParams);


        if (alViews.get(i).getType() == 0) {
            ...
            relLayout.setClipToPadding(true);
            relLayout.addView(customTextView);
        } 
        ...
        root.addView(relLayout);

    }
}

但是,通过查看代码,您可能更容易将布局定义为XML文件并将其加载到视图中。

看起来好像是在为allTemp数组中的每个项目渲染视图。这看起来很好地利用了回收者的观点,我相信这会更好地为您服务。

这可能会有所帮助:https://developer.android.com/guide/topics/ui/layout/recyclerview

© www.soinside.com 2019 - 2024. All rights reserved.