3

Found a Solution!

I now use a ViewPager instead of a ViewFlipper. The Views are now generated within my run() method (which is already there because I fetch data from the web) and saveed in a Map. In my Handler I only call pagerAdapter.notifyDataSetChanged() the pagerAdapter uses the Map of views and it works smooth and fast. So I'm now looking for a away to have the ViewPager scroll endless, but thats another problem not connected to this one ;)

Thank all of you for your answers and keep up the good support.

I'm quite new to Android development and facing a problem while inflating a (huge) layout. I getting some Data from a Webservice which works fine then i'm using a handler within my Activity to bring this data to the frontend. Here is my handleMessage:

    public void handleMessage(Message msg) {
        LayoutInflater inflater = getLayoutInflater();

        List<Integer> gamedays = new ArrayList<Integer>(games.keySet());
        Collections.sort(gamedays);

        for (Integer gameday : gamedays) {

            View gamedaytable = inflater.inflate(R.layout.gamedaytable, null);
            TableLayout table = (TableLayout) gamedaytable.findViewById(R.id.gameDayTable);
            table.removeAllViews();
            List<Game> gamelist = games.get(gameday);
            int rowcount = 2;
            for (Game game : gamelist) {

                View tableRow = inflater.inflate(R.layout.gamedayrow, null);

                TextView homeTeam = (TextView) tableRow.findViewById(R.id.gameDayHome);
                TextView awayTeam = (TextView) tableRow.findViewById(R.id.gameDayAway);
                TextView gameResult = (TextView) tableRow.findViewById(R.id.gameDayResult);
                gameResult.setBackgroundResource(R.drawable.resultbackground);
                homeTeam.setText(game.getHomeTeam().getName());
                awayTeam.setText(game.getAwayTeam().getName());
                if (game.getHomegoals() < 0 || game.getAwaygoals() < 0) {
                    gameResult.setText("-:-");
                } else {
                    gameResult.setText(game.getHomegoals() + ":" + game.getAwaygoals());
                }

                if (rowcount % 2 == 0) {
                    tableRow.setBackgroundColor(0xffdee0dd);

                } else {
                    // setting alternative background
                    tableRow.setBackgroundColor(0xfff1f3f0);
                }
                rowcount++;

                table.addView(tableRow);
            }
            flipper.addView(gamedaytable);
        }
        flipper.setDisplayedChild(thisgameday - 1);
        pd.dismiss();

    }

My Problem is that this code runs quite slow and d the processdialog freezes for about 1 second before it disappears and the layout is shown. games consists of 34 entries which contains 9 entries by itself. So I'm adding 34 Views consisting of a relativeLayout () which holds the table I think the problem is, that android starts to draw and calculte the layout and this takes too long. If I'm correct i can not use AsynTask because i can not do UI stuff there and im doing UI stuff only.

I looking for a way to have the process dialog not freezing while doing this. Or maybe I'm doing some completly wrong

R.layout.gamedaytable:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff1f3f0"
android:focusableInTouchMode="false" >

<TableLayout
    android:id="@+id/gameDayTable"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:focusableInTouchMode="false" >
</TableLayout>

</RelativeLayout>

R.layout.gamedayrow:

<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusableInTouchMode="false"
android:paddingBottom="5dp"
android:paddingTop="5dp" >

<TextView
    android:id="@+id/gameDayHome"
    style="@style/textsizeSmallScreen"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:text="Mannschaft 1" />

<TextView
    android:id="@+id/textView2"
    style="@style/textsizeSmallScreen"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:text=":" />

<TextView
    android:id="@+id/gameDayAway"
    style="@style/textsizeSmallScreen"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Mannschaft 2" />

<TextView
    android:id="@+id/gameDayResult"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="5dp"
    android:background="@drawable/resultbackground"
    android:paddingLeft="10dip"
    android:text="0:5"
    android:textColor="#FFFFFF"
    android:textSize="11dp"
    android:textStyle="bold"
    android:typeface="monospace" />

</TableRow>

Additional Info: This is how the Table should look like. So i'm not sure if this should really be a ListView because for me its tabledata ;)

table

amfa
  • 51
  • 1
  • 6

4 Answers4

4

You seem to be building a list, you should probably look at using a ListView, which'll have the advantages of only needing to build the UI for the number of rows currently being shown, and to also do view re-use, so that you don't need to inflate as many rows.

superfell
  • 18,780
  • 4
  • 59
  • 81
  • It's not a list i think all rows are always shown. And at the moment is may look like a plain list but i plan to extend the table/list by grouping the entries which are soccer results for a specific matchday by the day they are played (which can be one day between friday and monday). I'm not sure if a ListView is the correct solution. – amfa Mar 10 '12 at 00:42
  • Still sounds like ListView or ExpandableListView would be the way to go. – superfell Mar 10 '12 at 01:54
2

Found a Solution!

I now use a ViewPager instead of a ViewFlipper. The Views are now generated within my run() method (which is already there because I fetch data from the web) and saveed in a Map. In my Handler I only call pagerAdapter.notifyDataSetChanged() the pagerAdapter uses the Map of views and it works smooth and fast. So I'm now looking for a away to have the ViewPager scroll endless, but thats another problem not connected to this one ;)

Thank all of you for your answers and keep up the good support.

amfa
  • 51
  • 1
  • 6
1

It is better to go for Listview. Even we can add more than one design of rows in the listview in an optimized manner which will improves the performance better.

Pavandroid
  • 1,586
  • 2
  • 15
  • 30
  • I have not tried the ListView yet (shame on me) but how do arrange the listentries the same way they are arrange within a table? And without giving the textViews a fixed width? E.g. the textView2s with the ":" have to be in the same "column" in every entry – amfa Mar 10 '12 at 11:40
  • You can add the child views in a LinearLayout with Horizonatal orientation. Add the sum weight as 4 and keep all the child layouts weight as 1. Don't for get keep the width of the parent to 0(Its an optimized way of saying it will occupy the complete screen). – Pavandroid Mar 10 '12 at 17:01
0

You definitely can do this on an AsyncTask. While you cannot update the UI on the doInBackground method of an AsyncTask, you can from the onProgressUpdate.

I would break up the code so you are iterating through items while in doInBackground, call publishProgress for each item, and then do the UI updates for the item when you get a callback in onProgressUpdate.

Eric Levine
  • 13,536
  • 5
  • 49
  • 49
  • I don't think this will solve the problem because the my code consists of UI updates only (except for getting the views) Or can I Inflate the layout in doInBackground and just do the flipper.addView in the publishProgress? – amfa Mar 10 '12 at 00:49
  • Inflating them on doInBackground might work. See: http://stackoverflow.com/questions/6691311/inflate-a-view-in-a-background-thread/6692007#6692007 – Eric Levine Mar 10 '12 at 01:27
  • But according to thethread i should not do this because it could have some side effects. Maybe i should use a complete different solution because even if the creation will work.. the viewflipper itself is somehow very slow and does not have this "App Feeling" ;) Thank you anyway for your help – amfa Mar 10 '12 at 01:56
  • One issue I see is that you have nested for loops. By using AsyncTask you can at least breakup the iteration and UI work. Since those will become asynchronous, it may let the UI gracefully handle the load. – Eric Levine Mar 10 '12 at 02:05
  • As of the newest Android firmware, I discovered that inflating views in the background can no longer safely be done. – Avi Cherry Apr 04 '13 at 21:35