2015-12-19 18 views
5

Tôi đã có tài 'ImageView' với các thông số:Tuỳ chỉnh drawable với ImageView

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

và thiết lập tùy chỉnh 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; 
    } 
} 

Dường như ImageView sử dụng tất cả chiều rộng trong trường hợp này.

Cách triển khai Drawable chính xác để sử dụng nó với ImageView?

+1

Bạn có thể đăng mã có thể vẽ tùy chỉnh của mình không? – Brucelet

+0

@Brucelet đã hoàn tất, hãy thêm mã ví dụ –

+1

Tôi đã xem mã của bạn và có thể drawable nằm trong 'Imageview' một cách hoàn hảo. Imageview có thể chiếm chiều rộng bổ sung (vì nó có thể có hình chữ nhật hoặc hình vuông) nhưng bạn chỉ có thể thấy hình lục giác có thể vẽ được. Xin lỗi nhưng .. Câu hỏi thực sự là gì? – sha

Trả lời

4

Gốc của sự cố là chế độ clip.

của nó tốt hơn để sử dụng canvas.clipPath(hexagonPath, Region.Op.REPLACE);

Ngoài ra, câu hỏi ví dụ hoạt động tốt với ImageView, nhưng sau khi điều tra sâu tôi đã hiểu, rằng ở android 5.0 trở lên drawable này được sử dụng tại drawableLeft trong TextView. Ngoài ra, không cần ghi đè getIntrinsicHeight

1

Mã của bạn là hoàn toàn chính xác:

enter image description here

Đây là cách tôi điền ImageView (trong onCreate() hoạt động):

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

Layout của Activity trên ảnh chụp màn hình:

<?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> 

Nếu tôi thay thế wrap_content bằng giá trị, hình lục giác như mong đợi sẽ thay đổi kích thước của nó.

Đã thử nghiệm trên Android 6.0 và 4.3.

Chỉ một mẹo - thay vì giá trị được mã hóa cứng trong getIntrinsicHeight()getIntrinsicWidth(), thay vào đó, tốt hơn nên sử dụng dimens.