My app is designed as follows:
Main Activity uses action bars
First tab is a fragment that is split into 3 sections
| Linear Layout containing List view | |Linear Layout containing List View | | Linear Layout containing media controls and image view|
I have two AsyncTasks within this activity, one that fills the centre list view, the other that starts with the media controls to fill the image view (album art).
Both of these are working well. The List view AsyncTask throws a progress dialog spinning wheel. This is coming up in the centre of the screen. I understand that I can put this spinner into the top right of the application. But can i place it either in the top right of the list views linear layout, or centred at the back of the linear layout? That way it would be unobtrusive yet obvious what the progress bar applied to?
Thanks in advance
I understand that I can put this spinner into the top right of the
application. But can i place it either in the top right of the list
views linear layout, or centred at the back of the linear layout?
If you can calculate the position of the view, you would probably be able to position the ProgressDialog
where you want(for example see this question I answered Change position of progressbar in code). Also, keep in mind, that this could be very counter intuitive for the user who would see the screen for the dialog and the dialog placed at some weird position(he may not make the correlation between the position of the ProgressDialog
and the view for which the data is loaded).
Another option could be to modify the current layout for the ListView
part to add on top an initial gone FrameLayout
(which will cover the entire ListView
) with a background that simulates the background for a screen with a Dialog
(this FrameLayout
will contain a ProgressBar
placed where you want). This FrameLayout
would be made visible when the AsyncTask
kicks in(it may be wise to block the touch events for the underlining ListView
). This way the user can still do stuff in your app and it has a clear indication for the View
that is loading its data. Of course this will work well if it's possible for the user to work with the other data independently from the loading ListView
.
The answer from Luksprog is so good that I thought I should list the code here: Absolutely perfect
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/first_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/anchor" >
</ListView>
<View
android:id="@id/anchor"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_centerVertical="true"
android:background="#99cc00" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/anchor" >
<ListView
android:id="@+id/second_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#33c1c1c1"
android:visibility="gone" >
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|top"
android:indeterminate="true" />
</FrameLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
private String[] mItems = { "Item no.1", "Item no.2", "Item no.3",
"Item no.4", "Item no.5", "Item no.6", "Item no.7", "Item no.8",
"Item no.9", "Item no.10", "Item no.11", };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
// setup the two ListViews
ListView firstList = (ListView) findViewById(R.id.first_list);
firstList.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mItems));
firstList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// just as an example, one you click an item in the first
// ListView
// a custom AsyncTask will kick in to load data in to the second
// ListView
new MyTask(MainActivity.this).execute((Void) null);
}
});
ListView secondList = (ListView) findViewById(R.id.second_list);
secondList.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mItems));
secondList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// just to test that you can't click the ListView if the data is
// loading
Toast.makeText(getApplicationContext(), "click",
Toast.LENGTH_SHORT).show();
}
});
}
private class MyTask extends AsyncTask<Void, Void, Void> {
private MainActivity mActivity;
private FrameLayout mFrameOverlay;
public MyTask(MainActivity activity) {
mActivity = activity;
}
@Override
protected void onPreExecute() {
// the AsyncTask it's about to start so show the overlay
mFrameOverlay = (FrameLayout) mActivity.findViewById(R.id.overlay);
// set a touch listener and consume the event so the ListView
// doesn't get clicked
mFrameOverlay.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mFrameOverlay.setVisibility(View.VISIBLE);
}
@Override
protected Void doInBackground(Void... params) {
// do heavy work
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
//remove the overlay
mFrameOverlay.setVisibility(View.GONE);
// setup the ListView with the new obtained data
String[] obtainedData = { "D1", "D2", "D3" };
ListView theList = (ListView) mActivity
.findViewById(R.id.second_list);
theList.setAdapter(new ArrayAdapter<String>(mActivity,
android.R.layout.simple_list_item_1, obtainedData));
}
}
}
Luksprog, hope you don't mind me posting your code, just didn't want it to vanish from git and this answer be lost to others.