0

I have a ListView which contains progressBars, I want to show and hide the progressBar inside a Thread, here is my code :

public void onClick(View v) {
    if (v.getId() == R.id.ib_add_file) {
        Intent intent = new Intent(this, FilePickerActivity.class);
        startActivityForResult(intent, REQUEST_PICK_FILE);
    }
}

When I pick a file it will be added to the ListView and start uploading :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
        case REQUEST_PICK_FILE:
            if (data.hasExtra(FilePickerActivity.EXTRA_FILE_PATH)) {
                File file = new File(data.getStringExtra(FilePickerActivity.EXTRA_FILE_PATH));
                Fichier fichier = new Fichier();
                fichier.setFile(file);
                ArrayAdapter<Message> adapter = (ArrayAdapter<Message>) chat_list.getAdapter();
                adapter.add(fichier);
                int pos = adapter.getCount() - 1;
                MessageHolder holder = (MessageHolder) getViewByPosition(pos, chat_list).getTag();
                Log.i("Fichier", holder.fichier.getText().toString());
                //the log is showing the right file name
                holder.progress.setVisibility(View.VISIBLE);
                //the progressBar isn't showing !
                Log.i("ProgressBar", (holder.progress.getVisibility() == View.VISIBLE)? "Visible":"invisible");
                //the log is showing Visible !!!
            }
        }
    }
}

I'm using this function which i got from this answer to get the added row from the ListView to handle the ProgressBar:

public View getViewByPosition(int pos, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
    if (pos < firstListItemPosition || pos > lastListItemPosition) {
        return listView.getAdapter().getView(pos, null, listView);
    } else {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    MessageHolder msgHolder = null;
    Message msg = data.get(position);
    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        msgHolder = new MessageHolder();
        msgHolder.fichier = (TextView) row.findViewById(R.id.tv_fichier);
        msgHolder.iconFichier = (ImageView) row.findViewById(R.id.iv_icon_fichier);
        msgHolder.progress = (ProgressBar) row.findViewById(R.id.pb_fichier);
        row.setTag(msgHolder);
        //msgHolder.handler = new ProgressBarHandler(msgHolder.progress);
    } else {
        msgHolder = (MessageHolder) row.getTag();
    }
    Fichier fich = (Fichier) msg;
    msgHolder.fichier.setText(fich.getNomFichier());
    msgHolder.fichier.setPaintFlags(msgHolder.fichier.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
    msgHolder.iconFichier.setImageResource(fichier.getIconFichier());
    return row;
}

private static class MessageHolder {
    ImageView iconFichier;
    TextView fichier;
    ProgressBar progress;
    ProgressBarHandler handler;
}

And this is my xml for the the rows of the listview :

<ImageView
android:id="@+id/iv_icon_fichier"
style="@style/AvatarImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="@string/descThumbnail"
android:scaleType="centerCrop" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/iv_icon_fichier"
android:orientation="vertical" >

     <TextView
     android:id="@+id/tv_fichier"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textStyle="bold"
     android:textSize="22sp"
     android:text="Fichier" />

     <ProgressBar
     android:id="@+id/pb_fichier"
     style="?android:attr/progressBarStyleHorizontal"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:max="100"
     android:minWidth="200dp"
     android:progress="0"
     android:visibility="gone"/>
</LinearLayout>

Why my ProgressBar is not showing ?

Code Edited : I realized that my problem wasn't relater to the Handler, I tried showing the ProgressBar directly from my onActivityResult methode but it's not showing !

Community
  • 1
  • 1
user3578325
  • 229
  • 2
  • 6
  • 12
  • try this `public ProgressBarHandler(ProgressBar progressBar) {super(Looper.getMainLooper()); this.progressBar = progressBar; }` see if it helps – Elltz May 03 '15 at 01:39
  • thanks for the reply, I have edited my code, my problem isn't related to the Handler, have a look on my new onActivityResult code. – user3578325 May 03 '15 at 13:32
  • have you tried setting the progress ? like: holder.progress.setProgress(50); – Sam May 03 '15 at 13:45
  • it's not working too ... – user3578325 May 03 '15 at 13:55
  • yes it will not work i just forget, i never paid attention to the other post. i will try to post an answer okay sir – Elltz May 03 '15 at 15:36

2 Answers2

1

This is ListView's parent's

↳   android.view.ViewGroup
       ↳    android.widget.AdapterView<android.widget.ListAdapter>
           ↳    android.widget.AbsListView

looking at that i might even say i will call mylistView.removeViewAt(3); and that should work because of ViewGroup but it doesn't because of AdapterView.. Why i am saying this is that, i am no genius, that post has 44 upvotes, which means its legit, but i do not think that will be the way to go if you want to single out Update a View backed by an AdapterView because the getView method will override it your changes,even though the changes occur it doesn't neccessarily occur on your preffered View the View at position 0 is what the rest of the View start drawing from. eg, if you have an initial View with a visible TextView and an invisible EditText then all the Views will be like that unless you change one View before the getView returns(i have not used that method/way before and i am speaking with backed assumptions), so instead put another variable in your datasource like boolean needsupdate and check for needsupdate in your getView and change the Visibilty there. that will be the legit way to my intelligence -(maybe i might be a little off here). but give it a try

Elltz
  • 10,073
  • 3
  • 26
  • 55
  • Thanks for replying, but I really have problem in understanding what you mean, where exactly should i add the needsupdate variable and how I'm supposed to use it ? – user3578325 May 03 '15 at 19:09
  • in your dataObject, like you have a class that is your data object like this public class source{boolean needsupdate; String name;} etc etc , do you get me? in your case it should be `Fichier` then you check for it like `if(Fichier.needsupdate) // now change the visibility` @user3578325 – Elltz May 04 '15 at 21:01
  • hw was it sir @user3578325 – Elltz May 06 '15 at 19:44
  • it worked but there still some bugs so I changed the progressBar with a simple text view which shows the percentage and it works fine, thanks any way :) – user3578325 May 06 '15 at 20:55
  • aww you should have let me know about it maybe i could have extended my help, but im glad you found a way. btw if you weren't the one who upvoted, well you can give me an upvote :) lol, if you were its ok @user3578325 – Elltz May 06 '15 at 22:33
1

Have you tried putting the file retrieval code into a worker thread like this?

// set progressBar .VISIBLE first 

// then...    
new Thread(new Runnable() {
            public void run() {

                // file retrieval code

            }
        }).start();

Here is how it solved my own problem & here are the docs.

Community
  • 1
  • 1
rockhammer
  • 847
  • 1
  • 12
  • 35