我正在设计一个小应用程序,每秒用随机字母更改TextView
。
现在,我的代码看起来像这样并且效果很好:
@BindView(R.id.textview_letter) TextView letterTV;
private static final int DELAY_MILLIS = 1000;
private static final int LOOP_MAX = 10;
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private Handler h = new Handler();
private Random random = new Random();
private int position = 0;
private Runnable run = new Runnable() {
@Override
public void run() {
if (position >= LOOP_MAX) {
letterTV.setText("THE END !");
h.removeCallbacks(run);
} else {
String randomLetter = String.valueOf(ALPHABET.charAt(random.nextInt(ALPHABET.length())));
letterTV.setText(randomLetter);
h.postDelayed(run, DELAY_MILLIS);
position++;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
ButterKnife.bind(this);
h.post(run);
}
我现在想通过在每个字母之间将TextView
的背景设置为黑色(或使其不可见)几毫秒来改进它,因此如果在两个字母中有两倍相同的字母,则通知用户行。
我唯一的想法就是在我的Runnable
中添加另一个Runnable
并使用拆分延迟处理它们(例如700和300毫秒),但这看起来非常复杂。
这样做的正确方法是什么?
(顺便说一句,Runnable / Handler真的是我最适合使用的模式吗?)
编辑:在非UI线程中我可以做这样的事情:
while (randomLetter.next()) {
letterTV.setText(randomLetter);
Thread.sleep(700);
letterTV.setBackgroundColor(Color.BLACK);
Thread.sleep(300);
}
答案 0 :(得分:3)
使用RxAndroid,会降低复杂性:
public class Test extends AppCompatActivity {
private Disposable randomLetterObservable;
private TextView textView;
private Random random = new Random();
private final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
randomLetterObservable = Observable.interval(500L, TimeUnit.MILLISECONDS)
.timeInterval()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Timed<Long>>() {
@Override
public void accept(Timed<Long> longTimed) throws Exception {
String randomLetter = String.valueOf(ALPHABET.charAt(random.nextInt(ALPHABET.length())));
textView.setText(randomLetter);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (randomLetterObservable != null) {
randomLetterObservable.dispose();
}
}
}
有依赖关系:
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.8'
编辑:这是一个经过修改的解决方案,如果连续两次出现相同的字母,也会更改背景。
public class Test extends AppCompatActivity {
private Disposable randomLetterObservable;
private TextView textView;
private Random random = new Random();
private final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private String lastLetter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
randomLetterObservable = Observable.interval(700L, TimeUnit.MILLISECONDS)
.timeInterval()
.observeOn(AndroidSchedulers.mainThread())
.switchMap(new Function<Timed<Long>, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Timed<Long> longTimed) throws Exception {
String randomLetter = String.valueOf(ALPHABET.charAt(random.nextInt(ALPHABET.length())));
if (randomLetter.equals(lastLetter)) {
textView.setBackgroundColor(Color.BLACK);
return Observable.just(randomLetter)
.observeOn(Schedulers.computation())
.debounce(300L, TimeUnit.MILLISECONDS);
} else {
lastLetter = randomLetter;
return Observable.just(randomLetter);
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
textView.setText(s);
textView.setBackgroundColor(Color.TRANSPARENT);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (randomLetterObservable != null) {
randomLetterObservable.dispose();
}
}
}
事件在后台线程中发出,背景颜色和字母在主线程上设置。我认为这几乎就是你所要求的。 (您可能需要使用这些值来获得所需的效果)。
祝你好运。