【问题标题】:Custom drawable with ImageView使用 ImageView 自定义可绘制对象
【发布时间】:2015-12-24 04:59:29
【问题描述】:

我已经有一个带有这些参数的“ImageView”:

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

并设置自定义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;
    }
}

在这种情况下ImageView 似乎使用了所有宽度。

如何正确实现Drawable 以与ImageView 一起使用?

【问题讨论】:

  • 你能贴出你自定义drawable的代码吗?
  • @Brucelet 完成,添加示例代码
  • 我查看了您的代码,drawable 完美地位于Imageview。 Imageview 可能会占用额外的宽度(因为它可能是矩形或正方形),但您只能看到六边形的可绘制对象。抱歉,但是.. 实际问题是什么?

标签: android image android-imageview android-drawable


【解决方案1】:

问题的根源在于剪辑模式。

最好使用canvas.clipPath(hexagonPath, Region.Op.REPLACE);

此外,问题示例适用于 ImageView,但经过深入调查,我不明白,在 android 5.0 及更高版本中,此可绘制对象在 TextView 的 drawableLeft 中使用。 它也不需要覆盖getIntrinsicHeight

【讨论】:

    【解决方案2】:

    您的代码绝对正确:

    这就是我填写ImageView 的方式(在onCreate() 的活动中):

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

    截图上Activity的布局:

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

    如果我将wrap_content 替换为值,六边形会按预期改变其大小。

    在 Android 6.0 和 4.3 上测试。

    提示 - 与其在 getIntrinsicHeight()getIntrinsicWidth() 中硬编码值,不如使用 dimens 代替。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      相关资源
      最近更新 更多