Android TableLayout с более чем 1000 строк загружается очень медленно


Я ищу способ ускорить создание TableLayout с более чем 1000 строк. Есть ли способ создать TableLayout полностью на отдельном потоке или способ ускорить его?

Вот мой метод, который создает таблицу:

private void setTable()
{       
    final Activity activity = this;

    final Handler handler = new Handler();

    new Thread(new Runnable()
    {
        @Override
        public void run() 
        {
            for (int x = 0; x < rooms.size(); x++)
            {
                final int inx = x;
                handler.post(new Runnable()
                {
                    @Override
                    public void run() 
                    {
                        Methods.createRow(table, rooms.get(inx), null, activity);
                        TableRow row = (TableRow)table.getChildAt(inx);
                        row.setOnClickListener(new OnClickListener()
                        {
                            @Override
                            public void onClick(View arg0) 
                            {
                                if (arg0.getTag() != null && arg0.getTag().getClass() == Integer.class)
                                    select((Integer)arg0.getTag());
                            }
                        });
                    }
                });
            }
        }

    }).start();
}

Я надеялся, что использование обработчика по крайней мере позволит новому действию появиться до создания таблицы. При создании таблиц с большим количеством строк приложение, по-видимому, замирает на несколько секунд. setTable () выполняется в моем Метод Activity onStart ().

Методы

.метод createrow добавляет строку в конец метода TableView, который передается.

Редактировать:

После того, как я решил попробовать ListView, я получил гораздо лучшие результаты с гораздо меньшим количеством кода.
private void setTable()
{
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, roomNames);
    table.setAdapter(adapter);
    table.setOnItemClickListener(new OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
        {
            select(arg2);
        }
    });
}
3 2

3 ответа:

Прежде всего.

Почему ваше приложение зависает: Обработчик работает как очередь, он помещает в очередь каждое сообщение, которое вы сделали, и затем выполняет его последовательно в главном потоке.

Но основная проблема-это количество данных, которые вы пытаетесь показать сразу, но это легко решается с помощью адаптера, вы, вероятно, можете использовать какой-то компонент по умолчанию для решения этой проблемы, например ListView или GridView, Вы можете сделать ваши пользовательские строки для работы вокруг столбцов, возможно.

Просто угадав имя метода, кажется, что эта строка может медленно выполняться в главном потоке / UI: Методы.createRow (стол, комнаты.get(inx), null, activity);

Я бы предложил разделить всю тяжелую работу с базой данных и работу пользовательского интерфейса с AsyncTask, так что это может выглядеть примерно так:

private OnClickListener rowClickListener = new OnClickListener()
{
    @Override
    public void onClick(View arg0) 
    {
        if (arg0.getTag() != null && arg0.getTag().getClass() == Integer.class)
            select((Integer)arg0.getTag());
    }
};

private void setTable()
{       
    final Activity activity = this;

    final Handler handler = new Handler();

    new AsyncTask<Void, Void, List<TableRow>>() {
        @Override
        protected List<TableRow> doInBackground(Void... params) {
            // Do all heavy work here
            final List<TableRow> rows = new ArrayList<TableRow>(rooms.size());
            for (int x = 0; x < rooms.size(); x++)
            {
                Methods.createRow(table, rooms.get(x), null, activity);
                rows.add((TableRow)table.getChildAt(x));
            }
            return rows;
        }

        @Override
        protected void onPreExecute() {
            // maybe show progress indication
        }

        @Override
        protected void onPostExecute(List<TableRow> result) {
            // Do all UI related actions here (maybe hide progress indication)
            for (final TableRow row : result) {
                row.setOnClickListener(rowClickListener);
            }
        }
    };
}
Поскольку я не могу сказать, что находится в некоторых методах, вам просто нужно убедиться, что вы попытались оптимизировать как можно лучше в методах.метод createrow(...) и переместить всю работу, связанную с пользовательским интерфейсом, в onPostExecute(...) метод.

Вы укладываете сообщение со всеми действиями сразу. Так что это то же самое, что не использовать нить вообще в качестве основного потока, выполняющего всю работу. Попробуйте перейти на postDelay, и для каждого индекса комнаты дайте ему 1 миллисекунду или больше.