2016-07-18 2 views
0

У меня есть пользовательский ImageView, который переопределяет метод onDraw для обрезки углов с помощью Path, чтобы дать закругленный угол заданного радиуса. У меня есть RecyclerView, где у меня есть этот пользовательский ImageView во всех четырех элементах. Теперь проблема заключается в том, что этот пользовательский ImageView отлично отображает первый раз, когда он отображается в списке. Одновременно на экране можно разместить только 2 экрана. Когда я прокручиваю вниз, все в порядке. Во всех них я вижу закругленный угол. Но когда я просматриваю предыдущий элемент. Теперь эти углы теряют свою прозрачность в углах и становятся черными во всех, кроме третьего элемента в списке. Холст в onDraw также имеет isOpaque = true. Я много пробовал, но ничего не работает. Вот кодПользовательский ImageView теряет прозрачность, как только он выходит из экрана в recycleView

public class RoundedImageView extends ImageView 
{ 
    private Paint mPaint; 
    private int mCornerRadius = 0; 
    private boolean mRoundedTopLeft = true, mRoundedBottomLeft = true, mRoundedTopRight = true, mRoundedBottomRight = true; 

    public void setCornerRadius(int mCornerRadius) 
    { 
     this.mCornerRadius = mCornerRadius; 
    } 

    public void RoundCorners(boolean isRoundedTopLeft, boolean isRoundedTopRight, boolean isRoundedBottomLeft, boolean isRoundedBottomRight) 
    { 
     mRoundedTopLeft = isRoundedTopLeft; 
     mRoundedBottomLeft = isRoundedBottomLeft; 
     mRoundedBottomRight = isRoundedBottomRight; 
     mRoundedTopRight = isRoundedTopRight; 
    } 

    public RoundedImageView(Context context) 
    { 
     super(context); 
     if (Build.VERSION.SDK_INT >= 11) 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     setupPaint(); 
    } 

    public RoundedImageView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
     if (Build.VERSION.SDK_INT >= 11) 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     setupPaint(); 
    } 

    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) 
    { 
     super(context, attrs, defStyleAttr); 
     if (Build.VERSION.SDK_INT >= 11) 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     setupPaint(); 
    } 

    @TargetApi(21) 
    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) 
    { 
     super(context, attrs, defStyleAttr, defStyleRes); 
     if (Build.VERSION.SDK_INT >= 11) 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     setupPaint(); 

    } 

    private Paint setupPaint() 
    { 
     mPaint = new Paint(); 
     mPaint.setColor(Color.TRANSPARENT); 
     mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setStrokeWidth(1); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     return mPaint; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 
     super.onDraw(canvas); 

     Path path = RoundedRect(0, 0, getWidth(), getHeight(), mCornerRadius, mCornerRadius, 
       mRoundedTopLeft, mRoundedTopRight, mRoundedBottomRight, mRoundedBottomLeft); 
     canvas.drawPath(path, mPaint); 
    } 

    public static Path RoundedRect(
      float left, float top, float right, float bottom, float rx, float ry, 
      boolean tl, boolean tr, boolean br, boolean bl) 
    { 
     Path path = new Path(); 
     if (rx < 0) rx = 0; 
     if (ry < 0) ry = 0; 
     float width = right - left; 
     float height = bottom - top; 
     if (rx > width/2) rx = width/2; 
     if (ry > height/2) ry = height/2; 
     float widthMinusCorners = (width - (2 * rx)); 
     float heightMinusCorners = (height - (2 * ry)); 

     path.moveTo(right, top + ry); 
     if (tr) 
      path.rQuadTo(0, -ry, -rx, -ry);//top-right corner 
     else 
     { 
      path.rLineTo(0, -ry); 
      path.rLineTo(-rx, 0); 
     } 
     path.rLineTo(-widthMinusCorners, 0); 
     if (tl) 
      path.rQuadTo(-rx, 0, -rx, ry); //top-left corner 
     else 
     { 
      path.rLineTo(-rx, 0); 
      path.rLineTo(0, ry); 
     } 
     path.rLineTo(0, heightMinusCorners); 

     if (bl) 
      path.rQuadTo(0, ry, rx, ry);//bottom-left corner 
     else 
     { 
      path.rLineTo(0, ry); 
      path.rLineTo(rx, 0); 
     } 

     path.rLineTo(widthMinusCorners, 0); 
     if (br) 
      path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner 
     else 
     { 
      path.rLineTo(rx, 0); 
      path.rLineTo(0, -ry); 
     } 

     path.rLineTo(0, -heightMinusCorners); 

     path.close();//Given close, last lineto can be removed. 

     path.setFillType(Path.FillType.INVERSE_EVEN_ODD); 
     return path; 
    } 
} 

То, что я уже пробовал: - установка isRecyclable ложна в ViewHolder

  • установка другого режима PorterDuff в краске

  • LAYER_TYPE_HARDWARE (аппаратное ускорение) для этого вида

  • setDrawingCacheBackgroundColor(0x00000000); в конструкторе

  • setLayerType(View.LAYER_TYPE_SOFTWARE, paint); прохождение краски в этой функции

  • попытался сделать холст прозрачные, прежде чем super.onDraw()

UPDATE:

После большого количества пустячный вокруг я пришел к выводу, что всякий раз, когда мои viewHolder-х вид выходит из экрана. Все это альфа-канал становится черным. У меня есть ощущение, что он должен что-то сделать с помощью setLayerType(View.LAYER_TYPE_SOFTWARE, null);

+0

вы можете установить 'атрибуты' как' radius' и 'opacity' в' onBindViewHolder' – Sanoop

+0

@Sanoop да, это тоже было бы круто, но я хотел бы исправить эту проблему прежде, чем это сделать. – Rishabh876

+0

Да .. Отлично. .Но пытайтесь установить атрибуты в 'onBindViewHolder' и проверить, является ли переработчик причиной возникновения проблемы. – Sanoop

ответ

0

Выполнено, ускорив родительское ПО.

Я решил проблему, поставив

if (Build.VERSION.SDK_INT >= 11) 
       view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

в конструкторе моего ViewHolder. Он работал, даже если я включил ускорение программного обеспечения для любого родительского контейнера.

Теперь я не знаю, почему это сработало.

+0

Это связано с тем, что в ресайклере зритель подключен динамически и, следовательно, родитель, к которому подключен ваш просмотр, должен быть программным ускоряются. То же самое касается аппаратного ускорения. – Embydextrous

Смежные вопросы