【问题标题】:Cardview loses its radius when taken a screenshot programmatically以编程方式截取屏幕截图时,Cardview 失去其半径
【发布时间】:2020-05-31 07:16:55
【问题描述】:

我在 cardview 中有约束布局。卡片视图在屏幕上看起来不错。只有在截屏时,它才会在失去角落时呈现为位图。我添加了位图视图的图片。约束布局与圆角重叠。我需要边缘到边缘的圆度。

以下是正确显示圆角的模拟器截图:

这是渲染为位图的视图:

下面是我的示例代码。

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

【问题讨论】:

    标签: bitmap android-canvas android-constraintlayout android-cardview


    【解决方案1】:

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

    cardView.setCardBackgroundColor(Color.GREEN);
    

    cardView.setCardBackgroundColor(Color.BLUE);
    

    并删除该行

    childLayout.setBackgroundColor(Color.BLUE);
    

    您将看到以我认为您想要的方式捕获的屏幕图像。


    根本问题是圆角裁剪依赖于硬件层,该硬件层为视图显示系统生成的画布启用,但在您生成自己的位图和画布时被关闭。您可以通过Canvas#isHardwareAccelerated() 进行检查,

    查看Taking Screenshot Programmatically Using PixelCopy Api,了解您可能会采用的方法。另请参阅PixelCopy

    Here 是 GitHub 上的一个小项目,演示如何捕获布局。此演示应用程序仅使用问题中的代码来显示布局,捕获布局并将其重新显示在 ImageView 中。重新显示中的 TextView 仅显示“Captured!”

    【讨论】:

    • 示例代码的目的是显示当一个cardview在一个constraintlayout A内而另一个constraintlayout B在cardview内时,当你对A进行截图时,圆角消失了。颜色只是为了显示问题。
    • @SupreetKaur 这样就解决了问题?还是角落消失了?您已选择它作为正确答案
    • 我刚刚测试过,它适用于 api 28。但它在 api 28 以下不起作用。我在你的代码中看到你留下了Bitmap.createBitmap,因为它是 api 28。OP 仍然再次发生,即角落不见了
    • 接受的答案仅适用于高于 O 的版本。对于较低的 API 版本,我们必须在子类化视图并覆​​盖 ondraw 方法后使用 canvas.clipPath 裁剪画布的角。这是唯一的我们能够解决问题的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多