2016-05-10 9 views
-2

Ich möchte Bild von JSON in Imageview laden. Wenn ich basic android Imageview verwende, gibt es keine Verzögerung und es zeigt Bild schnell, aber wenn ich CircleImageView verwende, werden die Bilder verzögert und zeigen manchmal das Bild nicht.Verzögerung beim Laden eines Bildes aus dem Internet in CircleImageView in Android

Ich benutze Glide Bibliothek zum Anzeigen von Bildern in ImageView.

Meine CircleImageView Klasse:

public class CircularImage extends ImageView { 
    private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; 

    // Default Values 
    private static final float DEFAULT_BORDER_WIDTH = 4; 
    private static final float DEFAULT_SHADOW_RADIUS = 8.0f; 

    // Properties 
    private float borderWidth; 
    private int canvasSize; 
    private float shadowRadius; 
    private int shadowColor = Color.BLACK; 

    // Object used to draw 
    private Bitmap image; 
    private Drawable drawable; 
    private Paint paint; 
    private Paint paintBorder; 

    //region Constructor & Init Method 
    public tellfa_CircularImage(final Context context) { 
     this(context, null); 
    } 

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

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

    private void init(Context context, AttributeSet attrs, int defStyleAttr) { 
     // Init paint 
     paint = new Paint(); 
     paint.setAntiAlias(true); 

     paintBorder = new Paint(); 
     paintBorder.setAntiAlias(true); 

     // Load the styled attributes and set their properties 
     TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyleAttr, 0); 

     // Init Border 
     if (attributes.getBoolean(R.styleable.CircularImageView_civ_border, true)) { 
      float defaultBorderSize = DEFAULT_BORDER_WIDTH * getContext().getResources().getDisplayMetrics().density; 
      setBorderWidth(attributes.getDimension(R.styleable.CircularImageView_civ_border_width, defaultBorderSize)); 
      setBorderColor(attributes.getColor(R.styleable.CircularImageView_civ_border_color, Color.WHITE)); 
     } 

     // Init Shadow 
     if (attributes.getBoolean(R.styleable.CircularImageView_civ_shadow, false)) { 
      shadowRadius = DEFAULT_SHADOW_RADIUS; 
      drawShadow(attributes.getFloat(R.styleable.CircularImageView_civ_shadow_radius, shadowRadius), attributes.getColor(R.styleable.CircularImageView_civ_shadow_color, shadowColor)); 
     } 
    } 
    //endregion 

    //region Set Attr Method 
    public void setBorderWidth(float borderWidth) { 
     this.borderWidth = borderWidth; 
     requestLayout(); 
     invalidate(); 
    } 

    public void setBorderColor(int borderColor) { 
     if (paintBorder != null) 
      paintBorder.setColor(borderColor); 
     invalidate(); 
    } 

    public void addShadow() { 
     if (shadowRadius == 0) 
      shadowRadius = DEFAULT_SHADOW_RADIUS; 
     drawShadow(shadowRadius, shadowColor); 
     invalidate(); 
    } 

    public void setShadowRadius(float shadowRadius) { 
     drawShadow(shadowRadius, shadowColor); 
     invalidate(); 
    } 

    public void setShadowColor(int shadowColor) { 
     drawShadow(shadowRadius, shadowColor); 
     invalidate(); 
    } 

    @Override 
    public ScaleType getScaleType() { 
     return SCALE_TYPE; 
    } 

    @Override 
    public void setScaleType(ScaleType scaleType) { 
     if (scaleType != SCALE_TYPE) { 
      throw new IllegalArgumentException(String.format("ScaleType %s not supported. ScaleType.CENTER_CROP is used by default. So you don't need to use ScaleType.", scaleType)); 
     } 
    } 
    //endregion 

    //region Draw Method 
    @Override 
    public void onDraw(Canvas canvas) { 
     // Load the bitmap 
     loadBitmap(); 

     // Check if image isn't null 
     if (image == null) 
      return; 

     if (!isInEditMode()) { 
      canvasSize = canvas.getWidth(); 
      if (canvas.getHeight() < canvasSize) { 
       canvasSize = canvas.getHeight(); 
      } 
     } 

     // circleCenter is the x or y of the view's center 
     // radius is the radius in pixels of the cirle to be drawn 
     // paint contains the shader that will texture the shape 
     int circleCenter = (int) (canvasSize - (borderWidth * 2))/2; 
     // Draw Border 
     canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - (shadowRadius + shadowRadius/2), paintBorder); 
     // Draw CircularImageView 
     canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - (shadowRadius + shadowRadius/2), paint); 
    } 

    private void loadBitmap() { 
     if (this.drawable == getDrawable()) 
      return; 

     this.drawable = getDrawable(); 
     this.image = drawableToBitmap(this.drawable); 
     updateShader(); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     canvasSize = w; 
     if (h < canvasSize) 
      canvasSize = h; 
     if (image != null) 
      updateShader(); 
    } 

    private void drawShadow(float shadowRadius, int shadowColor) { 
     this.shadowRadius = shadowRadius; 
     this.shadowColor = shadowColor; 
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { 
      setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); 
     } 
     paintBorder.setShadowLayer(shadowRadius, 0.0f, shadowRadius/2, shadowColor); 
    } 

    private void updateShader() { 
     if (image == null) 
      return; 

     // Crop Center Image 
     image = cropBitmap(image); 

     // Create Shader 
     BitmapShader shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

     // Center Image in Shader 
     Matrix matrix = new Matrix(); 
     matrix.setScale((float) canvasSize/(float) image.getWidth(), (float) canvasSize/(float) image.getHeight()); 
     shader.setLocalMatrix(matrix); 

     // Set Shader in Paint 
     paint.setShader(shader); 
    } 

    private Bitmap cropBitmap(Bitmap bitmap) { 
     Bitmap bmp; 
     if (bitmap.getWidth() >= bitmap.getHeight()) { 
      bmp = Bitmap.createBitmap(
        bitmap, 
        bitmap.getWidth()/2 - bitmap.getHeight()/2, 
        0, 
        bitmap.getHeight(), bitmap.getHeight()); 
     } else { 
      bmp = Bitmap.createBitmap(
        bitmap, 
        0, 
        bitmap.getHeight()/2 - bitmap.getWidth()/2, 
        bitmap.getWidth(), bitmap.getWidth()); 
     } 
     return bmp; 
    } 

    private Bitmap drawableToBitmap(Drawable drawable) { 
     if (drawable == null) { 
      return null; 
     } else if (drawable instanceof BitmapDrawable) { 
      return ((BitmapDrawable) drawable).getBitmap(); 
     } 

     int intrinsicWidth = drawable.getIntrinsicWidth(); 
     int intrinsicHeight = drawable.getIntrinsicHeight(); 

     if (!(intrinsicWidth > 0 && intrinsicHeight > 0)) 
      return null; 

     try { 
      // Create Bitmap object out of the drawable 
      Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888); 
      Canvas canvas = new Canvas(bitmap); 
      drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
      drawable.draw(canvas); 
      return bitmap; 
     } catch (OutOfMemoryError e) { 
      // Simply return null of failed bitmap creations 
      Log.e(getClass().toString(), "Encountered OutOfMemoryError while generating bitmap!"); 
      return null; 
     } 
    } 
    //endregion 

    //region Mesure Method 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int width = measureWidth(widthMeasureSpec); 
     int height = measureHeight(heightMeasureSpec); 
     /*int imageSize = (width < height) ? width : height; 
     setMeasuredDimension(imageSize, imageSize);*/ 
     setMeasuredDimension(width, height); 
    } 

    private int measureWidth(int measureSpec) { 
     int result; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     if (specMode == MeasureSpec.EXACTLY) { 
      // The parent has determined an exact size for the child. 
      result = specSize; 
     } else if (specMode == MeasureSpec.AT_MOST) { 
      // The child can be as large as it wants up to the specified size. 
      result = specSize; 
     } else { 
      // The parent has not imposed any constraint on the child. 
      result = canvasSize; 
     } 

     return result; 
    } 

    private int measureHeight(int measureSpecHeight) { 
     int result; 
     int specMode = MeasureSpec.getMode(measureSpecHeight); 
     int specSize = MeasureSpec.getSize(measureSpecHeight); 

     if (specMode == MeasureSpec.EXACTLY) { 
      // We were told how big to be 
      result = specSize; 
     } else if (specMode == MeasureSpec.AT_MOST) { 
      // The child can be as large as it wants up to the specified size. 
      result = specSize; 
     } else { 
      // Measure the text (beware: ascent is a negative number) 
      result = canvasSize; 
     } 

     return (result + 2); 
    } 
    //endregion 
} 

CircleImageview ist wichtig, um mein Projekt und ich brauche CirlceImageView statt Grund ImageView zu verwenden.

Wie kann dieses Problem behoben werden?

Antwort

0

Sie sollten diese Methode init in allen constructors--

   OR 

Versuchen Sie rufen:

public class CircleImageView extends ImageView { 

private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; 

private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; 
private static final int COLORDRAWABLE_DIMENSION = 2; 

private static final int DEFAULT_BORDER_WIDTH = 0; 
private static final int DEFAULT_BORDER_COLOR = Color.BLACK; 
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; 
private static final boolean DEFAULT_BORDER_OVERLAY = false; 

private final RectF mDrawableRect = new RectF(); 
private final RectF mBorderRect = new RectF(); 

private final Matrix mShaderMatrix = new Matrix(); 
private final Paint mBitmapPaint = new Paint(); 
private final Paint mBorderPaint = new Paint(); 
private final Paint mFillPaint = new Paint(); 

private int mBorderColor = DEFAULT_BORDER_COLOR; 
private int mBorderWidth = DEFAULT_BORDER_WIDTH; 
private int mFillColor = DEFAULT_FILL_COLOR; 

private Bitmap mBitmap; 
private BitmapShader mBitmapShader; 
private int mBitmapWidth; 
private int mBitmapHeight; 

private float mDrawableRadius; 
private float mBorderRadius; 

private ColorFilter mColorFilter; 

private boolean mReady; 
private boolean mSetupPending; 
private boolean mBorderOverlay; 

public CircleImageView(Context context) { 
    super(context); 

    init(); 
} 

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

public CircleImageView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); 

    mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); 
    mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); 
    mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); 
    mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); 

    a.recycle(); 

    init(); 
} 

private void init() { 
    super.setScaleType(SCALE_TYPE); 
    mReady = true; 

    if (mSetupPending) { 
     setup(); 
     mSetupPending = false; 
    } 
} 

@Override 
public ScaleType getScaleType() { 
    return SCALE_TYPE; 
} 

@Override 
public void setScaleType(ScaleType scaleType) { 
    if (scaleType != SCALE_TYPE) { 
     throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); 
    } 
} 

@Override 
public void setAdjustViewBounds(boolean adjustViewBounds) { 
    if (adjustViewBounds) { 
     throw new IllegalArgumentException("adjustViewBounds not supported."); 
    } 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    if (mBitmap == null) { 
     return; 
    } 

    if (mFillColor != Color.TRANSPARENT) { 
     canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mDrawableRadius, mFillPaint); 
    } 
    canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mDrawableRadius, mBitmapPaint); 
    if (mBorderWidth != 0) { 
     canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mBorderRadius, mBorderPaint); 
    } 
} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    setup(); 
} 

public int getBorderColor() { 
    return mBorderColor; 
} 

public void setBorderColor(@ColorInt int borderColor) { 
    if (borderColor == mBorderColor) { 
     return; 
    } 

    mBorderColor = borderColor; 
    mBorderPaint.setColor(mBorderColor); 
    invalidate(); 
} 

public void setBorderColorResource(@ColorRes int borderColorRes) { 
    setBorderColor(getContext().getResources().getColor(borderColorRes)); 
} 

public int getFillColor() { 
    return mFillColor; 
} 

public void setFillColor(@ColorInt int fillColor) { 
    if (fillColor == mFillColor) { 
     return; 
    } 

    mFillColor = fillColor; 
    mFillPaint.setColor(fillColor); 
    invalidate(); 
} 

public void setFillColorResource(@ColorRes int fillColorRes) { 
    setFillColor(getContext().getResources().getColor(fillColorRes)); 
} 

public int getBorderWidth() { 
    return mBorderWidth; 
} 

public void setBorderWidth(int borderWidth) { 
    if (borderWidth == mBorderWidth) { 
     return; 
    } 

    mBorderWidth = borderWidth; 
    setup(); 
} 

public boolean isBorderOverlay() { 
    return mBorderOverlay; 
} 

public void setBorderOverlay(boolean borderOverlay) { 
    if (borderOverlay == mBorderOverlay) { 
     return; 
    } 

    mBorderOverlay = borderOverlay; 
    setup(); 
} 

@Override 
public void setImageBitmap(Bitmap bm) { 
    super.setImageBitmap(bm); 
    mBitmap = bm; 
    setup(); 
} 

@Override 
public void setImageDrawable(Drawable drawable) { 
    super.setImageDrawable(drawable); 
    mBitmap = getBitmapFromDrawable(drawable); 
    setup(); 
} 

@Override 
public void setImageResource(@DrawableRes int resId) { 
    super.setImageResource(resId); 
    mBitmap = getBitmapFromDrawable(getDrawable()); 
    setup(); 
} 

@Override 
public void setImageURI(Uri uri) { 
    super.setImageURI(uri); 
    mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null; 
    setup(); 
} 

@Override 
public void setColorFilter(ColorFilter cf) { 
    if (cf == mColorFilter) { 
     return; 
    } 

    mColorFilter = cf; 
    mBitmapPaint.setColorFilter(mColorFilter); 
    invalidate(); 
} 

private Bitmap getBitmapFromDrawable(Drawable drawable) { 
    if (drawable == null) { 
     return null; 
    } 

    if (drawable instanceof BitmapDrawable) { 
     return ((BitmapDrawable) drawable).getBitmap(); 
    } 

    try { 
     Bitmap bitmap; 

     if (drawable instanceof ColorDrawable) { 
      bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); 
     } else { 
      bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); 
     } 

     Canvas canvas = new Canvas(bitmap); 
     drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
     drawable.draw(canvas); 
     return bitmap; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

private void setup() { 
    if (!mReady) { 
     mSetupPending = true; 
     return; 
    } 

    if (getWidth() == 0 && getHeight() == 0) { 
     return; 
    } 

    if (mBitmap == null) { 
     invalidate(); 
     return; 
    } 

    mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

    mBitmapPaint.setAntiAlias(true); 
    mBitmapPaint.setShader(mBitmapShader); 

    mBorderPaint.setStyle(Paint.Style.STROKE); 
    mBorderPaint.setAntiAlias(true); 
    mBorderPaint.setColor(mBorderColor); 
    mBorderPaint.setStrokeWidth(mBorderWidth); 

    mFillPaint.setStyle(Paint.Style.FILL); 
    mFillPaint.setAntiAlias(true); 
    mFillPaint.setColor(mFillColor); 

    mBitmapHeight = mBitmap.getHeight(); 
    mBitmapWidth = mBitmap.getWidth(); 

    mBorderRect.set(0, 0, getWidth(), getHeight()); 
    mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth)/2.0f, (mBorderRect.width() - mBorderWidth)/2.0f); 

    mDrawableRect.set(mBorderRect); 
    if (!mBorderOverlay) { 
     mDrawableRect.inset(mBorderWidth, mBorderWidth); 
    } 
    mDrawableRadius = Math.min(mDrawableRect.height()/2.0f, mDrawableRect.width()/2.0f); 

    updateShaderMatrix(); 
    invalidate(); 
} 

private void updateShaderMatrix() { 
    float scale; 
    float dx = 0; 
    float dy = 0; 

    mShaderMatrix.set(null); 

    if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { 
     scale = mDrawableRect.height()/(float) mBitmapHeight; 
     dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; 
    } else { 
     scale = mDrawableRect.width()/(float) mBitmapWidth; 
     dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; 
    } 

    mShaderMatrix.setScale(scale, scale); 
    mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); 

    mBitmapShader.setLocalMatrix(mShaderMatrix); 
} 

} 

Stile:

<declare-styleable name="CircleImageView"> 
    <attr name="civ_border_width" format="dimension" /> 
    <attr name="civ_border_color" format="color" /> 
    <attr name="civ_border_overlay" format="boolean" /> 
    <attr name="civ_fill_color" format="color" /> 
</declare-styleable> 
+0

Bitte senden Sie mir Stil .xml Attr für dieses CircleImage Sehen Sie –

+0

da gehen Sie @Palang –

+0

Dank @Abraham Gharyali, es ist schnell ein paar, aber nicht solche Basis imageView :( –