【问题标题】:how to draw nested circle programmatically如何以编程方式绘制嵌套圆
【发布时间】:2015-01-12 14:21:32
【问题描述】:

这里我使用层列表通过 XML 绘制嵌套的 Circle

<item>
    <shape android:shape="oval" >
        <stroke
            android:width="1dp"
            android:color="@android:color/holo_orange_light" />

        <padding
            android:bottom="7dp"
            android:left="7dp"
            android:right="7dp"
            android:top="7dp" />
    </shape>
</item>
<item>
    <shape android:shape="oval" >
        <solid android:color="@color/welcome_bg" />
    </shape>
</item>

不,我想要以编程方式使用相同的嵌套圆圈,因为我想动态更改颜色,或者有什么方法可以在上面提供的 xml 中动态更改颜色

这是我的自定义视图

public class MyView extends EditText {

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

}

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);

}

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

}

@Override
protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(Color.GRAY);

    RectF oval1 = new RectF(50, 50, 300, 300);
    canvas.drawOval(oval1, paint);

    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.RED);
    RectF oval2 = new RectF(55, 55, 295, 295);
    canvas.drawOval(oval2, paint);

}
}

谢谢

【问题讨论】:

  • 创建一个自定义 View 类,然后在 onDraw 中填充一些东西。这应该让你继续前进!
  • 我创建了一个自定义视图,但在这种情况下嵌套的圆圈没有正确填充,它看起来只是像素模糊,但是当我使用 xml 代码时一切正常。

标签: java android eclipse stack-overflow


【解决方案1】:

当您使用 xml 时,指定的尺寸以 dp 为单位 - 与密度无关的像素。但是在您的代码中,绘图函数将实际像素作为参数,您必须将其考虑在内并自己计算适当的值。

根据您的设备声明的屏幕密度,1dp 将被转换为:

  • ldpi (120 dpi) - 0.75 像素
  • mdpi (160 dpi) - 1 像素
  • hdpi (240 dpi) - 1.5 像素
  • xhdpi (320 dpi) - 2 像素
  • xxhdpi (480 dpi) - 3 像素
  • xxxhdpi (640 dpi) - 4 像素

计算真实像素的公式是px = dp * (dpi / 160)

public class MyView extends EditText {

float mDensityScale;    

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

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs, 0);    
}

public MyView(Context context) {
    super(context);
    init(context, null, 0);
}

private void init(Context context, AttributeSet attrs, int defStyle)
{
    final DisplayMetrics dm = context.getResources().getDisplayMetrics();
    mDensityScale = dm.density;
}

private float pix(float dp)
{
    return dp * mDensityScale;
}   

@Override
protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(Color.GRAY);

    RectF oval1 = new RectF(pix(50), pix(50), pix(300), pix(300));
    canvas.drawOval(oval1, paint);

    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.RED);
    RectF oval2 = new RectF(pix(55), pix(55), pix(295), pix(295));
    canvas.drawOval(oval2, paint);

}
}

您可以阅读更多:

【讨论】:

  • 这个例子的问题,它是画圆,但圆的外线和笔画都不完美,圆的线和笔画都表现出模糊行为@Dalija Prasnikar
  • @Daljia - 在公式中 px = dp * (dpi / 160) ...dpi 是设备的每英寸点数?...我们如何找到设备的 dpi?我们如何将设备分类为 ldpi 或 mdi 或 xdpi 等。谢谢
  • @NagaR dpi 是每英寸设备的点数,您可以通过DisplayMetrics 找到它(上面代码中的init 方法)。 dm.densityDpi 将为您提供设备的 dpi(它属于哪个类别 - ldpi、mdpi..),dm.density 将为您提供预乘比例(dpi / 160)。要计算设备像素,请使用px = dp * dm.density(上述代码中的pix 方法)另请查看developer.android.com/reference/android/util/…
  • @DalijaPrasnikar - 感谢您的回答。它很有用
【解决方案2】:

如果您想在继续使用 xml 的同时更改可绘制颜色,您可以为要修改的项目添加一个 id:

<item>
    <shape android:shape="oval" >
        <stroke
            android:width="1dp"
            android:color="@android:color/holo_orange_light" />

        <padding
            android:bottom="7dp"
            android:left="7dp"
            android:right="7dp"
            android:top="7dp" />
    </shape>
</item>
<item android:id="@+id/circle_inner">
    <shape android:shape="oval" >
        <solid android:color="@color/welcome_bg" />
    </shape>
</item>

然后在您的代码中获取可绘制的图层列表并搜索相关 id 并更改颜色:

LayerDrawable layerDrawable = (LayerDrawable) v.getBackground();
GradientDrawable innerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_inner);
innerCircle.setColor(0xff00ff00);

请注意,我正在转换为 GradientDrawable,因为 &lt;shape&gt; 标记是指向 (shape tag documentation) 的指针

【讨论】:

    【解决方案3】:

    <item android:id="@+id/circle_outer">
        <shape android:shape="oval" >
            <stroke
                android:width="1dp"
                android:color="@android:color/holo_orange_light" />
    
            <padding
                android:bottom="7dp"
                android:left="7dp"
                android:right="7dp"
                android:top="7dp" />
        </shape>
    </item>
    <item android:id="@+id/circle_inner">
        <shape android:shape="oval" >
            <solid android:color="@color/welcome_bg" />
        </shape>
    </item>
    

    在这里,我提供了 XML 并设置了它们的 id 并以编程方式更改颜色 XML Items的变色方式

    LayerDrawable layerDrawable = (LayerDrawable) ctx.getResources().getDrawable(R.drawable.tv_circle);
        GradientDrawable innerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_inner);
        GradientDrawable outerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_outer);
        innerCircle.setColor(0xff00ff00);
        outerCircle.setStroke(2, Color.BLUE, 0, 10);
    

    谢谢大家,它对我有用,请关闭它

    【讨论】:

      猜你喜欢
      • 2015-03-22
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多