【问题标题】:setBackgroundResource doesn't set the imagesetBackgroundResource 不设置图像
【发布时间】:2013-05-17 04:18:59
【问题描述】:
    Handler hnd = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        int id = sequence.get(msg.arg1);

        if(msg.arg1 % 2 == 0) {
            sq.get(id-1).setBackgroundResource(R.drawable.square_show);
        } else {
            sq.get(id-1).setBackgroundResource(R.drawable.square);
        }
    }
};

@Override
public void onResume() {
    super.onResume();

    Thread background = new Thread(new Runnable() {
        public void run() {
            try {
                for(int i = 0; i < sequence.size()-1; i++) {
                    record_tv.setText(""+i);
                    Thread.sleep(200);
                    Message msg = hnd.obtainMessage();
                    msg.arg1 = i;
                    msg.sendToTarget();
                }
            } catch(Throwable t) {

            }
        }
    });

    background.start();
}

[代码更新] 现在它通过第一个循环并停止

你知道为什么第一个 runOnUiThread 中的代码被执行但它没有做我想要的吗?

我想要的是:将图像更改为“方形”,等待 2 秒,将图像更改为“square_show”,等待 2 秒并重复循环

我已经挣扎了一个小时了......

【问题讨论】:

  • 请问什么是平方?
  • sq 是 ImageViews 的列表

标签: java android multithreading


【解决方案1】:

您可以使用以下代码轻松设置图像。

sq.get(id-1).setImageResource(R.drawable.square_show);
sq.get(id-1).setImageResource(R.drawable.square);

【讨论】:

  • 是的,但我的问题是我希望它在两个动作之间等待 2 秒,但我是怎么做的,它不起作用
  • 然后试试 thrd.sleep(2000);在 run() 方法中最后才在 sq.get(id-1).setImageResource(R.drawable.square_show);
【解决方案2】:

public void show(int size) {

    // CICLE THROUGH EACH SQUARE

    for(int i = 0; i <= size-1; i++) {          

        Thread thrd = new Thread() {
            public void run() {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                                           sq.get(id-1).setImageResource(R.drawable.square_show);         
                               //     System.out.println("1st.........."); 
                       try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                                         sq.get(id-1).setImageResource(R.drawable.square);
                  //     System.out.println("2nd..........");
                       try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    }
                });




            }
        };

        thrd.start();
    }
}

【讨论】:

  • 实际上,它可能确实有效,但我对其进行了测试,它阻塞了 UI,“我认为它可以工作”,然后返回 UI,而不显示它在做什么
  • 那是因为你不能从后台线程修改 ui。您可以尝试使用处理程序来实现您想要实现的目标
【解决方案3】:

这是一种错误的实现方式。这可能会对您有所帮助。 http://developer.android.com/guide/topics/graphics/2d-graphics.html#tween-animation

【讨论】:

    【解决方案4】:

    我建议你使用处理程序

    int drawablebkg[] ={R.drawable.ic_launcher,R.drawable.icon};
    Handler m_handler;
    Runnable m_handlerTask ; 
    ImageView iv;
    iv = (ImageView)findViewById(R.id.imageView1);
    m_handler = new Handler(); 
       m_handlerTask = new Runnable()
        {
             @Override 
             public void run() {
                 iv.setImageResource(android.R.color.transparent); 
                if(i<2)
                {
    
                  ivsetBackgroundResource(drawablebkg[i]);
                  i++;
                }
                else 
                  {
                      i=0;
                  }
                  m_handler.postDelayed(m_handlerTask, 2000);
             }
        };
        m_handlerTask.run();  
    

    在你的活动的 onPause() 中

     @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
    
        //_t.cancel();
        m_handler.removeCallbacks(m_handlerTask);
    }  
    

    另一种方式

        iv= (ImageView)findViewById(R.id.imageView1);
        AnimationDrawable animation = new AnimationDrawable();
        animation.addFrame(getResources().getDrawable(R.drawable.ic_launcher), 2000);
        iv.setImageResource(android.R.color.transparent); 
        animation.addFrame(getResources().getDrawable(R.drawable.icon), 2000);
    
        animation.setOneShot(false);
    
        iv.setBackgroundDrawable(animation);
        //set setBackgroundDrawable(animation) is decprecreated i guess. not sure in which api
    
        // start the animation!
        animation.start();
    

    另一种方式

    在drawable文件夹中定义background.xml

    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/ic_launcher" android:duration="2000" />
    <item android:drawable="@drawable/icon" android:duration="2000" />
    </animation-list>
    

    我你的活动 onCreate();

    ImageView iv = (ImageView)findViewById(R.id.imageView1);
    iv.setBackgroundResource(R.drawable.background);
    
    AnimationDrawable animation= (AnimationDrawable)loadingRaven.getBackground();
    loadingRaven.setImageResource(android.R.color.transparent); 
    animation.start();
    

    注意停止动画需要调用animation.stop()

    【讨论】:

    • 我尝试了你的动画方式,但它无法识别 addFrame() 方法(我同时包含了 android.view.animation.Animation; 和 android.graphics.drawable.AnimationDrawable;)
    • 我有 import 语句作为 import android.graphics.drawable.AnimationDrawable;。它适用于我的设备。我在这里发布之前已经测试过
    • @DomeWTF 您是否收到任何异常或错误。你是在设备还是模拟器上测试?您的目标是哪个 android 版本。
    【解决方案5】:

    因为 UI 线程中的资源发生了变化,而您的 background 线程正在休眠。 UI 线程正常运行。 使用handlers:

    public class MainActivity extends Activity {
    
    Button b;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b = (Button) findViewById(R.id.button1);
    }
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
    
            if (msg.arg1 % 2 == 0) {
                b.setBackgroundResource(R.drawable.analytic_icon);
            } else {
                b.setBackgroundResource(R.drawable.ic_launcher);
            }
        }
    };
    
    @Override
    public void onResume() {
        super.onResume();
    
        Thread background = new Thread(new Runnable() {
            public void run() {
                try {
                    for (int i = 0; i < 20; i++) { 
                        Thread.sleep(2000);
                        Message msg = handler.obtainMessage(); 
                        msg.arg1 = i;
                        msg.sendToTarget();
                    }
                } catch (Throwable t) {
                    // just end the background thread
                }
            }
        });
    
        background.start();
    }
    }
    

    【讨论】:

    • 经过几次尝试,我注意到在执行“msg.sendToTarger()”后它再也没有回到循环
    • 这段代码对我来说运行良好。你能把这个 Log.v("DEBUG", String.valueOf(i)); 添加到循环中,然后把你的 logcat 转储发给我吗?
    【解决方案6】:

    试试这个,它会工作:

    public void show(final int size) {
        Thread thrd = new Thread(new Runnable() {
    
            @Override
            public void run() {
                for (int i = 0; i <= size - 1; i++) {
                    id = (Integer) sequence.get(i);
                    runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            sq.get(id - 1).setBackgroundResource(
                                    R.drawable.square_show);
                        }
                    });
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            sq.get(id - 1).setBackgroundResource(
                                    R.drawable.square);
                        }
                    });
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thrd.start();
    }
    

    【讨论】:

    • 在线程中使用睡眠是一个糟糕的设计。你也应该使用 Thread.sleep(2000);并将相同的内容放入 try 块和 catch (InterruptedException e)
    • 是的,你是对的,我只是给出了提示,如何解决给定的问题,因为这里我们不是在谈论良好的编码实践和设计模式等:)
    • 我会说您编辑您的帖子并添加注释或其他内容以表明这是不好的做法。它将帮助其他访问该帖子的人。
    猜你喜欢
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多