Пользовательский дизайн CursorAdapter

Вот код, который я использую для своего настраиваемого адаптера курсора Android, который я использую для привязки данных к моему списку.

public class MessageAdapter extends CursorAdapter {
   private Cursor mCursor;
   private Context mContext;
   private final LayoutInflater mInflater;


    public MessageAdapter(Context context, Cursor c) {
        super(context, c);
        mInflater=LayoutInflater.from(context);
    mContext=context;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        TextView mobileNo=(TextView)view.findViewById(R.id.mobileNolistitem);
        mobileNo.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_MOBILENO)));

        TextView frequency=(TextView)view.findViewById(R.id.frequencylistitem);
        frequency.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_FREQUENCY)));

        TextView rowid=(TextView)view.findViewById(R.id.rowidlistitem);
        rowid.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_ID)));

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        final View view=mInflater.inflate(R.layout.message_list_item,parent,false); 
        return view;
    }

}

Я знаю, что есть еще один эффективный способ сделать это, который повторяет экземпляр элемента списка. Может кто-нибудь сказать мне, как?

31 голос | спросил rogerstone 1 MarpmTue, 01 Mar 2011 19:10:38 +03002011-03-01T19:10:38+03:0007 2011, 19:10:38

2 ответа


23

Это именно то, как вы должны использовать CursorAdapter. Я уверен, что вы имеете в виду «переработку» представлений, о которых говорилось при переопределении метода getView() для BaseAdapter.

В случае CursorAdapter все это позаботится о вас, чтобы просто реализовать newView() и bindView() полностью использует преимущества перепродажи View, о которых вы просите.

Вот код для CursorAdapter.getView():

public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}

Итак, вы видите, что метод пытается переработать представление, которое было передано, проверив convertView == null. В случае успеха он использует этот вид и просто вызывает bindView(), чтобы настроить его соответствующим образом. Если convertView имеет значение null, он вызывает newView(), чтобы создать представление, а затем bindView(), чтобы настроить его. Это один из редких случаев на SE, который я могу сказать: «Вы делаете это правильно!»

  • Но для nitpick нет оснований поддерживать ссылку на ваш контекст в mContext - вы нигде не используете его, а ссылки на контексты могут привести к утечкам памяти и, в конечном итоге, к концу мира.
ответил LeffelMania 3 Mayam11 2011, 01:45:16
7

Было бы еще проще использовать SimpleCursorAdapter, но тот же самый принцип применяется для CursorAdapter. Вы можете кэшировать вызовы на findViewById() в представлении и даже getColumnIndex на курсор, сохраняя данные в теге views. Использование этого параметра остановлено медленным рендерингом ListView.

Шаблон ViewHolder заимствован из демонстрационного примера эффективного API-адаптера здесь .

 public static class CustomSimpleCursorAdapter extends SimpleCursorAdapter {

    /* constructor(); */

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        super.bindView(view, context, cursor);

        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.textView1 = (TextView) view.findViewById(R.id.text1);
            holder.textView2 = (TextView) view.findViewById(R.id.text2);
            holder.column1 = cursor.getColumnIndexOrThrow("column1");
            holder.column2 = cursor.getColumnIndexOrThrow("column2");
            view.setTag(holder);
        }

        holder.textView1.setText(cursor.getString(holder.column1));
        holder.textView2.setText(cursor.getString(holder.column2));
    }

    static class ViewHolder {
        TextView textView1;
        TextView textView2;
        int column1; 
        int column2;
    }
}
ответил Tom Curran 18 AM00000030000003631 2011, 03:00:36

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132