【问题标题】:Android OnDraw()Android OnDraw()
【发布时间】:2011-02-04 13:53:42
【问题描述】:

我是 Android 新手,我无法理解这个概念,所以基本上这就是我想要更好地理解它的方法..

  • 我创建了一个可扩展视图的 DrawShape 类。在 OnDraw() 的这个类中,我正在创建一个圆圈并用颜色填充它。

  • 从我正在调用应用程序的活动。 //到目前为止,我做得很好。

现在,我需要多次重新绘制圆(蓝色、红色、黄色等)

所以我在阅读,最好的方法是使用线程。我还读到你需要使用 postInvalidate() 来重绘(我仍然不明白我应该从哪里调用它)这是从 Activity 调用的吗?,还是在 OnDraw() 中?。

希望你明白我想要完成什么,只是我还没有找到一个很好的教程来说明这一点,如何重绘东西 x 次.. 当我执行 Thread.sleep() 时它全部停止然后它显示我的应用程序..但现在我明白了为什么,因为我正在玩主线程。

请帮助我理解这一点..

谢谢

【问题讨论】:

    标签: android


    【解决方案1】:

    我做了这样的事情

    animcolor()
    {
    Timer timer = new Timer();
    int delay =  ...;
    int period = ...;
    timer.schedule(new TimerTask(){
       run() { 
             setColor( randomint() ); ) 
             customview.postInvalidate();
       }
    }, delay, period);
    

    线程?不需要创建它们;计时器在并发方面做得很好。

    ...代码看起来有点像....

    res/layout/file.xml

    <org.customviewlayout a:id="@+id/customlayout"/>
    
    
    
    src/org.MyActivity.java
    
    
    class MyActivity 
    {
      onCreate()
      {
        customlayout = findViewById(R.id.customlayout);
        customlayout.animcolor();
       }
    }
    

    src/org.customlayout.java

    import org.customview;
    class customlayout
    {
      customview;
    
      customlayout(context, attrs)
      {
        customview = new customview();
        addview(customview);  // so it's onDraw() method will be called
      }
    
      onlayout(...)
      {
        customview.layout(...);
      }
    
      animcolor()
      {
        Timer timer = new Timer();
        int delay =  ...;
        int period = ...;
        timer.schedule(new TimerTask(){
           run() { 
               setColor( randomint() ); ) 
               customview.postInvalidate();
           }
        }, delay, period);
    
      }
    
      setcolor(int)
      {
        ....
      }
    }
    

    【讨论】:

      【解决方案2】:

      我认为,您可以在活动中使用 Timer 和 TimerTask 来执行此操作。 TimerTask 以您指定的延迟运行,运行时您要做的就是 yourDrawShapeInstance.postInvalidate();

      机制是这样的,因为你不是在你调用 postInvalidate() 的 ui 线程上来在 ui 队列上添加一个无效,当 ui 引擎选择你之前调用的延迟无效时,然后自动调用你的 onDraw 方法DrawShape 视图和视图将被重绘。

      (我不测试这个,我在这里写)

      TimerTask task = new TimerTask(){
        public void run(){
          myDrawShapeInstance.postInvalidate();
        }
      }
      

      【讨论】:

        【解决方案3】:

        绘制时,始终使用远离主线程的线程,并且始终在线程完成后失效(大多数情况下——显示绘制的当前结果)。您可能会从一些与用户相关的事件中调用您的绘图函数,因此请确保您正在为该绘图过程创建另一个线程。遵守这些规则,你会没事的。

        void drawCircleToCanvas(int color)
        {
        final Handler handler = new Handler() {
                   public void handleMessage(Message msg) {
                      myDrawShapeInstance.postInvalidate();
                      }
                   };
                Thread updateUI = new Thread() {  
                   public void run() {
        
                   //************draw something here***************
        
                      handler.sendEmptyMessage(0);
                      }
                   };
                  updateUI.start();
        }
        

        【讨论】:

        • 太好了,如果我需要重画圆圈,那么在 run() 中我可以放一些类似 Canvas c = new Canvas();和油漆油漆=新油漆();我可以从这里做吗?你有什么建议?另外,如果我有一个扩展视图的类,我可以做类似 myClass.OnDraw(); 的事情吗? ?
        • 这里有几件事:线程应该用于更新影响画布的值。比如在游戏中移动角色的位置 ++x(将角色水平移动到某个位置上)。您可以使用线程来更改要绘制的圆圈数量的值以及将它们更改为的颜色。通过调用 postInvalidate(),画布的 onDraw() 函数也会被调用,所以你不需要直接调用 onDraw()。此链接的代码与您正在执行的操作非常相似:blog.goltergaul.de/2010/03/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-19
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多