【问题标题】:onDraw doesn't get called on custom view?onDraw 不会在自定义视图上调用?
【发布时间】:2012-09-27 07:14:55
【问题描述】:

我正在尝试用特定颜色绘制圆角矩形,但我什么也没得到。 我已经做了很多谷歌搜索,发现了一些这样的问题并全部阅读。但是,他们都没有解决我的问题。为什么我的 onDraw 方法从未被调用?

感谢任何帮助。

public class RoundedTagItem extends RelativeLayout {

    Context ctx;
    String colorString;
    int color;

    public RoundedTagItem(Context context) {
        super(context);
        this.ctx = context;
        color = Color.WHITE;
        this.setWillNotDraw(false);
        this.setPadding(10, 0, 10, 0);
    }

    public RoundedTagItem(Context context, String color) {
        super(context);
        this.ctx = context;
        this.colorString = color;
        this.setWillNotDraw(false);
        this.setPadding(10, 0, 10, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {

       if(colorString != null)
             color = Color.parseColor("#" + colorString);

       int rectValue = 35;
       Log.d("Rounded", "rectValue: " + rectValue);
       RectF rect1 = new RectF(0, 0, rectValue, rectValue);

       Paint paint = new Paint();
       paint.setStrokeWidth(1);
       paint.setStrokeCap(Paint.Cap.ROUND);
       paint.setStyle(Paint.Style.FILL);
       paint.setAntiAlias(true);
       paint.setColor(color);

       canvas.save();
       canvas.drawRoundRect(rect1, 10, 10, paint);
       canvas.restore();

       super.onDraw(canvas);
    }

    public void ChangeBackgroundColor(String colorString) {
        color = Color.parseColor(colorString);
        invalidate();
    }

}

然后我将图标放在主类的自定义视图上:

// add category items to view
LinearLayout categories = (LinearLayout) findViewById(R.id.detailTagImagesLayout);
for(int i = 0; i < item.getCategoryItems().size(); i++) {

    RoundedTagItem v = null;
    if(i == 0) 
        v = new RoundedTagItem(DetailActivity.this, 
                           item.getCategoryItems().get(i).getColorCode());
    else 
        v = new RoundedTagItem(DetailActivity.this);            

    ImageView img = new ImageView(DetailActivity.this);
    img.setImageDrawable(Drawable.createFromPath(
                     item.getCategoryItems().get(i).getLightIconUrl()));
    v.addView(img);

    v.setTag(i);
    v.setOnClickListener(new TagClickListener());               

    categories.addView(v);
}

【问题讨论】:

    标签: android android-custom-view ondraw


    【解决方案1】:

    您可以做出/修复的一些改进/问题...

    您可以将这些行移到您的构造函数中:

    if(colorString != null)
       color = Color.parseColor("#" + colorString);
    

    因为这个colorString 永远不会改变,而且你现在的做法是每次调用onDraw 时都会计算它(他会被调用很多次)。

    其次,请将您的super.onDraw(canvas) 移到您的第一行。

    第三你需要在你的构造函数上定义你的 LayoutParams。如果一个视图的宽度/高度为 0,它的绘制将永远不会被调用!

    this.setLayoutParams(new LayoutParams(150, 150));
    

    最后请确保您使用的是RoundTagItem。您可以使用如下标记将此视图添加到您的 xml:&lt;your.package.RoundTagItem&gt; 其中your.package 是您正在使用的包 (com.something.blabla)。如果您像这样使用它,请确保您定义了layout_widthlayout_height

    您还可以通过添加到您的根视图(您可以使用findViewById(R.layout.your_root) 获取它)或将您的视图设置为主要内容来以编程方式添加您的视图。

    RoundedTagItem myView = new RoundedTagItem(this);
    setContentView(myView);
    

    【讨论】:

    • 感谢您的建议,我会做的。但问题是我正在根据数组的大小动态创建这个视图,所以我创建了很多这个视图并将它们全部放入 LinearLayout。
    • 只要您确定显示您的LinearLayout,就没有问题。确保您正在显示它(在您的视图之前添加一个文本)并更改 super.onDraw 并告诉我您的问题是否仍然存在。
    • 我使用这个自定义视图作为背景,并放置一个图标。我看到图标,但没有背景绘制。 :(
    • 你如何在这个服装视图上放置一个图标?你有一个LinearLayout 对吗?假设你的LinearLayoutandroid:id=@+id/root。现在你需要确定这个LinearLayout属于你在setContentView上使用的布局。最后得到布局:LinearLayout rootLayout = (LinearLayout) findViewById(R.id.root) 并在rootLayoutrootLayout.addView(myView) 上添加您的观点。如果这个 rootLayout 正在被绘制,那么视图将会调用它们的 onDraw 方法。
    • 我更新了我的问题,以展示我如何在我的主要活动中的这些自定义视图上添加图标。在我看来,我做了你说的同样的事情......
    【解决方案2】:

    尝试创建一个简单的单个RelativeLayout XML (rounded_tag_item.xml),并为自定义视图充气:

    public class RoundedTagItem extends RelativeLayout {
    
        public RoundedTagItem(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public RoundedTagItem(Context context) {
            super(context);
            init(context);  
        }
    
        private void init(Context context) {
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            if (inflater != null) {       
                RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.rounded_tag_item, new RelativeLayout(context));
    
                // rest of stuff...
            }
        }
    }
    

    【讨论】:

    • 您打算如何设置该视图的颜色?
    • public RoundedTagItem(上下文上下文,字符串颜色) { super(context);初始化(上下文,颜色);}
    • 或添加 setColor(String color) 方法
    • 我已经尝试创建 rounded_tag_item.xml 但问题是我需要动态更改背景颜色,所以在 xml 中创建不会解决我的问题。
    • 在自定义视图创建过程中一旦充气,就会调用它的onDraw方法,你可以使用上面计划使用的相同方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多