vfp sobre qué que métodos hay escribir cursoradapter clase android simplecursoradapter

sobre - Android: Problema con newView y bindView en SimpleCursorAdapter personalizado



cursoradapter vfp (2)

Creé un SimpleCursorAdapter personalizado de uno de los únicos ejemplos que encontré .

Cuando se llama a mi ListActivity, se llama a newView y bindView para cada una de las entradas de mi base de datos, y se vuelve a llamar para cada entrada. Tengo algunas preguntas:

-es el ejemplo correcto (si no, ¿dónde puedo encontrar uno)?

-si la llamada bindView siempre está precedida por la llamada newView, ¿por qué hacer lo mismo en ambas funciones?

¿Por qué se llama a la secuencia newView-bindView dos veces para cada elemento?

¿Por qué algunos ejemplos de CursorAdapter usan getView en lugar de newView y bindView?

Básicamente, ¿cómo se debe usar SimpleCursorAdapter y qué tiene de malo mi código?

Gracias

ListaActividad

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(); } }

Personalizado 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; } } }


El ejemplo es casi correcto. No es necesario realizar el enlace en newView() , ya que, como mencionó, se bindView() . Si ve la secuencia que se llama a newView / bindView dos veces por elemento, probablemente esté usando ListView con su altura establecida en wrap_content , lo que siempre es una mala idea. Finalmente, newView() y bindView() son específicos de CursorAdapter : implementa getView() y llama a newView() o bindView() por ti. Sin embargo, anular getView() es perfectamente válido. Así es como funcionan otros adaptadores.

Tenga en cuenta que getView() (y, por lo tanto, bindView / newView) solo se invocan para cada elemento que se mostrará en la pantalla.


La getView() función getView() le brinda la posibilidad de "reutilizar" elementos de la lista ya inflados (los elementos de la lista que están "desplazados" desde el puerto de vista actual cuando se desplaza de una lista a otra).

Al hacerlo, ahorrará una gran cantidad de recursos de memoria y tiempo de ejecución del procesador, ya que inflar es una operación que consume bastante tiempo. Para todos y cada uno de los convertView que reutiliza, también ahorra tiempo de ejecución de GC (ya que el recolector de basura no tiene que recopilar ese elemento de lista específico).

También puede crear una clase de "colección de vistas" (la clase ViewHolder en el siguiente ejemplo) que contendrá las referencias de cada vista en su elemento de lista inflada. De esta manera, no tiene que encontrarlos cada vez que actualice un elemento de la lista con nuevos valores (normalmente cuando se desplaza por la lista). findViewById() también es una operación que consume bastante tiempo.

También creo que se pueden almacenar más variables, como el inflador de diseño y los índices de columna. Todo para ahorrar tiempo :-)

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; }