android - ArcLayout 像素化

标签 android layout automatic-ref-counting

我使用 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);
}

最佳答案

转到项目中的这个文件:https://github.com/florent37/ArcLayout/blob/master/arclayout/src/main/java/com/github/florent37/arclayout/ArcLayout.java

使用问题中建议的代码更新 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);
    }
}

关于android - ArcLayout 像素化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47632207/

相关文章:

java - 如何按GMT时区获取货币名称?

java - 将视频流从 Socket 保存到文件

android - 我的 android 动画时间有什么问题?

twitter-bootstrap - 在 bootstrap/kickstrap 中使用媒体查询的完全不同的布局

objective-c - 如果属性被定义为副本,那么在分配给 ivar 时是否还需要进行副本?

java - 将 dialogflow 依赖项添加到我的 android 应用程序后出现重复类错误

android - 包装内容不起作用

CSS左侧菜单布局问题

memory - 场景多的 Cocos2D 项目没有正确释放内存

objective-c - 关于自动引用计数,我需要了解什么?