以编程方式截取屏幕截图时,Cardview 会丢失其半径
Cardview loses its radius when taken a screenshot programmatically
我在 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;
}
从你的代码来看,我不清楚你想要完成什么。但是,如果您更改以下行
cardView.setCardBackgroundColor(Color.GREEN);
到
cardView.setCardBackgroundColor(Color.BLUE);
并删除行
childLayout.setBackgroundColor(Color.BLUE);
您会看到您的屏幕图像按照我认为您想要的方式捕获。
根本问题是圆角裁剪取决于硬件层,该硬件层为视图显示系统生成的 canvas 启用,但在您生成自己的位图和 canvas.您可以使用 Canvas#isHardwareAccelerated()、
进行检查
看看Taking Screenshot Programmatically Using PixelCopy Api for an approach that you might be able to take. Also, see PixelCopy。
Here 是 GitHub 上的一个小项目,演示如何着手捕获布局。这个演示应用程序只是使用问题中的代码来显示布局,捕获布局并在 ImageView 中重新显示它。重新显示中的 TextView 仅显示 "Captured!"
我在 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;
}
从你的代码来看,我不清楚你想要完成什么。但是,如果您更改以下行
cardView.setCardBackgroundColor(Color.GREEN);
到
cardView.setCardBackgroundColor(Color.BLUE);
并删除行
childLayout.setBackgroundColor(Color.BLUE);
您会看到您的屏幕图像按照我认为您想要的方式捕获。
根本问题是圆角裁剪取决于硬件层,该硬件层为视图显示系统生成的 canvas 启用,但在您生成自己的位图和 canvas.您可以使用 Canvas#isHardwareAccelerated()、
进行检查看看Taking Screenshot Programmatically Using PixelCopy Api for an approach that you might be able to take. Also, see PixelCopy。
Here 是 GitHub 上的一个小项目,演示如何着手捕获布局。这个演示应用程序只是使用问题中的代码来显示布局,捕获布局并在 ImageView 中重新显示它。重新显示中的 TextView 仅显示 "Captured!"