Подтвердить что ты не робот

В Android, как я плавно увядает фон от одного цвета к другому? (Как использовать потоки)

Я играю с Android-программированием в течение нескольких недель, и я пытаюсь заставить что-то работать, что кажется простым, но я думаю, что чего-то не хватает.

Я пытаюсь сделать так, чтобы фон постепенно исчезал, скажем, от белого до черного.

Я пробовал несколько вещей, ни одна из которых, похоже, не работает.

Первое, что я сделал, это использовать цикл for и метод setBackgroundColor для LinearLayout, изменяя значения R, G и B вместе от 0 до 255. Это не работает.

Я могу сделать одно из изменений настроек, но когда я делаю цикл, я получаю только последнее значение. Я думаю, что пользовательский интерфейс блокируется, пока цикл продолжается и размораживается, когда цикл завершается. Я попытался положить задержки в цикле (уродливые задержки вложенных циклов и 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);
        }
    }
}

Любая помощь будет принята с благодарностью

Приветствия

Стив

4b9b3361

Ответ 1

В вашей петле ваша настройка на фоне настолько быстра, что пользовательский интерфейс (не будет) способен запланировать обновление дисплея. Да, вам лучше использовать второй поток для обновления фона, иначе вы остановите поток пользовательского интерфейса. Попробуйте следующее:

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

Это потоковая версия вашего кода.

Ответ 2

Я нашел другой способ изменить цвет фона, если вам интересно - я думаю, что использование анимации будет проще, чем у вас в настоящее время:)

Если вы используете API-уровень 11 или выше, вы можете использовать ObjectAnimator для цвета фона вашего LinearLayout.

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

Кроме того, просто обратите внимание, должны использоваться 32-битные цветовые коды. Подробнее см. http://developer.android.com/reference/android/graphics/Color.html, но вы можете использовать Color.argb, Color.rgb, hex, как я использовал выше, или посмотреть на константы цвета int.

Надеюсь, это поможет!

Ответ 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, Девять старых андроидов позволят вам использовать API-интерфейс анимации на устройствах обратно на Android 1.0. 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();
}