像素化 ArcLayout
ArcLayout pixelize
我使用https://github.com/florent37/ArcLayout 弧形布局
但是我的布局像素化了
<com.github.florent37.arclayout.ArcLayout
android:layout_width="match_parent"
android:layout_height="200dp"
app:arc_height="20dp"
app:arc_cropDirection="cropOutside"
app:arc_position="bottom">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#fff">
</LinearLayout>
</com.github.florent37.arclayout.ArcLayout>
我找到了这个主题:https://github.com/florent37/ArcLayout/issues/8
但我不明白如何使用下面的代码:
@override
protected void dispatchDraw(Canvas canvas) {
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawPath(clipPath, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
使用问题中建议的代码更新 dispatchDraw
方法。
编辑
用这个文件替换你的ArcLayout.java:
public class ArcLayout extends FrameLayout {
private ArcLayoutSettings settings;
private int height = 0;
private int width = 0;
private Path clipPath;
public ArcLayout(Context context) {
super(context);
init(context, null);
}
public ArcLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public void init(Context context, AttributeSet attrs) {
settings = new ArcLayoutSettings(context, attrs);
settings.setElevation(ViewCompat.getElevation(this));
/**
* If hardware acceleration is on (default from API 14), clipPath worked correctly
* from API 18.
*
* So we will disable hardware Acceleration if API < 18
*
* https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
* Section #Unsupported Drawing Operations
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
private Path createClipPath() {
final Path path = new Path();
float arcHeight = settings.getArcHeight();
switch (settings.getPosition()){
case ArcLayoutSettings.POSITION_BOTTOM:{
if (settings.isCropInside()) {
path.moveTo(0, 0);
path.lineTo(0, height);
path.quadTo(width / 2, height - 2 * arcHeight, width, height);
path.lineTo(width, 0);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(0, height - arcHeight);
path.quadTo(width / 2, height + arcHeight, width, height - arcHeight);
path.lineTo(width, 0);
path.close();
}
break;
}
case ArcLayoutSettings.POSITION_TOP:
if (settings.isCropInside()) {
path.moveTo(0, height);
path.lineTo(0, 0);
path.quadTo(width / 2, 2 * arcHeight, width, 0);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(0, arcHeight);
path.quadTo(width / 2, -arcHeight, width, arcHeight);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
break;
case ArcLayoutSettings.POSITION_LEFT:
if (settings.isCropInside()) {
path.moveTo(width, 0);
path.lineTo(0, 0);
path.quadTo(arcHeight * 2, height / 2, 0, height);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(width, 0);
path.lineTo(arcHeight, 0);
path.quadTo(-arcHeight, height / 2, arcHeight, height);
path.lineTo(width, height);
path.close();
}
break;
case ArcLayoutSettings.POSITION_RIGHT:
if (settings.isCropInside()) {
path.moveTo(0, 0);
path.lineTo(width, 0);
path.quadTo(width - arcHeight * 2, height / 2, width, height);
path.lineTo(0, height);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(width - arcHeight, 0);
path.quadTo(width + arcHeight, height / 2, width - arcHeight, height);
path.lineTo(0, height);
path.close();
}
break;
}
return path;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
calculateLayout();
}
}
private void calculateLayout() {
if (settings == null) {
return;
}
height = getMeasuredHeight();
width = getMeasuredWidth();
if (width > 0 && height > 0) {
clipPath = createClipPath();
ViewCompat.setElevation(this, settings.getElevation());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !settings.isCropInside()) {
ViewCompat.setElevation(this, settings.getElevation());
setOutlineProvider(new ViewOutlineProvider() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void getOutline(View view, Outline outline) {
outline.setConvexPath(clipPath);
}
});
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
Paint paint= new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawPath(clipPath, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
}
我使用https://github.com/florent37/ArcLayout 弧形布局
但是我的布局像素化了
<com.github.florent37.arclayout.ArcLayout
android:layout_width="match_parent"
android:layout_height="200dp"
app:arc_height="20dp"
app:arc_cropDirection="cropOutside"
app:arc_position="bottom">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#fff">
</LinearLayout>
</com.github.florent37.arclayout.ArcLayout>
我找到了这个主题:https://github.com/florent37/ArcLayout/issues/8
但我不明白如何使用下面的代码:
@override
protected void dispatchDraw(Canvas canvas) {
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawPath(clipPath, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
使用问题中建议的代码更新 dispatchDraw
方法。
编辑
用这个文件替换你的ArcLayout.java:
public class ArcLayout extends FrameLayout {
private ArcLayoutSettings settings;
private int height = 0;
private int width = 0;
private Path clipPath;
public ArcLayout(Context context) {
super(context);
init(context, null);
}
public ArcLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public void init(Context context, AttributeSet attrs) {
settings = new ArcLayoutSettings(context, attrs);
settings.setElevation(ViewCompat.getElevation(this));
/**
* If hardware acceleration is on (default from API 14), clipPath worked correctly
* from API 18.
*
* So we will disable hardware Acceleration if API < 18
*
* https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
* Section #Unsupported Drawing Operations
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
private Path createClipPath() {
final Path path = new Path();
float arcHeight = settings.getArcHeight();
switch (settings.getPosition()){
case ArcLayoutSettings.POSITION_BOTTOM:{
if (settings.isCropInside()) {
path.moveTo(0, 0);
path.lineTo(0, height);
path.quadTo(width / 2, height - 2 * arcHeight, width, height);
path.lineTo(width, 0);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(0, height - arcHeight);
path.quadTo(width / 2, height + arcHeight, width, height - arcHeight);
path.lineTo(width, 0);
path.close();
}
break;
}
case ArcLayoutSettings.POSITION_TOP:
if (settings.isCropInside()) {
path.moveTo(0, height);
path.lineTo(0, 0);
path.quadTo(width / 2, 2 * arcHeight, width, 0);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(0, arcHeight);
path.quadTo(width / 2, -arcHeight, width, arcHeight);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
break;
case ArcLayoutSettings.POSITION_LEFT:
if (settings.isCropInside()) {
path.moveTo(width, 0);
path.lineTo(0, 0);
path.quadTo(arcHeight * 2, height / 2, 0, height);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(width, 0);
path.lineTo(arcHeight, 0);
path.quadTo(-arcHeight, height / 2, arcHeight, height);
path.lineTo(width, height);
path.close();
}
break;
case ArcLayoutSettings.POSITION_RIGHT:
if (settings.isCropInside()) {
path.moveTo(0, 0);
path.lineTo(width, 0);
path.quadTo(width - arcHeight * 2, height / 2, width, height);
path.lineTo(0, height);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(width - arcHeight, 0);
path.quadTo(width + arcHeight, height / 2, width - arcHeight, height);
path.lineTo(0, height);
path.close();
}
break;
}
return path;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
calculateLayout();
}
}
private void calculateLayout() {
if (settings == null) {
return;
}
height = getMeasuredHeight();
width = getMeasuredWidth();
if (width > 0 && height > 0) {
clipPath = createClipPath();
ViewCompat.setElevation(this, settings.getElevation());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !settings.isCropInside()) {
ViewCompat.setElevation(this, settings.getElevation());
setOutlineProvider(new ViewOutlineProvider() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void getOutline(View view, Outline outline) {
outline.setConvexPath(clipPath);
}
});
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
Paint paint= new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawPath(clipPath, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
}