Android ViewPager автоматически изменяет страницу
Я хочу запланировать действие для автоматического изменения моих страниц ViewPager.
Я пробовал:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
featureViewPager.setCurrentItem(currentPage++, true);
}
}, 100, 500);
но я всегда получаю:
E/AndroidRuntime(5381): FATAL EXCEPTION: Timer-0
E/AndroidRuntime(5381): java.lang.IllegalStateException: Must be called from main thread of process
Я уже в главной теме правильно? Как я могу это решить?
Спасибо за ваше время.
====================================
РЕДАКТИРОВАТЬ:
====================================
Спасибо за все ваши ответы. На основе этих ответов я столкнулся с двумя решениями:
Решение 1:
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
featureViewPager.setCurrentItem(currentPage++, true);
}
});
}
}, 500, 3000);
Решение 2:
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
featureViewPager.setCurrentItem(currentPage++, true);
}
};
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
handler.post(Update);
}
}, 500, 3000);
Какой из них лучше или они одинаковы?
Еще раз спасибо.
Ответы
Ответ 1
Если вы хотите использовать поток в главном ui, тогда вам нужно использовать hander, чтобы передать его.
Handler handler = new Handler();
Runnable update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES - 1) {
currentPage = 0;
}
featureViewPager.setCurrentItem(currentPage++, true);
}
};
new Timer().schedule(new TimerTask() {
@Override
public void run() {
handler.post(update);
}
}, 100, 500);
Ответ 2
Самый простой способ решить эту задачу - создать postDelayed runnable
private Handler mHandler;
public static final int DELAY = 5000;
Runnable mRunnable = new Runnable()
{
@Override
public void run()
{
//TODO: do something like mViewPager.setCurrentPage(mIterator);
mHandler.postDelayed( mRunnable , DELAY );
}
};
поскольку вы можете видеть, что он будет контур бесконечно. Когда вы хотите остановить его, просто вызовите
mHandler.removeCallbacks( mRunnable );
Ответ 3
TimerTask будет запускать на нем собственный поток (= не поток пользовательского интерфейса).
Вы можете просто вызвать setCurrentItem непосредственно в основном потоке с помощью Handler.