tags:

views:

77

answers:

3

I use an BaseAdapter to display a list of objects. This objects are fetched from a server. The getView() method of the BaseAdapter is the following:

/* (non-Javadoc)
         * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LinearLayout content = (LinearLayout) View.inflate(lexs, R.layout.favorite_item, null);

            LinearLayout paragraphView = new LinearLayout(lexs); 
            paragraphView.setBackgroundColor(Color.RED);
            paragraphView.setGravity(Gravity.CENTER_VERTICAL);
            paragraphView.setOrientation(LinearLayout.HORIZONTAL);

            ImageView img = new ImageView(lexs);
            img.setImageResource(R.drawable.down);
            paragraphView.addView(img);
            img.setPadding(0, 0, 5, 0);
            img.setOnClickListener(new WorkspaceOnClickListener(position));

            TextView text = new TextView(lexs);
            text.setTextColor(Color.WHITE);
            text.setText(favorites.get(position).getParentChapter().getBook().getName() + ": §" + favorites.get(position).getName());
            text.setOnClickListener(new ParagraphOnClickListener(position));

            DisplayMetrics metrics = new DisplayMetrics();
            lexs.getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int maxWidth = metrics.widthPixels - 100;

            text.setMaxWidth(maxWidth);
            text.setMinWidth(maxWidth);
            paragraphView.addView(text);

            ImageView imgClose = new ImageView(lexs);
            imgClose.setMinimumHeight(30);
            imgClose.setMinimumWidth(30);
            imgClose.setImageResource(R.drawable.close);
            imgClose.setPadding(5, 0, 0, 0);
            paragraphView.addView(imgClose);
            imgClose.setOnClickListener(new CloseListener(position));

            content.addView(paragraphView);
            content.setPadding(0, 0, 0, 10);

            if (favorites.get(position).isExpanded()) {
                LinearLayout textLayer = new LinearLayout(lexs);
                textLayer.setBackgroundColor(Color.rgb(214, 214, 214));

                LinearLayout left = new LinearLayout(lexs);
                left.setOrientation(LinearLayout.VERTICAL);

                ImageView moveUp = new ImageView(lexs);
                moveUp.setImageResource(R.drawable.move_up);
                moveUp.setOnClickListener(new MoveListener(UP, position));
                moveUp.setPadding(0, 0, 0, 10);
                left.addView(moveUp);

                ImageView moveDown = new ImageView(lexs);
                moveDown.setImageResource(R.drawable.move_down);
                moveDown.setOnClickListener(new MoveListener(DOWN, position));
                left.addView(moveDown);

                TextView paragraphText = new TextView(lexs);
                paragraphText.setText(favorites.get(position).getText());
                paragraphText.setTextColor(Color.BLACK);

                LinearLayout right = new LinearLayout(lexs);
                right.setOrientation(LinearLayout.HORIZONTAL);
                right.addView(paragraphText);

                textLayer.addView(left);
                textLayer.addView(right);
                content.addView(textLayer);

                img.setImageResource(R.drawable.up);
            }

            return content;
        }

    }

So I'd like that this whole method is called in background and during the method is executed, a ProgresDialog is shown. I defined the ProgressDialog the following way:

public class LoadingInformation {

    private static ProgressDialog progressDialog;

    public static void showProgressInformation(Context view) {

        progressDialog = ProgressDialog.show(view, "Please wait...", "Doing Extreme Calculations...", true);
        System.out.println("Start Loading Screen");

    }

    public static void stopShowingProgressInformation() {

        Handler handler=new Handler();
        handler.post(new Runnable(){public void run(){progressDialog.dismiss();}});
        System.out.println("Stop Loading Screen");

    }

}

But the problem is, i don't know how to implement the calls correctly. I tried to replace all lines:

adapter.notifyDataSetChanged();

With the following code:

public void updateFavoriteList() {

        LoadingInformation.showProgressInformation(lexs);

        new Thread() {

            public void run() {

                lexs.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        adapter.notifyDataSetChanged();
                        LoadingInformation.stopShowingProgressInformation();
                    }

                });



            }

            }.start();


    }

But unfortunately this doesn't work as expected. Has anybody a hint how to do it betteR?

+1  A: 

The getView() method of the adapter isn’t responsible for downloading the content in the list, all it does is build the current row being displayed in the ListView. getView() doesn’t have anything to do with actually downloading the data from a network resource, which is where you wan’t the ProgressDialog.

When you instantiate the adapter (not shown in your code) you pass the data you want your BaseAdapter to populate the ListView with. Either the data has already been downloaded and simply handed off to the adapter, or the adapter itself does in the constructor.

If you wan’t the dataset for your ListView to change, you’re going to have to create some setter method or have a method in the adapter that refreshes the dataset from the network automatically. In any case though, this is where you want the ProgressDialog to show, not while the getView() method is setting up the ListView row.

P.S. One other suggestion I'd give is to make use of the convertView param passed to getView(). It'll improve the performance of your list by a lot if you have a large list. Check out Romain Guy's presentation about ListView in either the Google I/O 2009 or 2010 talks.


EDIT:

So “favorties” is an array (or List, etc.) of data for your ListView. You most likely pass the “favorites” data to the adapter via a constructor argument. At that point the data already exists in the adapter, or you’re passing a network location so the adapter can fetch the data and display it in the ListView.

For simplicity sake, lets say you download some string data into a String array, before passing it to the adapter. Each element contains a string to be displayed in your ListView via a TextView. You pass that array to the adapter and it handles formatting the ListView for you with the logic in the getView() method.

Now while you are downloading the data to populate the ListView with, you want to show the ProgressDialog to let the user know something is happening. Like some people have already said, you would use an AsyncTask to accomplish this. AsyncTask will allow you to display a ProgressDialog via onPreExecute() while you actually download the data in doInBackground() and get rid of the dialog in onPostExecute().

I hope that makes sense.

Jason Knight
Hmm I don't know if I understand you correctly. But in my code the data is fetched from a server in this line: text.setText(favorites.get(position).getParentChapter().getBook().getName() + ": §" + favorites.get(position).getName()); I know this isn't really a good way to do, but for now I have it that way. And thanks for the hint about convertView. As soon as I know how to use this, I'll changed the code.
Roflcoptr
Check out the edit I made to my post. It was too long to post as a comment.
Jason Knight
+1  A: 

The time consuming tasks should be handeld with an AsyncTask. Read http://developer.android.com/intl/fr/resources/articles/painless-threading.html

It has been added to the Android framework to help you do these time consuming things and update progress dialogs without having to code the boilerplate of Tasks and Handlers yourself.

Kevin Gaudin
Just a side note: Make sure you invoke the AsyncTask constructor on the GUI thread.
James Van Huis
A: 

I think you're looking for AsynTask.

Regards.

mrrtnn