Android runOnUiThread 以显示进度对话框并填充视图
Android runOnUiThread to show progress dialog and to populate views
我通常在 .Net 上工作,但我需要开发一个 Android 应用程序。所以我是Android的新手,提前为错误道歉! :)
这是我的故事,
我正在填充一个客户列表(在代码后面创建 ui 元素),单击按钮即可查看。我正在这样做,从数据库中提取数据。所以提取数据和创建视图需要一些时间。我想做的是在填充客户列表时显示进度对话框。目前我可以做到 运行。但问题是它没有立即显示进度对话框,然后同时显示客户列表和进度对话框。
这是我的按钮点击;
public void ShowCustomers(View view){
final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.setTitle("Title");
dialog.setMessage("Loading...");
if(!dialog.isShowing()){
dialog.show();
}
}
});
new Thread() {
public void run() {
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
PopulateRecentGuests(); //Creates customer list dynamically
dialog.dismiss();
}
});
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}.start();
}
并填充客户;
public void PopulateRecentGuests(){
LinearLayout customers = (LinearLayout)findViewById(R.id.customers);
String query = "SELECT * from Table";
ModelCustomer customerModel = new ModelCustomer();
ArrayList<HashMap<String, String>> recentGuests = customerModel.RetrievingQuery(query);
customersCount = recentGuests.size();
Context context = getApplicationContext();
if(customersCount < 1)
Toast.makeText(context, "There is no available customer in database!", Toast.LENGTH_LONG);
else if(!recentGuests.get(0).containsKey("err")) {
for(int i = 0; i < recentGuests.size(); i++){
HashMap<String, String> guest = recentGuests.get(i);
Button button = new Button(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0,5,0,5);
button.setLayoutParams(params);
button.setWidth(800);
button.setHeight(93);
button.setTag(guest.get("id"));
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("New button clicked! ID: " + v.getTag());
Intent intent = new Intent(getApplicationContext(), ProductPageActivity.class);
intent.putExtra("CustomerID", v.getTag().toString());
startActivity(intent);
}
});
button.setBackgroundColor(Color.parseColor("#EFEFEF"));
button.setText(guest.get("FirstName") + " " + guest.get("LastName") + " " + guest.get("GuideName"));
button.setTextColor(Color.BLACK);
button.setTextSize(20);
button.setEnabled(false);
customers.addView(button); // customers is a linear layout and button is being added to customers
Button guest_list_btn = (Button)findViewById(R.id.guest_list_btn);
guest_list_btn.setEnabled(true);
}
}
else{
CharSequence text = recentGuests.get(0).get("err");
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
Button guest_list_btn = (Button)findViewById(R.id.guest_list_btn);
Button guest_list_close_btn = (Button)findViewById(R.id.guest_list_close_btn);
customers.setVisibility(View.VISIBLE);
AnimationSet aset = new AnimationSet(true);
aset.setFillEnabled(true);
aset.setInterpolator(new LinearInterpolator());
AlphaAnimation alpha = new AlphaAnimation(0.0F, 1.0F);
alpha.setDuration(400);
aset.addAnimation(alpha);
TranslateAnimation trans = new TranslateAnimation(200, 0, 0, 0);
trans.setDuration(400);
aset.addAnimation(trans);
customers.startAnimation(aset);
guest_list_btn.setEnabled(false);
guest_list_close_btn.setEnabled(true);
for(int i = 0; i < customers.getChildCount(); i++){
View child = customers.getChildAt(i);
child.setEnabled(true);
}
}
经过我的研究,我了解到运行onuithread是在looper之后调用的。我的问题是如何立即显示进度对话框然后填充客户列表(创建 ui 元素)。顺便说一下,我首先尝试使用 asynctask 来做到这一点,但我做不到。
比提前!
But the problem is it doesn't show the progress dialog immediately,
then customerlist and progress dialog are displayed at the same time.
那是因为您在 UI 主线程上进行了长时间操作(并按顺序关闭了对话框)。相反,您应该将检索数据(这需要时间)和构建视图(以及关闭对话框)分开。
//...
new Thread() {
public void run() {
// do the long operation on this thread
final ArrayList<HashMap<String, String>> recentGuests = customerModel.RetrievingQuery(query);
// after retrieving the data then use it to build the views and close the dialog on the main UI thread
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
// remove the retrieving of data from this method and let it just build the views
PopulateRecentGuests(recentGuests);
dialog.dismiss();
}
});
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}.start();
我通常在 .Net 上工作,但我需要开发一个 Android 应用程序。所以我是Android的新手,提前为错误道歉! :)
这是我的故事, 我正在填充一个客户列表(在代码后面创建 ui 元素),单击按钮即可查看。我正在这样做,从数据库中提取数据。所以提取数据和创建视图需要一些时间。我想做的是在填充客户列表时显示进度对话框。目前我可以做到 运行。但问题是它没有立即显示进度对话框,然后同时显示客户列表和进度对话框。
这是我的按钮点击;
public void ShowCustomers(View view){
final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.setTitle("Title");
dialog.setMessage("Loading...");
if(!dialog.isShowing()){
dialog.show();
}
}
});
new Thread() {
public void run() {
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
PopulateRecentGuests(); //Creates customer list dynamically
dialog.dismiss();
}
});
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}.start();
}
并填充客户;
public void PopulateRecentGuests(){
LinearLayout customers = (LinearLayout)findViewById(R.id.customers);
String query = "SELECT * from Table";
ModelCustomer customerModel = new ModelCustomer();
ArrayList<HashMap<String, String>> recentGuests = customerModel.RetrievingQuery(query);
customersCount = recentGuests.size();
Context context = getApplicationContext();
if(customersCount < 1)
Toast.makeText(context, "There is no available customer in database!", Toast.LENGTH_LONG);
else if(!recentGuests.get(0).containsKey("err")) {
for(int i = 0; i < recentGuests.size(); i++){
HashMap<String, String> guest = recentGuests.get(i);
Button button = new Button(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0,5,0,5);
button.setLayoutParams(params);
button.setWidth(800);
button.setHeight(93);
button.setTag(guest.get("id"));
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("New button clicked! ID: " + v.getTag());
Intent intent = new Intent(getApplicationContext(), ProductPageActivity.class);
intent.putExtra("CustomerID", v.getTag().toString());
startActivity(intent);
}
});
button.setBackgroundColor(Color.parseColor("#EFEFEF"));
button.setText(guest.get("FirstName") + " " + guest.get("LastName") + " " + guest.get("GuideName"));
button.setTextColor(Color.BLACK);
button.setTextSize(20);
button.setEnabled(false);
customers.addView(button); // customers is a linear layout and button is being added to customers
Button guest_list_btn = (Button)findViewById(R.id.guest_list_btn);
guest_list_btn.setEnabled(true);
}
}
else{
CharSequence text = recentGuests.get(0).get("err");
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
Button guest_list_btn = (Button)findViewById(R.id.guest_list_btn);
Button guest_list_close_btn = (Button)findViewById(R.id.guest_list_close_btn);
customers.setVisibility(View.VISIBLE);
AnimationSet aset = new AnimationSet(true);
aset.setFillEnabled(true);
aset.setInterpolator(new LinearInterpolator());
AlphaAnimation alpha = new AlphaAnimation(0.0F, 1.0F);
alpha.setDuration(400);
aset.addAnimation(alpha);
TranslateAnimation trans = new TranslateAnimation(200, 0, 0, 0);
trans.setDuration(400);
aset.addAnimation(trans);
customers.startAnimation(aset);
guest_list_btn.setEnabled(false);
guest_list_close_btn.setEnabled(true);
for(int i = 0; i < customers.getChildCount(); i++){
View child = customers.getChildAt(i);
child.setEnabled(true);
}
}
经过我的研究,我了解到运行onuithread是在looper之后调用的。我的问题是如何立即显示进度对话框然后填充客户列表(创建 ui 元素)。顺便说一下,我首先尝试使用 asynctask 来做到这一点,但我做不到。
比提前!
But the problem is it doesn't show the progress dialog immediately, then customerlist and progress dialog are displayed at the same time.
那是因为您在 UI 主线程上进行了长时间操作(并按顺序关闭了对话框)。相反,您应该将检索数据(这需要时间)和构建视图(以及关闭对话框)分开。
//...
new Thread() {
public void run() {
// do the long operation on this thread
final ArrayList<HashMap<String, String>> recentGuests = customerModel.RetrievingQuery(query);
// after retrieving the data then use it to build the views and close the dialog on the main UI thread
try{
runOnUiThread(new Runnable() {
@Override
public void run() {
// remove the retrieving of data from this method and let it just build the views
PopulateRecentGuests(recentGuests);
dialog.dismiss();
}
});
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}.start();