使用setLayerType作为软件崩溃的ClipPath

时间:2016-03-22 05:06:13

标签: java android

我正在尝试在自定义视图中剪切路径,但它显示为黑色。通过搜索和找到相同的原因。发现我需要设置“setLayerType(LAYER_TYPE_SOFTWARE,null)”。在此之后它看起来很完美,但在一些变化中崩溃。

崩溃日志(其中一个基于设备):

  1. java.lang.NegativeArraySizeException
  2. 位图超过32位

    public class CardLayout extends LinearLayout {
    
    private View mRoot;
    private ImageView mCategoryImageView;
    private LinearLayout mCategoryBottomView;
    
    private RectF mRect;
    private Paint mPaint;
    private View mDivider;
    private Path mPath;
    private int mPadding = 30;
    
    public CardLayout(Context context) {
        super(context);
    }
    
    public CardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    public CardLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mRoot = LayoutInflater.from(getContext()).inflate(R.layout.card_content, null);
        addView(mRoot);
        initUI();
    }
    
    private void initUI() {
    
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mPath = new Path();
    
        mCategoryHeadlineTextView = (TextView) mRoot.findViewById(R.id.categoryHeadline);
        mCategoryImageView = (ImageView) mRoot.findViewById(R.id.categoryImageView);
        mCategoryBottomView = (LinearLayout) mRoot.findViewById(R.id.ctg_btm_view);
        mDivider = mRoot.findViewById(R.id.divider);
    
        setLayerType(LAYER_TYPE_SOFTWARE,null);
    }
    
    public void setCategoryImage(String categoryUrl) {
        if (mCategoryImageView != null) {
            Glide.with(mContext)
                    .load(categoryUrl)
                    .placeholder(R.drawable.two)
                    .into(mCategoryImageView);
        }
    }
    
    public void setBottomView(String[] optionText, int[] optionResource, int tag) {
    
        if (mCategoryBottomView != null) {
            CategoryBottomOptions options = new CategoryBottomOptions(mContext, optionText, optionResource, tag, mCategoryBottomView);
        }
    }
    
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    
        mRect = new RectF(mDivider.getX() - mPadding, mDivider.getY() - mPadding, mDivider.getX() + mPadding, mDivider.getY() + mPadding);
        mPath.addArc(mRect, 270, 180);
        canvas.clipPath(mPath);
        canvas.drawPath(mPath, mPaint);
    
        mRect = new RectF(mDivider.getWidth() - mPadding, mDivider.getY() - mPadding, mDivider.getWidth() + mPadding, mDivider.getY() + mPadding);
        mPath = new Path();
        mPath.addArc(mRect, 90, 180);
        canvas.clipPath(mPath);
        canvas.drawPath(mPath, mPaint);
    }
    }
    

1 个答案:

答案 0 :(得分:1)

你应该做这样的事情来创建一个带有视图的窗口。

public class ClippedImageView extends ImageView {
    private Paint mPaint;
    private Path mPath;

    public ClippedImageView(Context context) {
        this(context, null);
        init();
    }

    public v(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    public ClippedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mPath = new Path();
        RectF rect = new RectF(0, 0, 100, 100);
        mPath.addArc(rect, 270, 180);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.clipPath(mPath, Region.Op.DIFFERENCE);
        super.onDraw(canvas);
    }
}