Android Progress dialog within listview
Asked Answered
P

2

1

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

Psychodiagnostics answered 19/7, 2012 at 8:7 Comment(1)
I'm not sure to understand, can you upload a mockup ?Selffulfillment
F
2

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.

Floruit answered 19/7, 2012 at 8:41 Comment(4)
Hi, the second option is what I'm after. Now just need to figure out how to tie a progress bar to an xml layout and then work out how to swap the backgrounds! Thanks again.Psychodiagnostics
So...if i follow this link for the custom dialog [link]hrupin.com/2011/09/… then work out how to interchange that with the linear layout background I should be where i want to be!Psychodiagnostics
@AdamSherratt That link doesn't work. Anyway, I've built a small example on how you might do it, you can find it here gist.github.com/3142840 . It has some commentaries so you should be able to understand.Floruit
wow, thats the kind of helpfulness that gets you a +1! I'll check it out tonight, many many thanksPsychodiagnostics
P
2

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.

Psychodiagnostics answered 19/7, 2012 at 20:3 Comment(3)
No problem, anyway the gist is linked to my account and I don't plan on leaving programming so it will be there:)Floruit
If you have problems don't hesitate to post a question on stackoverflow.Floruit
Way ahead of you:) Its almost working, just need to work out whats wrong with the final part. See last comment. [Link]#11556000Psychodiagnostics

© 2022 - 2024 — McMap. All rights reserved.