-1

I've a listview and each list item has a progressbar. I want to control that progressbar in a asynktask in this way : in onPreExecute() progressbar set to visible, in onPostExecute() the progressbar set to gone. I've tried with the following code but in this way sometimes it doesn't work and the progressbar is always visible:

  private class sendMsg extends AsyncTask<String, String, String>{
            String mess;
            int ind;

            @Override 
            protected void onPreExecute(){
                ind=lv.getLastVisiblePosition(); 
                addItems(mess, false,false,nick,null);  //here I add the item to listview
        }
    @Override
            protected String doInBackground(String... arg0) {.....}
        @Override
            protected void onPostExecute(String temp){

                if(temp.equals("SUCCESS")) {
                     View v = lv.getChildAt(ind+1);
                     ProgressBar pbb = (ProgressBar)  v.findViewById(R.id.messric);
                     pbb.setVisibility(View.GONE); }
            }

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"

     >
         <LinearLayout
        android:id="@+id/bollavera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:orientation="vertical"
        android:layout_margin="10dp"

        >

        <TextView
            android:id="@+id/comment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:layout_margin="5dip"
            android:paddingLeft="10dip"
            android:textColor="@android:color/primary_text_light"
            android:textSize="18dp" />

        <ProgressBar
            android:id="@+id/messric"
            style="?android:attr/progressBarStyleSmall"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone" />

</LinearLayout>
    </LinearLayout>

</RelativeLayout>

Another problem on this code is : if try to make the progressbar VISIBLE from the adapter, when there will be other items, the item before them has again a progressbar, also if i rotate the screen. I can't make visible that progressbar in the method onPreExecute() because i don't know if the item is just visible because i add the item 1 row before.

1 Answers1

2

You should probably make your custom adapter (you do have one, right?) have two types of items: one for when the progress bar should be shown, one for when it shouldn't. My answer on this related question might be able to help you get started.

Theoretically you could then just attach an AsyncTask to each of your adapter items. I have never benchmarked AsyncTasks but my guess is you'll have performance issues doing it that way. You might be better off with starting a worker thread, or maybe a handful of worker threads that process the items and then report back. Probably a HandlerThread with a custom Handler would be the easiest way to achieve this. I wrote a little very basic explanation on the relationship between handlers, handler threads and loopers in this question and you'll probably be able to find much more searching here on SO.

UPDATE

You are looking at two separate things and kind of mashing them up right now: One is business logic, one is visualization. Your adapter is only responsible for translating data into a visual representation of that data (i.e. progress bar shown or not). The manipulation of that data should happen somewhere else (for instance as the result of a "task finished" message that a worker thread sends to your handler on the UI thread). The handler could, for instance, set a flag on the corresponding data item and call notifyChange on your data structure.

If I were you, here's how I would go about it:

  1. I'm guessing you're using a simple array as your data structure right now. I'd change that to my own structure and make it implement ContentObservable. This will probably end up being a thin wrapper around an array or a List.

  2. Set up a handler on the UI thread.

  3. Set up one or more worker threads that handle network communication with the server. Each one should have a queue accepting tasks which it then runs one by one. Each time it is done, it sends a message back to your handler on the UI thread, something like "hey, I finished work for message #123 and the server said it was a success". (Then it goes on with the next task from its queue.)

  4. Your handler goes to your data structure, tells it "message #123 was confirmed by the server". The data structure updates itself (for instance by setting a flag on whatever item corresponds to message #123) and then calls notifyChange on itself.

  5. Your own adapter will have to be registered as an observer on the data structure. When it receives the change notification (from your data structure), it will in turn call notifyDatasetChanged on itself forcing the view to update. If you have implemented getView and getItemViewType correctly, this will automatically make the progress bar be visible or hidden.

Community
  • 1
  • 1
BadIdeaException
  • 2,125
  • 15
  • 32
  • my idea is to implement a similar whatsapp message deliver status but with the progressbar, so this is the suggested way to do it? – Francesco Stranieri Apr 29 '14 at 09:07
  • and yes i've an arrayadapter, it's a chat and it works, but I was thinking the best way to manage those progressbars – Francesco Stranieri Apr 29 '14 at 09:11
  • No, you misunderstood me. I think you'll want to implement your own adapter, that will know when to show or hide your progress bar. You could make it extend `ArrayAdapter`, that way you don't have to start completely from scratch. – BadIdeaException Apr 29 '14 at 09:23
  • The progressbar must disappear when there is a success response from server, so I have to wait the response and manage the progressbar. – Francesco Stranieri Apr 29 '14 at 09:28
  • I've edited my answer, see if that makes it a little clearer. Basically, you should not mix the "wait for the success response form the server" with the "show or hide progress bar" logic. While one affects the other, they are conceptually different things. Decoupling one from the other will give you much more clean, maintainable, testable code. – BadIdeaException Apr 29 '14 at 09:49