以编程方式截取Cardview时,Cardview失去了半径 [英] Cardview loses its radius when taken a screenshot programmatically

查看:111
本文介绍了以编程方式截取Cardview时,Cardview失去了半径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在cardview中有约束布局.卡片视图在屏幕上看起来不错.仅当截取屏幕截图时,它才会渲染到位图,即失去角点时.我已经添加了位图视图的图片.约束布局与圆角重叠.我需要边缘到边缘的圆度.

下面是模拟器的屏幕截图,正确显示了圆角:

以下是渲染到位图的视图:

下面是我的示例代码.

 公共类MainActivity扩展了AppCompatActivity {私人CardView cardView;私人按钮按钮;私有ConstraintLayout parentLayoutA;私有ConstraintLayout layoutB;私有ConstraintLayout childLayout;private ConstraintSet innerSet;私有ConstraintSet outsideSet;@Override受保护的void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);CreateCardViewProgrammatically();}公共无效CreateCardViewProgrammatically(){cardView =新的CardView(this);childLayout =新的ConstraintLayout(this);parentLayoutA =新的ConstraintLayout(this);layoutB = new ConstraintLayout(this);button = new Button(this);如果(Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP){layoutB.setClipToOutline(true);}cardView.setRadius(150);button.setText("Click !!");button.setTextColor(Color.BLACK);button.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v){takeScreenShot();}});如果(Build.VERSION.SDK_INT> = Build.VERSION_CODES.JELLY_BEAN_MR1){parentLayoutA.setId(View.generateViewId());layoutB.setId(View.generateViewId());childLayout.setId(View.generateViewId());cardView.setId(View.generateViewId());button.setId(View.generateViewId());}innerSet =新的ConstraintSet();externalSet =新的ConstraintSet();ConstraintLayout.LayoutParams parentParams =新的ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,ConstraintLayout.LayoutParams.MATCH_PARENT);layoutB.setLayoutParams(parentParams);childLayout.setLayoutParams(parentParams);cardView.setCardElevation(0);cardView.setPadding(50,50,50,50);parentLayoutA.addView(layoutB);layoutB.addView(cardView);cardView.addView(childLayout);childLayout.addView(button);innerSet.centerHorizo​​ntally(button.getId(),ConstraintSet.PARENT_ID);innerSet.centerVertically(button.getId(),ConstraintSet.PARENT_ID);innerSet.constrainHeight(button.getId(),200);externalSet.connect(cardView.getId(),ConstraintSet.END,ConstraintSet.PARENT_ID,ConstraintSet.END,200);externalSet.connect(cardView.getId(),ConstraintSet.START,ConstraintSet.PARENT_ID,ConstraintSet.START,200);outsideSet.centerHorizo​​ntally(cardView.getId(),ConstraintSet.PARENT_ID);externalSet.centerVertically(cardView.getId(),ConstraintSet.PARENT_ID);outsideSet.constrainHeight(cardView.getId(),1500);innerSet.applyTo(childLayout);outsideSet.applyTo(layoutB);setContentView(parentLayoutA);parentLayoutA.setBackgroundColor(Color.YELLOW);layoutB.setBackgroundColor(Color.MAGENTA);cardView.setCardBackgroundColor(Color.GREEN);childLayout.setBackgroundColor(Color.BLUE);}公共无效takeScreenShot(){imageFromView(parentLayoutA);}公共位图imageFromView(查看视图){DisplayMetrics指标= this.getApplication().getResources().getDisplayMetrics();int width = view.getWidth()>0?view.getWidth():metrics.widthPixels;int height = view.getHeight()>0?view.getHeight():metrics.heightPixels;位图位图= Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);view.draw(画布);返回位图;} 

解决方案

通过查看您的代码,我不清楚您要完成什么.但是,如果您更改以下行

  cardView.setCardBackgroundColor(Color.GREEN); 

  cardView.setCardBackgroundColor(Color.BLUE); 

并删除该行

  childLayout.setBackgroundColor(Color.BLUE); 

您将看到您以我想的方式捕获的屏幕图像.


潜在的问题是,圆角裁剪取决于硬件层,该硬件层已为视图显示系统生成的画布启用,但在生成自己的位图和画布时已关闭.您可以使用

I have constraintlayout within cardview. The cardview looks fine on the screen. It is only when taken a screenshot,it is rendered to a bitmap thats when it loses the corners. I have added the picture of the bitmap view. The constraintlayout overlaps the rounded corners. I need edge to edge roundness.

Below is the screenshot of the emulator showing round corners correctly:

Here is the view rendered to a bitmap:

Below is my sample code.

public class MainActivity extends AppCompatActivity {

    private CardView cardView;
    private Button button;
    private ConstraintLayout parentLayoutA;
    private ConstraintLayout layoutB;
    private ConstraintLayout childLayout;
    private ConstraintSet innerSet;
    private ConstraintSet outerSet;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CreateCardViewProgrammatically();
    }


    public void CreateCardViewProgrammatically(){

        cardView = new CardView(this);
        childLayout = new ConstraintLayout(this);
        parentLayoutA = new ConstraintLayout(this);
        layoutB = new ConstraintLayout(this);
        button = new Button(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            layoutB.setClipToOutline(true);
        }

        cardView.setRadius(150);

        button.setText("Click!!");
        button.setTextColor(Color.BLACK);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               takeScreenShot();
            }
        });

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            parentLayoutA.setId(View.generateViewId());
            layoutB.setId(View.generateViewId());
            childLayout.setId(View.generateViewId());
            cardView.setId(View.generateViewId());
            button.setId(View.generateViewId());
        }

        innerSet = new ConstraintSet();
        outerSet = new ConstraintSet();

        ConstraintLayout.LayoutParams parentParams = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.MATCH_PARENT,
                ConstraintLayout.LayoutParams.MATCH_PARENT
        );

        layoutB.setLayoutParams(parentParams);
        childLayout.setLayoutParams(parentParams);
        cardView.setCardElevation(0);
        cardView.setPadding(50,50,50,50);

        parentLayoutA.addView(layoutB);
        layoutB.addView(cardView);
        cardView.addView(childLayout);
        childLayout.addView(button);

        innerSet.centerHorizontally(button.getId(), ConstraintSet.PARENT_ID);
        innerSet.centerVertically(button.getId(), ConstraintSet.PARENT_ID);
        innerSet.constrainHeight(button.getId(), 200);

        outerSet.connect(cardView.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 200);
        outerSet.connect(cardView.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 200);
        outerSet.centerHorizontally(cardView.getId(), ConstraintSet.PARENT_ID);
        outerSet.centerVertically(cardView.getId(), ConstraintSet.PARENT_ID);
        outerSet.constrainHeight(cardView.getId(), 1500);

        innerSet.applyTo(childLayout);
        outerSet.applyTo(layoutB);

        setContentView(parentLayoutA);

        parentLayoutA.setBackgroundColor(Color.YELLOW);
        layoutB.setBackgroundColor(Color.MAGENTA);
        cardView.setCardBackgroundColor(Color.GREEN);
        childLayout.setBackgroundColor(Color.BLUE);
    }

    public void takeScreenShot() {
        imageFromView(parentLayoutA);
    }

    public Bitmap imageFromView(View view) {

        DisplayMetrics metrics = this.getApplication().getResources().getDisplayMetrics();
        int width = view.getWidth() > 0 ? view.getWidth() : metrics.widthPixels;
        int height = view.getHeight() > 0 ? view.getHeight() : metrics.heightPixels;

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);

        return bitmap;
    }

解决方案

From looking at your code, I am not clear on what you are trying to accomplish. However, if you change the following line

cardView.setCardBackgroundColor(Color.GREEN);

to

cardView.setCardBackgroundColor(Color.BLUE);

and delete the line

childLayout.setBackgroundColor(Color.BLUE);

you will see your screen image captured the way I think you want.


The underlying problem is that the rounded corner clipping is dependent upon the hardware layer which is enabled for the canvas generated by the view display system but is turned off when you generate your own bitmap and canvas. You can check this with Canvas#isHardwareAccelerated(),

Take a look at Taking Screenshot Programmatically Using PixelCopy Api for an approach that you might be able to take. Also, see PixelCopy.

Here is a small project on GitHub demonstrating how to go about capturing a layout. This demo app simply uses the code in the question to display a layout, captures the layout and redisplays it in an ImageView. A TextView in the redisplay simply displays "Captured!"

这篇关于以编程方式截取Cardview时,Cardview失去了半径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆