Android: проблема с newView и bindView в пользовательском SimpleCursorAdapter

Я создал пользовательский SimpleCursorAdapter из одного из единственных примеров, которые я нашел .

Когда вызывается мой ListActivity, newView и bindView вызывается для каждой моей записи в БД и вызывается снова для каждой записи. У меня есть несколько вопросов:

– это пример справа (если нет, где я могу его найти)?

-if вызову bindView всегда предшествует вызов newView, зачем делать то же самое в обеих функциях?

-why является последовательностью newView-bindView, вызываемой дважды для каждого элемента?

-Какие примеры CursorAdapter используют getView вместо newView и bindView?

В принципе, как должен использоваться SimpleCursorAdapter, и что не так с моим кодом?

благодаря


ListActivity

public class ContactSelection extends ListActivity { private WhipemDBAdapter mDbHelper; private FriendAdapter friendAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDbHelper = new WhipemDBAdapter(this); mDbHelper.open(); setContentView(R.layout.contact_list); Cursor c = mDbHelper.fetchAllFriends(); startManagingCursor(c); String[] from = new String[] {}; int[] to = new int[] {}; this.friendAdapter = new FriendAdapter(this, R.layout.contact_row, c, from, to); setListAdapter(this.friendAdapter); getListView().setItemsCanFocus(false); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } @Override protected void onResume() { super.onResume(); mDbHelper.open(); } @Override protected void onPause() { super.onPause(); mDbHelper.close(); } } 

Пользовательский SimpleCursorAdapter

 public class FriendAdapter extends SimpleCursorAdapter implements OnClickListener { private Context mContext; private int mLayout; public FriendAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); this.mContext = context; this.mLayout = layout; } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { Cursor c = getCursor(); final LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(mLayout, parent, false); String name = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME)); String fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID)); TextView name_text = (TextView) v.findViewById(R.id.contact_name); if (name_text != null) { name_text.setText(name); } ImageView im = (ImageView) v.findViewById(R.id.contact_pic); Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture"); if (im != null) { im.setImageDrawable(drawable); } CheckBox bCheck = (CheckBox) v.findViewById(R.id.checkbox); if (im != null) { bCheck.setTag(fb_id); } if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) bCheck.setChecked(true); bCheck.setOnClickListener(this); return v; } @Override public void bindView(View v, Context context, Cursor c) { String name = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME)); String fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID)); TextView name_text = (TextView) v.findViewById(R.id.contact_name); if (name_text != null) { name_text.setText(name); } ImageView im = (ImageView) v.findViewById(R.id.contact_pic); Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture"); if (im != null) { im.setImageDrawable(drawable); } CheckBox bCheck = (CheckBox) v.findViewById(R.id.checkbox); if (im != null) { bCheck.setTag(fb_id); } ArrayList<String> dude = ((GlobalVars) mContext.getApplicationContext()).getSelectedFriendList(); if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) bCheck.setChecked(true); bCheck.setOnClickListener(this); } @Override public void onClick(View v) { CheckBox cBox = (CheckBox) v; String fb_id = (String) cBox.getTag(); if (cBox.isChecked()) { if (!((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) ((GlobalVars) mContext.getApplicationContext()).addSelectedFriend(fb_id); } else { if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) ((GlobalVars) mContext.getApplicationContext()).removeSelectedFriend(fb_id); } } private Drawable LoadImageFromWebOperations(String url) { try { InputStream is = (InputStream) new URL(url).getContent(); Drawable d = Drawable.createFromStream(is, "src name"); return d; }catch (Exception e) { System.out.println("Exc="+e); return null; } } } 

Переопределение функции getView() дает возможность «повторно использовать» уже раздутые элементы списка (элементы списка, которые «прокручиваются» из текущего порта просмотра, когда вы прокручиваете список назад и вперед).

Таким образом, вы сэкономите много ресурсов памяти и времени работы процессора, поскольку надувание – довольно трудоемкая операция. Для каждого convertView вы повторно используете, вы также сохраняете время выполнения GC (поскольку сборщику мусора не нужно собирать этот конкретный элемент списка).

Вы также можете создать класс «view collection» (класс ViewHolder в приведенном ниже примере), в котором будут храниться ссылки для каждого представления в вашем надутом элементе списка. Таким образом, вам не нужно искать их каждый раз, когда вы обновляете элемент списка с новыми значениями (обычно, когда вы прокручиваете список). findViewById() также занимает довольно много времени.

Кроме того, я думаю, вы можете кэшировать больше переменных, таких как раздув макета, и индексы столбцов. Все, чтобы сэкономить время 🙂

 private final Context mContext; private final int mLayout; private final Cursor mCursor; private final int mNameIndex; private final int mIdIndex; private final LayoutInflater mLayoutInflater; private final class ViewHolder { public TextView name; public ImageView image; public CheckBox checkBox; } public FriendAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); this.mContext = context; this.mLayout = layout; this.mCursor = c; this.mNameIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_NAME); this.mIdIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_FB_ID); this.mLayoutInflater = LayoutInflater.from(mContext); } public View getView(int position, View convertView, ViewGroup parent) { if (mCursor.moveToPosition(position)) { ViewHolder viewHolder; if (convertView == null) { convertView = mLayoutInflater.inflate(mLayout, null); viewHolder = new ViewHolder(); viewHolder.name = (TextView) convertView.findViewById(R.id.contact_name); viewHolder.image = (ImageView) convertView.findViewById(R.id.contact_pic); viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } String name = mCursor.getString(mNameIndex); String fb_id = mCursor.getString(mIdIndex); Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture"); boolean isChecked = ((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id); viewHolder.name.setText(name); viewHolder.image.setImageDrawable(drawable); viewHolder.checkBox.setTag(fb_id); viewHolder.checkBox.setChecked(isChecked); } return convertView; } 

Пример почти прав. Вам не нужно выполнять привязку в newView() , так как вы упомянули, будет вызван bindView() . Если вы видите последовательность newView / bindView, вызываемую дважды для каждого элемента, вы, вероятно, используете ListView с его высотой, установленной в wrap_content , что всегда является плохой идеей. Наконец, newView() и bindView() специфичны для CursorAdapter : он реализует getView() и вызывает для вас либо newView() либо bindView() . Тем не менее, getView() отлично действует. Так работают другие адаптеры.

Обратите внимание, что getView() (и поэтому bindView / newView) вызывается только для каждого элемента, который будет отображаться на экране.

Intereting Posts
Как создать контекстное меню в элементе ListView в Android? Держите TextInputLayout всегда сфокусированным или сохраняйте ярлык всегда расширенным Как узнать, как получить выбранный элемент в расширяемом списке ANDROID Как решить инструменты Facebook: replace = "android: theme"? Диспетчер API Google Places отображает только определенные типы мест Обнаружение, когда система ui видна с липким иммерсивным режимом Хотите захватить кнопку Bluetooth-гарнитуры, нажмите Вручную добавление aar с файлом pom / iml зависимости Игра в android Как разработать анализатор спектра из аудио в реальном времени? Андроид listview внутри cardview onTouch прослушиватель конфликт / чувствительность Weird: не может изменить значение Integer в jni Невозможно запустить службу Google Play на эмуляторе (необходимо обновить сервис Google Play) Как вызвать щелчок или отправить событие при совместном использовании данных в других приложениях на Android? Android 4.1.2 браузер по умолчанию – проблема рендеринга с отключенными полями ввода