CustomAdapter с объяснениями разных типов строк - PullRequest
0 голосов
/ 22 марта 2012

Я попытался в Stackoverflow опубликовать свой код, но я думаю, что в этом слишком много ошибок, чтобы их можно было исправить.

Так как моей самой большой проблемой является недоразумение, я просто спрошу, как яЯ должен его разработать.

ПРОБЛЕМА : Я хочу сделать listView, управляемый пользовательским курсором-адаптером.

Почему пользовательский cursorAdapter?

Потому что на данный момент я хочу иметь editText в первой строке listView, затем элементы из базы данных, а затем другой editText всамая последняя строка listView.Я мог бы решить эту проблему с помощью верхних и нижних колонтитулов, но позже мне нужно много других шаблонов строк в том же listView, и, возможно, даже много курсоров, вот почему.

Я пытался использовать много типов в адаптереследуя этому руководству : Ссылка о наличии множества типов строк в одном listView

Конечно, я переопределил bindView и newView.

НО

Этотерпит неудачу.У меня много ошибок, например, я не знаю, как напрямую добавить editText в мой listView и т. Д. Самая большая проблема для меня - это понимание, мне просто нужно объяснить, как это сделать, я имею в виду, что именно я должен делатьв bindView, и что именно я должен делать в newView.

Хорошо, я передумал, вот код моего адаптера.Осторожно, это может быть ужасно.

    package com.android.activity;


import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.TextView;

public class NotesCursorAdapter extends CursorAdapter{

    private Context context;
    //  private Cursor cursor;
    private int addNoteTopPosition = 0;
    private int addNoteBottomPosition;
    private LayoutInflater inflater;

    private static final int TYPE_ITEM = 0;
    private static final int TYPE_ADD_NOTE_BOTTOM = 1;
    private static final int TYPE_ADD_NOTE_TOP = 2;
    private static final int TYPE_MAX_COUNT = TYPE_ADD_NOTE_TOP + 1;

    public NotesCursorAdapter (Context context, Cursor cursor, int flag){
        super(context, cursor);
        this.context = context;
        addNoteTopPosition = 0;
        addNoteBottomPosition = cursor.getCount()+1;

        inflater = LayoutInflater.from(this.context);

    }

    //  public 

    @Override
    public int getCount() {  
        return super.getCount() + 2;
    } 





    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        ViewHolder holder = null;
        int type = getItemViewType(position);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {

            case TYPE_ADD_NOTE_TOP:
                convertView = inflater.inflate(R.layout.add_note_top, null);
                holder.view = (EditText)convertView.findViewById(R.id.add_note_top_id);
                break;
            case TYPE_ITEM:
                convertView = inflater.inflate(R.layout.row_note, null);
                holder.view = (TextView)convertView.findViewById(R.id.note);
                getCursor().moveToPosition(position - 1);
                //              System.out.println("modified : " + getCursor().getInt(getCursor().getColumnIndex("_id")));
                ((TextView) holder.view).setText(getCursor().getInt(getCursor().getColumnIndex("_id")) + getCursor().getString(getCursor().getColumnIndex("content_note")));
                break;
            case TYPE_ADD_NOTE_BOTTOM:
                convertView = inflater.inflate(R.layout.add_note_bottom, null);
                holder.view = (EditText)convertView.findViewById(R.id.add_note_bottom_id);
                break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        return convertView;
    }

    @Override
    public int getItemViewType(int position) {
        int type;
        if (position == addNoteTopPosition){
            type = TYPE_ADD_NOTE_TOP;
        } else if (position == addNoteBottomPosition){
            type = TYPE_ADD_NOTE_BOTTOM;
        }else {
            type = TYPE_ITEM;
        }
        return type;
    }

    @Override
    public int getViewTypeCount() {
        return TYPE_MAX_COUNT;
    }

    @Override
    public long getItemId(int position) {  
        return position;  
    }

    public static class ViewHolder {
        public View view;
    }

}

Примечание: позже я исправлю некоторые оптимизации, такие как viewHolder и т. Д.

Примечание 2: На всякий случай, вот моя основная деятельностьcode

package com.android.activity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewDebug.FlagToString;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.CursorAdapter;

import com.android.database.Note;
import com.android.database.NoteDataSource;

public class EverydayNotesAndroid3Activity extends Activity {
    /** Called when the activity is first created. */

    private Cursor cursorNotes;
    private NotesCursorAdapter notesCursorAdapter;
    private InputMethodManager imm;
    private Activity activity;
    private ListView listView;
    private int positionItem;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        activity = this;

        NoteDataSource.getSingletonObject(activity);

        NoteDataSource.getSingletonObject(activity).open();

        cursorNotes = NoteDataSource.getSingletonObject(activity).getCursorUpdatedDatabase(); // return all notes in a cursor

        startManagingCursor(cursorNotes);

        listView = (ListView) findViewById(R.id.main_list);

        notesCursorAdapter = new NotesCursorAdapter(activity, cursorNotes, 3);

        listView.setAdapter(notesCursorAdapter);

        Button b = new Button(activity);

        b = (Button) findViewById(R.id.done);

        b.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                NoteDataSource.getSingletonObject(activity).createNoteTop("Hello stack overflow world");
                cursorNotes = NoteDataSource.getSingletonObject(activity).getCursorUpdatedDatabase();
                notesCursorAdapter.changeCursor(cursorNotes); 
                notesCursorAdapter.notifyDataSetChanged();
            }

        });



        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id){
                if (position == 0){
                    showAlertWindowAddTop(parent, v, position, id);

                }else if (position == parent.getChildCount()-1){

                    showAlertWindowAddBottom(parent, v, position, id);
                }else{

                    showAlertWindowModify(parent, v, position, id);

                }

            }
        });

    }

И не беспокойтесь о:

1) функциях showAlertWindowblabla () ==> это работает

2) функция createNoteTop тоже работает, она вставляетстрока в базе данных.

Спасибо, что читаете, ищите ваши ответы.

РЕДАКТИРОВАТЬ: Хорошо, так что после некоторой долгой работы не очень много, я становлюсь ближе к тому, что я хочу.К сожалению, у меня все еще есть ошибка отображения, когда я изменяю поле, я не знаю почему, он просто удаляет это поле где-то еще в списке.Я думаю, что это большая ошибка (в методе bindView или newView), которую легко исправить, но я устал и не понимаю, откуда она взялась.Поэтому, чтобы убить двух зайцев одним выстрелом, я выкладываю модифицированный код моего customAdapter.

1 Ответ

1 голос
/ 22 марта 2012

Это довольно часто встречается в подклассе CursorAdapter, так как это должно быть сделано таким образом. Вы должны использовать ResourceCursorAdapter и т. Д., Если у вас есть простые потребности.

Итак, немного фона: ListView перезаписывает представления. Поэтому newView вызывается только для (количество элементов на экране) + 1 (тот, который частично виден при запуске прокрутки). Затем эти предметы используются повторно, когда они прокручиваются за пределы экрана. Следовательно, устанавливать текстовые метки в newView довольно бесполезно, так как в любом случае он будет переопределен в bindView (это место, где вы должны это сделать), поскольку newView не будет вызываться для каждого TYPE_ITEM.

Так что, я думаю, главная проблема в том, что вы меняете содержимое представления списка, изменяя addNoteBottomPosition в вашем newView методе, что на самом деле является худшей вещью, которую вы можете сделать. Адаптер списка предназначен для получения стабильных результатов. Это означает, что если вы скажете, что getItemViewType(8) имел тип TYPE_ADD_NOTE_BOTTOM, вы не сможете развернуться в следующий раз и сказать «ура, теперь его TYPE_ITEM». Что ты и делаешь Ваш код основан на том факте, что newView вызывается в определенном порядке. Другая проблема заключается в том, что вы возитесь с позициями, на которые опирается CursorAdapter.

Так как вы решаете это?

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

Используйте ResourceCursorAdapter только для элементов и ListView.addHeaderView() и ListView.addFooterView() для добавления верхних и нижних колонтитулов. Если вы извлечете исходный код ListView, то заметите, что addHeaderView фактически будет использовать HeaderViewListAdapter (http://developer.android.com/reference/android/widget/HeaderViewListAdapter.html)), который по сути является адаптером списка упаковщиков, который оборачивает вложенный ListAdapter, который вы затем предоставите.

При таком подходе вам не нужно беспокоиться о разных типах представлений и т. Д.

Если я не смог вас убедить, а вы все еще хотите подкласс CursorAdapter, тогда вам нужно проверить его реализацию. Вы заметите, что он опирается на правильные позиции, и поэтому, если вы действительно хотите возиться с позициями и отделять их от позиций строки курсора, вам нужно будет переопределить все виды методов, такие как getItem(), getItemId().

Короче говоря, вы не хотите туда идти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...