Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
#1

Как подзаморозить интерфейс?

29.01.2015, 11:27. Просмотров 402. Ответов 8
Метки нет (Все метки)

Здравствуйте!
Пытаюсь загрузить список ListView из базы. В списке примерно 20 строк. Если делаю это в UI-потоке, то всё грузится меньше секунды, плавно отображается, всё хорошо.
Если делаю в фоновом потоке, открывается примерно с такой же скоростью, но при этом контролы "моргают", список как-то дёргается, сначала исчезает, потом вновь появляется.
Как можно на период работы AsyncTask "заморозить" интерфейс, чтобы он не дёргался?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.01.2015, 11:27
Ответы с готовыми решениями:

Как удаленно влиять на интерфейс пользователя?
Как в качестве разработчика спроектировать интерфейс приложения так, чтобы...

[Swipe, Fragment] - интерфейс как у маркета
Приветствую, которую неделю туплю и не могу сделать интерфейс как у маркета....

Дизайн: как задать программно интерфейс приложения?
Здравствуйте. Расскажите мне пожалуйста как можно больше про дизайн...

Iptables, правила, перенаправляющие на интерфейс eth1 все пакеты, приходящие на интерфейс eth0
Добрый день, подскажите, пожалуйста, как Iptables написать правила,...

Можно ли создать интерфейс, в котором один из методов будет возвращать класс, который реализует интерфейс
Можно ли создать интерфейс, в котором один из методов будет возвращать класс,...

8
Gabberr
103 / 103 / 19
Регистрация: 13.10.2009
Сообщений: 404
29.01.2015, 11:46 #2
А что в асинтаске происходит?
По идее, если в бекграунде создаётся массив записей из базы, далее массив передаётся в онпост, а там сетится адаптеру, моргать ничего не должно.
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
29.01.2015, 14:27  [ТС] #3
Gabberr, примерно такой код. Для того чтобы при обновлении списка старые данные не затирались новыми, пока он ещё не загрузился (с вылетом Exception), создаю второй массив, а затем копирую один из другого.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    private ArrayList<Rubric> arrList;
 
    task = new LoadList().execute();
 
    private class LoadList extends AsyncTask<Void, Void, Void> {
        private DatabaseHelper dbHelper;
 
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
 
             dbHelper = new DatabaseHelper(context);
        }
 
        @Override
        protected Void doInBackground(Void... params) {
            ArrayList<Rubric> arrList2;
 
            try {
                Cursor cursor = dbHelper.getCursor("запрос");
                if (cursor != null) {
                    if (cursor.moveToFirst()) {
                        arrList2 = new ArrayList<Rubric>();
                        do {
                            arrList2.add(new Rubric(cursor));
                        } while (cursor.moveToNext());
                    } else
                        arrList2 = null;
                    cursor.close();
                } else
                    arrList2 = null;
            } finally {
                dbHelper.close();
            }
 
            if (!isCancelled()) {
                if (arrList != null)
                    arrList.clear();
                arrList = arrList2;
            }
 
            return null;
        }
 
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
 
            if (!isCancelled()) {
                ArrayAdapter<Rubric> adapter = new ArrayAdapter<Rubric>(
                        context, R.layout.listitem, R.id.text1, arrList);
                lvMain.setAdapter(adapter);
            }
        }
    }
0
Gabberr
103 / 103 / 19
Регистрация: 13.10.2009
Сообщений: 404
29.01.2015, 14:40 #4
Ну так моргание из-за того что создаётся новый адаптер и сетится списку.
Создай глобальный адаптер и в онпост просто вызывай у него clear() и addAll()
1
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
29.01.2015, 17:57  [ТС] #5
Gabberr, что-то я никак не могу сделать. Всяко попробовал, но всегда при обновлении получаю пустой список.
Вот, например, из http://androiddocs.ru/listview-array...atasetchanged/ взял способ и доработал.
В onPostExecute:
Java
1
2
3
4
5
6
7
8
9
10
                    if (adapter == null) {
                        adapter = new ArrayAdapter<Rubric>(
                                context, R.layout.listitem, R.id.text1, arrList);
                        adapter.setNotifyOnChange(true); // добавил этот метод.
                        lvMain.setAdapter(adapter);
                    } else {
                        adapter.clear();
                        adapter.addAll(arrList);
                        adapter.notifyDataSetChanged();
                    }
При заполнении arrList тоже пробовал всякими способами, всё равно пустой список.
Проверил длины arrList и adapter, получилось 25 элементов что до обновления, что после.
0
Gabberr
103 / 103 / 19
Регистрация: 13.10.2009
Сообщений: 404
29.01.2015, 18:38 #6
Думаю дело в том, что в онпост у тебя arrList равен нулу.
Не надо в бекграунде делать так
Java
1
2
   arrList.clear();
  arrList = arrList2;
Тут просто перекидывание ссылок получается, возможно, что после отработки этого метода локальный экземпляр arrList2 обнуляется
Передай arrList2 в онпост
Java
1
2
3
4
5
6
7
8
9
  @Override
        protected void onPostExecute(ArrayList<Rubric> array) {
            super.onPostExecute(result);
            if(adapter!=null && array!=null && array.size() > 0){
                adapter.clear();
                adapter.addAll(array);
                adapter.notifyDataSetChanged();
            }
        }
Добавлено через 5 минут
или вот так тогда, но первый вариант правильнее
Java
1
2
   arrList.clear();
  arrList.addAll(arrList2);
1
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
30.01.2015, 10:18  [ТС] #7
Gabberr, в общем, спасибо за советы.
Я и вчера, и сегодня пробовал работать то с arrList, то с arrList2, копировал их по-всякому. Тоже думал на ссылки и очистку массивов. Попробовал переделать AsyncTask. Измерял количество элементов в массивах и адаптере до и после. Оказалось, после выполнения adapter.notifyDataSetChanged() длина адаптера равнялась 0. Но это бы и ладно, можно копаться дальше, но я вот чего заметил.
У меня-то задача немного другая была. Я заходил в некий фрагмент, грузил список. Если он грузился в UI-потоке, всё было гладко, если в фоновом - моргало. Дальше переходил в другой фрагмент, потом возвращался в первый. И снова моргало. Т.е. установка setAdapter происходит каждый раз, и мне не требуется обновлять список. Проблема именно в этом - как перед установкой setAdapter заморозить интерфейс?

Добавлено через 5 минут
Иногда бывает такая ситуация, когда список не успевает быстро загрузиться, например, если пользователь быстро переходит по фрагментам туда-сюда. Тогда, в принципе, может возникнуть исключительная ситуация с сообщением, что другие данные грузятся в тот же адаптер. Поэтому я пытался добавить массив arrList2, но не уверен, что это правильно.
0
Gabberr
103 / 103 / 19
Регистрация: 13.10.2009
Сообщений: 404
30.01.2015, 10:19 #8
Проект сильно секретный?)
я б посмотрел, поковырял
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
30.01.2015, 12:01  [ТС] #9
Gabberr, да, к сожалению, пишем для организации. Но за помощь спасибо. Будут идеи - напишу.

Добавлено через 1 час 34 минуты
Немного неправильно сформулировал и заодно повторно для себя уяснил.
Если загружать данные в фоновом потоке, то мелькание будет, потому что сначала покажется чистый фрагмент, потом секунду будут грузиться данные, затем они добавятся в список.
Если данные загружать в основном потоке, то мелькания не будет, потому что фрагмент не отображается, пока не загрузятся все данные. Т.е. будет рисоваться старый фрагмент, а спустя секунду откроется новый с уже загруженными данными. Но при этом, конечно же, нельзя отобразить прогресс (впрочем, он нужен для операций дольше секунды).
0
30.01.2015, 12:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.01.2015, 12:01

Как сделать интерфейс приложения, написанный в VB6, как в WinXP?
Как сделать интерфейс приложения, написанный в VB6, как в WinXP?

Подскажите, как в туннельном интерфейсе сконфигурировать начало туннеля, как петлевой интерфейс?
Есть неполный пример конфигурации одного из маршрутизаторов. Туннель служить...

База данных "учебный план специальности". GUI. Графический интерфейс. Пользовательский интерфейс
Всем привет. Свалилась на меня, значит, курсовая по прологу. Все бы ничего, да...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru