Android - с помощью runOnUiThread для изменения пользовательского интерфейса из потока
Я использую собственное представление заголовка и хотел бы показать/скрыть индикатор прогресса в представлении заголовка, когда поток работает.
Это мое представление заголовка XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/image_left_btn"
android:layout_width="75dip"
android:layout_height="wrap_content"
android:text="Back"
/>
<TextView
android:id="@+id/image_title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20dip"
android:textStyle="bold"
android:textColor="#fff"
android:layout_gravity="center"
android:gravity="center"
android:paddingLeft="8dip"
android:paddingRight="8dip"
/>
<ProgressBar
android:id="@+android:id/progress_small_title"
style="?android:attr/progressBarStyleSmall"
android:layout_width="75dip"
android:layout_height="wrap_content"
android:paddingRight="8dip"/>
</LinearLayout>
В моей деятельности, установив это как пользовательскую строку заголовка, я делаю это
titleProgress = (ProgressBar)findViewById(R.id.progress_small_title);
titleProgress.setVisibility(View.INVISIBLE);
где titleProgress - объект ProgressBar.
Это то, что я делаю в своем потоке
runOnUiThread(new Runnable() {
public void run() {
titleProgress.setVisibility(View.VISIBLE);
}
});
//long operation here
runOnUiThread(new Runnable() {
public void run() {
titleProgress.setVisibility(View.INVISIBLE);
}
});
Но нет изменений в индикаторе выполнения. Он никогда не отображается. Может кто-нибудь, пожалуйста, скажите мне, что не так с кодом?
Можно ли отобразить панель прогресса заголовка в пользовательском заголовке?
Спасибо.
Ответы
Ответ 1
Несколько вещей, чтобы попробовать:
1) (Возможно, это не так) Убедитесь, что "titleProgress
" является изменчивым.
2) Попробуйте бросить несколько postInvalidate()
или titleProgress.postInvalidate()
там, чтобы вызвать перерисовку.
3) Вы пристрастились к машине x486 на аллее, напоминающем гигантский зеленый робот? (просто шучу)
Сообщите мне, если эти первые два (и если вы действительно отчаянные, третий) доставите вас куда угодно.
Ответ 2
Что вы должны использовать в этом случае, это AsyncTask, см.
http://developer.android.com/reference/android/os/AsyncTask.html
Если вы не нацелены на версию Android до версии 1.5, вам придется использовать другой класс UserTask.
См. http://android-developers.blogspot.com/2009/05/painless-threading.html
Ответ 3
использовать связь с обработчиками,
- выполнить поток
- в
run()
: вы должны отправить сообщение обработчику, который обновит progressBar (горизонтально, конечно): handler.sendMessage(handler.obtainMessage());
-
в вашей деятельности, вы должны переопределить метод handleMessage(Message msg )
: вроде этого
handler = new Handler(){
@override
public void handleMessage(Message msg )
{
//here you write the code which will update your progressBar
}
};
Ответ 4
Правильно ли ваш макет? Вы пытались сначала выполнить эту работу с вертикальной компоновкой? Просто чтобы увидеть, отображается ли индикатор выполнения, когда вы начинаете свою деятельность?
Ответ 5
Попробуйте изменить стиль ProgressBar на горизонтальный:
style="?android:attr/progressBarStyleHorizontal"
Оригинальный
style="?android:attr/progressBarStyleSmall"
дает круговой "индикатор прогресса", который нельзя полностью увидеть в заголовке.