在Android中,如何平滑地将背景从一种颜色渐变为另一种颜色?(如何使用线程)

plicqrtu  于 2022-12-25  发布在  Android
关注(0)|答案(6)|浏览(212)

我已经断断续续地玩了几个星期的Android编程,我试图让一些看起来很简单的东西工作,但我想我错过了一些东西。
我所要做的是让背景从白色平滑地褪成黑色。
我试过几种方法,似乎都不管用。
我做的第一件事是使用for循环和setBackgroundColor方法来实现LinearLayout,将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);
        }
    }
}

任何帮助都将不胜感激
干杯
史蒂夫

pb3s4cty

pb3s4cty1#

如果你感兴趣的话,我发现了另一种改变背景颜色的方法--我认为使用动画会比你现在使用的更容易:)
如果您使用的是API级别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颜色常量。

qacovj5a

qacovj5a2#

在您的循环中,您的后台设置太快,以至于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();
}

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

pb3s4cty

pb3s4cty3#

对于此问题,更好的答案是使用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();
zrfyljdw

zrfyljdw4#

如果有人正在寻找3.0之前版本的解决方案,Nine Old Androids将允许您在Android 1.0之前的设备上使用动画API。http://nineoldandroids.com/

u4vypkhs

u4vypkhs5#

更多适用于旧设备的解决方案:
计时器

@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();
}
093gszye

093gszye6#

private fun applyColorFade(fromColor: Int, toColor: Int) {
    ObjectAnimator.ofObject(
        toolbar, "backgroundColor", ArgbEvaluator(), 
        fromColor,
        toColor
    ).apply {
      duration = 2000
      startDelay = 200
      start()
    }
}

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

相关问题