2013-03-08 3 views
8

Я страдаю этой проблемой в течение нескольких месяцев и месяцев (но теперь я настройку производительности). Тем не менее, мне теперь отчаянно нужно знать, почему мой адаптер чувствует, что нужно запустить bindView до 4 раз на записи.Пользовательский адаптер курсора, вызывающий bindView несколько раз

У меня есть пользовательский адаптер курсора, который заполняет gridview.

Некоторые отладки, чтобы показать, что происходит:

03-08 14:46:47.980: I/AdapterCursorGrid(20724): newView() 
03-08 14:46:48.470: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:48.600: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:48.690: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:49.490: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:50.320: I/AdapterCursorGrid(20724): newView() 
03-08 14:46:51.170: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:51.190: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:51.190: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.190: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:51.200: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:51.870: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:51.896: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.896: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Picture creation... 

В «Аватар пусто ...» и «Создание фото ...» просто отлаживать, что говорит мне, что обработка и обновление 2 конкретных ImageView сек ,

Почему o почему bindView работает так много раз? Каковы причины этого и что я могу сделать, чтобы решить эту проблему?

Логически говоря, я ожидаю, что bindView будет работать один раз (и один раз при каждом обновлении адаптера), я ошибаюсь, думая об этом?

+0

Независимо от «создания изображения» должна * не * быть на главном потоке приложения. 'bindView()' должен возвращаться менее чем за 1 мс на 'GridView', независимо от того, считаете ли вы, что его называют слишком много раз по другим причинам. ** Расходы ~ 600 мс в «Создание картинки» очень плохие **. Даже если 'bindView()' вызывается только один раз на ячейку, он будет называться MxN раз (M строк, N столбцов), когда «GridView» изначально заполняется, а это означает, что * ваш пользовательский интерфейс заморожен в течение нескольких секунд * с самого начала , – CommonsWare

+0

@CommonsWare Да, я достиг этого с задачей aync. – HGPB

ответ

13

Операционная система может звонить по телефону bindView несколько раз, чтобы она могла правильно измерить и выложить список. Это не ошибка, как это должно быть. Это, наряду с гладкостью прокрутки, является причиной того, что реализация bindView должна быть максимально эффективной. Есть несколько полезных советов и трюков, которые вы можете использовать подробно на Android Developers Page.

+1

Должен ли я считать, что это относится к 'gridView'? – HGPB

+0

Да. Android может вызывать это столько раз, сколько требуется для правильного измерения и компоновки контейнера. – CaseyB

+0

В настоящее время я реализую шаблон ViewHolder. Я обновляю обработку изображений в async-задаче, а затем снова просмотрю 'bindView'. Тревожной частью является идея о том, что моя асинхронная задача будет выведена 4 раза в текущем состоянии. Любые другие предложения относительно того, почему это называется 4 раза? «GridView» установлен на fill_parent для высоты и ширины. Царапины. – HGPB

0

Одна вещь, которую я обнаружил с ImageView, заключается в том, что изменение изображения приведет к тому, что ImageView запросит макет, если новое и старое изображение не будут иметь одинаковый размер.

Внутренне ImageView использует getIntrinsicWidth() и getIntrinsicHeight(), чтобы решить, следует ли запрашивать макет.

Попробуйте что-то вроде этого (хотя было бы больше смысла, чтобы отправить текущую ширину/высоту вашего асинхронной нагрузки и изменение размера растрового изображения до возвращения из фона):

public void replaceBitmap(ImageView iv, Bitmap bitmap) { 
    Drawable current = iv.getDrawable(); 
    if (bitmap.getWidth() != current.getIntrinsicHeight() 
      || bitmap.getHeight() != current.getIntrinsicHeight()) { 
     bitmap = Bitmap.createScaledBitmap(bitmap, 
      current.getIntrinsicWidth(), current.getIntrinsicHeight(), true); 
    } 
    iv.setImageBitmap(bitmap); 
} 
10

Я также обнаружил, что BindView был называемый гораздо больше раз, чем ожидалось. Моя высота ListView была установлена ​​в wrap_content. После изменения его в match_parent количество вызовов резко сократилось.

Кредит для этого решения идет к ответу на этот вопрос Custom CursorAdapater's bindView called 77 times...have I done something wrong?

+0

Почему этот ответ еще не подтвержден? Это потрясающее решение. – faizal

+0

Ну, это не технически решение вопроса. Я просто хотел подчеркнуть, что если вы видите, что bindView называется чрезмерным количеством раз, это может быть связано с тем, что высота ошибочно устанавливается в wrap_content. – aaronmarino

+0

Спасибо, ты спас мой день! Этот ответ должен быть принятым ответом :) –

Смежные вопросы