问题 在Android中实现自定义drawable


我试图在Android中掌握2D图形。   作为一个例子,我想实现一个自定义drawable并在我的Activity中显示它

我通过扩展Android drawable来定义一个自定义的drawable,如下所述

 class myDrawable extends Drawable {

   private static final String TAG = myDrawable.class.getSimpleName();
   private ColorFilter cf;
   @Override
   public void draw(Canvas canvas) {


     //First you define a colour for the outline of your rectangle

     Paint rectanglePaint = new Paint();
     rectanglePaint.setARGB(255, 255, 0, 0);
     rectanglePaint.setStrokeWidth(2);
     rectanglePaint.setStyle(Style.FILL);

     //Then create yourself a Rectangle
     RectF rectangle = new RectF(15.0f, 50.0f, 55.0f, 75.0f); //in pixels


     Log.d(TAG,"On Draw method");
     // TODO Auto-generated method stub
     Paint paintHandl = new Paint();
     //  paintHandl.setColor(0xaabbcc);
     paintHandl.setARGB(125, 234, 213, 34 );
     RectF rectObj = new RectF(5,5,25,25);
     canvas.drawRoundRect(rectangle, 0.5f, 0.5f, rectanglePaint);

   }

   @Override
   public int getOpacity() {
     // TODO Auto-generated method stub
     return 100;
   }

   @Override
   public void setAlpha(int alpha) {
     // TODO Auto-generated method stub
   }

   @Override
   public void setColorFilter(ColorFilter cf) {
     // TODO Auto-generated method stub
     this.cf = cf;
   }
 }

我想在我的活动中显示这个,如下所示

public class custDrawable extends Activity {
/** Called when the activity is first created. */


 LinearLayout layObj = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        layObj = (LinearLayout) findViewById(R.id.parentLay);
        ImageView imageView = (ImageView) findViewById(R.id.icon2);
        myDrawable myDrawObj = new myDrawable();
        imageView.setImageDrawable(myDrawObj);
        imageView.invalidate();
//  layObj.addView(myDrawObj, params);

    }
}

但是,当我运行应用程序时,我看到活动上没有矩形,任何人都可以帮助我吗? 我哪里错了?


2750
2018-06-03 16:29


起源



答案:


你的问题在于 getOpacity() 方法。 100不是有效值。你应该使用一个 的PixelFormat 值。另外,你应该创建你的 RectF 和 Paint 在构造函数中,然后只需调整值 draw() 所以你不要创建那么多需要垃圾收集的对象。喜欢这个:

public class Square extends Drawable
{
    private final Paint mPaint;
    private final RectF mRect;

    public Square()
    {
        mPaint = new Paint();
        mRect = new RectF();
    }

    @Override
    public void draw(Canvas canvas)
    {
        // Set the correct values in the Paint
        mPaint.setARGB(255, 255, 0, 0);
        mPaint.setStrokeWidth(2);
        mPaint.setStyle(Style.FILL);

        // Adjust the rect
        mRect.left = 15.0f;
        mRect.top = 50.0f;
        mRect.right = 55.0f;
        mRect.bottom = 75.0f;

        // Draw it
        canvas.drawRoundRect(mRect, 0.5f, 0.5f, mPaint);
    }

    @Override
    public int getOpacity()
    {
        return PixelFormat.OPAQUE;
    }

    @Override
    public void setAlpha(int arg0)
    {
    }

    @Override
    public void setColorFilter(ColorFilter arg0)
    {
    }
}

11
2018-06-03 18:41



我做了casey提到的更改,但我仍然无法看到我的观点中提取的任何有效内容。 - Girish
另一个问题是,你似乎永远不会添加 ImageView 到你的 LinearLayout。你需要添加 layObj.addView(imageView); 到了最后 onCreate() - CaseyB
我已经将imageView添加到线性布局,它基本上是设置边界的一个问题在xml中,我硬编码了图像视图的宽度和高度,现在它显示出来了,所以我的setBounds有些问题吗? - Girish
是否可以将图像嵌入圆角矩形或任何绘制的原始形状,比如多边形或路径?如果是这样,请分享代码? - Girish
如果你覆盖了 draw() 方法你可以绘制你想要的任何东西 Canvas。 - CaseyB


答案:


你的问题在于 getOpacity() 方法。 100不是有效值。你应该使用一个 的PixelFormat 值。另外,你应该创建你的 RectF 和 Paint 在构造函数中,然后只需调整值 draw() 所以你不要创建那么多需要垃圾收集的对象。喜欢这个:

public class Square extends Drawable
{
    private final Paint mPaint;
    private final RectF mRect;

    public Square()
    {
        mPaint = new Paint();
        mRect = new RectF();
    }

    @Override
    public void draw(Canvas canvas)
    {
        // Set the correct values in the Paint
        mPaint.setARGB(255, 255, 0, 0);
        mPaint.setStrokeWidth(2);
        mPaint.setStyle(Style.FILL);

        // Adjust the rect
        mRect.left = 15.0f;
        mRect.top = 50.0f;
        mRect.right = 55.0f;
        mRect.bottom = 75.0f;

        // Draw it
        canvas.drawRoundRect(mRect, 0.5f, 0.5f, mPaint);
    }

    @Override
    public int getOpacity()
    {
        return PixelFormat.OPAQUE;
    }

    @Override
    public void setAlpha(int arg0)
    {
    }

    @Override
    public void setColorFilter(ColorFilter arg0)
    {
    }
}

11
2018-06-03 18:41



我做了casey提到的更改,但我仍然无法看到我的观点中提取的任何有效内容。 - Girish
另一个问题是,你似乎永远不会添加 ImageView 到你的 LinearLayout。你需要添加 layObj.addView(imageView); 到了最后 onCreate() - CaseyB
我已经将imageView添加到线性布局,它基本上是设置边界的一个问题在xml中,我硬编码了图像视图的宽度和高度,现在它显示出来了,所以我的setBounds有些问题吗? - Girish
是否可以将图像嵌入圆角矩形或任何绘制的原始形状,比如多边形或路径?如果是这样,请分享代码? - Girish
如果你覆盖了 draw() 方法你可以绘制你想要的任何东西 Canvas。 - CaseyB


您可能必须实现其他覆盖,如getIntrinsicWidth()和getIntrinsicHeight()。一种方法是将layout_width和layout_height设置为某个常量(在XML中为layout_width =“42dip”layout_height =“42dip”,或者如果使用Java布局,则将layoutParams设置为某个值)。有些View类型处理没有getIntrinsic *实现,所以试试吧!这包括直视图

如果没有特定的宽度或高度,您可以尝试返回-1。

很难说这个问题是否得到了解决,但我通过谷歌来到这里试图帮助自己记住制作自定义Drawable的细节,而且我想帮助人们避免这种情况: http://xkcd.com/979/


0
2018-01-09 18:12