Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android dynamically created table - bad performance

i would like you to help me. I want to create dynamicly table (screenshot). I created it via code below:

    TableLayout tl = (TableLayout) findViewById(R.id.main_table);

    FOR. 1-300.........
    TableRow tr_head = new TableRow(this);
    tr_head.setId(10);
    tr_head.setBackgroundColor(Color.CYAN);
    tr_head.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
    RelativeLayout rl = new RelativeLayout(this);
    rl.setId(20);


    ImageButton xyz = new ImageButton(this);
    xyz.setId(21);
    xyz.setPadding(5, 5, 5, 5);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 20 );
    rl.addView(xyz,params); 

    tr_head.addView(rl);
    tl.addView(tr_head, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); 
    END OF FOR.......  

Via similar code i nicely create 2 types of items one for category(3 child views) and one for category item(10 child views). Then i use code bellow to assign onclick listener for buttons and whole items.:

int count = tl.getChildCount();
    for(int i = 0; i < count; i++){
        TableRow v = (TableRow)tl.getChildAt(i);

        if(v.getChildAt(0) instanceof RelativeLayout){
            RelativeLayout relativ = (RelativeLayout)v.getChildAt(0);

        if(relativ.getChildCount()>5)
            relativ.setOnClickListener(new MyClickListener());
                     ...........

But when i want to create table which contains 300 items, it takes 30 sec. to render this view on emulator. It is really very slow. So i would like to ask you how to render this view. Some example or tutorial will be very helpfull.

Many Thanks in advance.

I want to create this

like image 478
Matin Petrulak Avatar asked Jan 17 '23 03:01

Matin Petrulak


2 Answers

Android is very slow at having many Views in memory. To work around this I would recommend using the default Andoird ListView with a custom ListAdapter.

The Views are created on the fly when the user scrolls the list, so only the currently visible Views have to be in memory.

This example uses a CursorAdapter, but you can also use an ArrayAdapter.

private class ExtendCursorAdapter extends CursorAdapter {

    public ExtendCursorAdapter(Context context, Cursor c) {
        super(context, c);
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) { //Determine if it's a category or an item
            return 0; // category
        } else {
            return 1; // item
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (getItemViewType(position) == 0) {
            View v;
            if (convertView != null)
                v = convertView;
            else
                v = inflater.inflate(R.id.listcategory);
            // Set title, ...
            return v;
        } else{
            // the same for the item
        }
    }
}

An additional performance increase comes from the usage of convertView. While scrolling you don't need to create any additional Views because Android reuses the ones which come out of sight. You just have to make sure to reset all data of convertView.

like image 60
flo Avatar answered Jan 20 '23 03:01

flo


I ran into similar performance problems, except all I wanted to do was display text in a formatted table shape (columns auto-sized etc). In this case, you may want to forego TableLayout entirely and use something like java.util.Formatter to transform text into a table shape and feed this to a single TextView. For me, this resulted in large performance gains (~2 seconds to load an activity down to almost instant).

See more detials here.

like image 25
Johnson Wong Avatar answered Jan 20 '23 02:01

Johnson Wong