2015-12-19 20 views
5

ho già 'ImageView' con questi parametri:personalizzato drawable con ImageView

android:layout_width="wrap_content" 
android:layout_height="wrap_content" 

e impostare personalizzato Drawable:

public class HexDrawable extends Drawable { 

    private Path hexagonPath; 
    private float mWidth, mHeight; 
    private int mBackgroundColor; 
    private int mStrokeColor; 
    private int mStrokeWidth; 

    public HexDrawable(){ 
     init(); 
    } 

    public void setBackgroundColor(int color) { 
     mBackgroundColor = color; 
    } 

    public void setStrokeWidth(int width) { 
     mStrokeWidth = width; 
    } 

    public void setStrokeColor(int color) { 
     mStrokeColor = color; 
    } 

    @Override 
    public int getIntrinsicHeight() { 
     return 60; 
    } 

    @Override 
    public int getIntrinsicWidth() { 
     return 60; 
    } 

    private void init() { 
     hexagonPath = new Path(); 
     mBackgroundColor = Color.BLUE; 
     mStrokeColor = Color.GREEN; 
     mStrokeWidth = 4; 
    } 

    private void calculatePath() { 
     float p = mStrokeWidth/2; 
     float w = mWidth - 2 * p; 
     float h = mHeight - 2 * p; 
     float r = h/2; 
     float a = (float) (r/Math.sqrt(3)); 
     PointF X = new PointF(p + a + r/2, p); 
     PointF Y = new PointF(p + a + r , p); 
     PointF A = new PointF(p + a, p + 0f); 
     PointF B = new PointF(p + 0f, p + r); 
     PointF C = new PointF(p + a, p + 2 * r); 
     PointF D = new PointF(p + w - a, p + 2 * r); 
     PointF E = new PointF(p + w, p + r); 
     PointF F = new PointF(p + w - a, p + 0); 
     hexagonPath.moveTo(Y.x, Y.y); 
     hexagonPath.lineTo(A.x, A.y); 
     hexagonPath.lineTo(B.x, B.y); 
     hexagonPath.lineTo(C.x, C.y); 
     hexagonPath.lineTo(D.x, D.y); 
     hexagonPath.lineTo(E.x, E.y); 
     hexagonPath.lineTo(F.x, F.y); 
     hexagonPath.lineTo(X.x, X.y); 
    } 

    @Override 
    protected void onBoundsChange(Rect bounds) { 
     mWidth = bounds.width(); 
     mHeight = bounds.height(); 
     calculatePath(); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     Paint paint = new Paint(); 
     paint.setColor(mStrokeColor);     // set the color 
     paint.setStrokeWidth(mStrokeWidth);    // set the size 
     paint.setDither(true);     // set the dither to true 
     paint.setStyle(Paint.Style.STROKE);  // set to STOKE 
     paint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want 
     paint.setStrokeCap(Paint.Cap.ROUND);  // set the paint cap to round too 
     paint.setPathEffect(new CornerPathEffect(mStrokeWidth)); // set the path effect when they join. 
     paint.setAntiAlias(true); 
     canvas.drawPath(hexagonPath, paint); 
     canvas.clipPath(hexagonPath, Region.Op.INTERSECT); 
     canvas.drawColor(mBackgroundColor); 
     canvas.drawPath(hexagonPath, paint); 
     canvas.save(); 
    } 

    @Override 
    public void setAlpha(int alpha) { 

    } 

    @Override 
    public void setColorFilter(ColorFilter colorFilter) { 

    } 

    @Override 
    public int getOpacity() { 
     return 0; 
    } 
} 

Sembra che ImageView uso tutta larghezza in questo caso.

Come implementare Drawable correttamente per utilizzarlo con ImageView?

+1

potete inserire il codice del vostro drawable personalizzato? – Brucelet

+0

@Brucelet fatto, aggiunto codice di esempio –

+1

Ho guardato il tuo codice e drawable si trova in 'Imageview' perfettamente. La vista panoramica può occupare una larghezza aggiuntiva (in quanto potrebbe richiedere una forma rettangolare o quadrata) ma è possibile visualizzare solo il disegno esagonale. Scusa ma ... Qual è la domanda vera? – sha

risposta

4

La radice del problema era la modalità clip.

è più opportuno utilizzare canvas.clipPath(hexagonPath, Region.Op.REPLACE);

Inoltre, in discussione esempio funziona bene con ImageView, ma dopo un'indagine profonda ho undestand, che ad Android 5.0 e sopra di questo disegnabile è utilizzata a drawableLeft in TextView. Anche la sua non è necessario eseguire l'override getIntrinsicHeight

1

Il codice è assolutamente corretto:

enter image description here

Questo è come mi riempio ImageView (in onCreate() di attività):

((ImageView)findViewById(R.id.hexImageView)).setImageDrawable(new HexDrawable()); 

Struttura della Activity sulla schermata:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:padding="16dp"> 

    <ImageView 
     android:id="@+id/hexImageView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</FrameLayout> 

Se sostituisco wrap_content con valore, l'esagono come previsto sta cambiando le sue dimensioni.

Testato su Android 6.0 e 4.3.

Solo un suggerimento - invece di valori hardcoded in getIntrinsicHeight() e getIntrinsicWidth(), potrebbe essere meglio utilizzare dimens invece.