【问题标题】:In Android, how do I smoothly fade the background from one color to another? (How to use threads)在Android中,如何平滑地将背景从一种颜色淡化为另一种颜色? (如何使用线程)
【发布时间】:2011-03-05 00:42:07
【问题描述】:

我已经断断续续地玩了几个星期的 Android 编程,我试图让一些看起来很简单的东西工作起来,但我认为我错过了一些东西。

我想要做的是让背景从白色平滑地渐变到黑色。

我尝试了一些方法,但似乎都不起作用。

我做的第一件事是使用 for 循环和 LinearLayout 的 setBackgroundColor 方法,将 R、G 和 B 值一起从 0 更改为 255。它不起作用。

我可以做一个设置更改,但是当我做循环时,我只得到最后一个值。我认为正在发生的是 UI 在循环进行时锁定,而在循环结束时解冻。我尝试在循环中添加延迟(丑陋的嵌套循环延迟和 Thread.sleep),但都无济于事。

谁能给我任何关于如何让它工作的指示?我需要第二个线程来更改颜色吗?我对线程有一个模糊的概念,虽然我从未使用过它们。

我的示例代码大致显示了我正在尝试做的事情如下:

main.xml 是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/screen"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

而我的java代码是(0.01 inc.只是作为一个丑陋的延迟机制来尝试看到颜色变化缓慢):

package nz.co.et.bgfader;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class bgfader extends Activity {

    LinearLayout screen;

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        screen = (LinearLayout) findViewById(R.id.screen);
        for (int i = 0; i < 65535; i+=0.01) {
            screen.setBackgroundColor(0xff000000 + i);
        }
    }
}

任何帮助将不胜感激

干杯

史蒂夫

【问题讨论】:

    标签: android


    【解决方案1】:

    如果您有兴趣,我发现了另一种更改背景颜色的方法——我认为使用动画会比您目前使用的更容易:)

    如果您使用 API Level 11 或更高版本,您可以在 LinearLayout 的背景颜色上使用 ObjectAnimator。

     ObjectAnimator colorFade = ObjectAnimator.ofObject(screen, "backgroundColor", new ArgbEvaluator(), Color.argb(255,255,255,255), 0xff000000);
      colorFade.setDuration(7000);
      colorFade.start();
    

    另外,请注意,必须使用 32 位 int 颜色代码。有关详细信息,请参阅http://developer.android.com/reference/android/graphics/Color.html,但您可以使用 Color.argb、Color.rgb、我上面使用的十六进制,或者查看 int 颜色常量。

    希望这会有所帮助!

    【讨论】:

    • 谢谢 - 我使用的是 2.2,所以这个解决方案不会奏效......鉴于它是为我女儿准备的夜灯应用程序,而她的平板电脑是基于 2.2 的,我会需要坚持使用原始的线程选项......但我喜欢这种方式,因为它很简单,所以我可能会对它进行修改。干杯
    • 真的很高兴知道。只为 3.0+ 感到羞耻。为 2.2/2.3+ 寻找类似的解决方案
    【解决方案2】:

    在您的循环中,您在后台的设置是如此之快,以至于 UI 无法(将无法)安排显示更新。是的,您最好使用第二个线程来更新背景,否则您将停止 UI 线程。请尝试以下操作:

    LinearLayout screen;
    Handler handler = new Handler();
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        screen = (LinearLayout) findViewById(R.id.screen);
    
        (new Thread(){
            @Override
            public void run(){
                for(int i=0; i<255; i++){
                    handler.post(new Runnable(){
                        public void run(){
                            screen.setBackgroundColor(Color.argb(255, i, i, i));
                        }
                    });
                    // next will pause the thread for some time
                    try{ sleep(10); }
                    catch{ break; }
                }
            }
        }).start();
    }
    

    这是您的代码的线程版本。

    【讨论】:

    • 谢谢! :) 就这样,做了一些小的改动。我必须使 i 成为全局变量,因为否则无法在 run 方法中访问它(或者我猜我可以通过它)。我还必须调整 try/catch,因为它不会按原样为我编译。非常感谢,这让我疯了几天。我会玩一下线程,看看我能不能用这段代码做一些有趣的事情。
    • 这不是一个好的做法。您不允许从 bg 线程更新 UI。 @Amy 的建议是正确的。有一个项目nineoldandroids.com 为Android pre-3.0 实现了ObjectAnimator
    • 如果我想使用TextView 中的seekbar 值将一种颜色淡化成另一种颜色怎么办?
    • 应该更新每个更新帧并使用增量时间变量来倍增结果,这将在某些设备上随速度增加和减少。
    【解决方案3】:

    这个问题的更好答案是使用ObjectAnimator

    ObjectAnimator colorFade = ObjectAnimator.ofObject(view, "backgroundColor" /*view attribute name*/, new ArgbEvaluator(), mContext.getResources().getColor(R.color.colorMenuOverlay) /*from color*/, Color.WHITE /*to color*/);
                    colorFade.setDuration(3500);
                    colorFade.setStartDelay(200);
                    colorFade.start();
    

    【讨论】:

      【解决方案4】:

      如果有人在寻找 3.0 之前的解决方案,九老 Android 将允许您在回到 Android 1.0 的设备上使用动画 API。 http://nineoldandroids.com/

      【讨论】:

        【解决方案5】:

        针对旧设备的更多解决方案:

        计时器

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            final Timer myTimer = new Timer();
            final View myview = getWindow().getDecorView().findViewById(
                    android.R.id.content);
        
            myTimer.schedule(new TimerTask() {
                int color = 0;
                @Override
                public void run() {
                    // If you want to modify a view in your Activity
                    runOnUiThread(new Runnable() {
                        public void run() {
                            color++;
                            myview.setBackgroundColor(Color.argb(255, color, color,
                                    color));
                            if (color == 255)
                                myTimer.cancel();
                        }
                    });
                }
            }, 1000, 20); // initial delay 1 second, interval 1 second
        
        }
        

        线程

            @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            new Thread() {
                int color = 0;
                View myview = getWindow().getDecorView().findViewById(
                        android.R.id.content);
                @Override
                public void run() {
                    for (color = 0; color < 255; color++) {
                        try {
                            sleep(20);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    myview.setBackgroundColor(Color.argb(255,
                                            color, color, color));
                                }
                            });
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
        

        【讨论】:

          【解决方案6】:
          private fun applyColorFade(fromColor: Int, toColor: Int) {
              ObjectAnimator.ofObject(
                  toolbar, "backgroundColor", ArgbEvaluator(), 
                  fromColor,
                  toColor
              ).apply {
                duration = 2000
                startDelay = 200
                start()
              }
          }
          

          // 这是一个可重用的视图颜色渐变动画方法

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-18
            • 2019-01-29
            相关资源
            最近更新 更多