我尝试使用Stackoverflow发布我的代码,但我认为有太多错误需要修复。
因为我最大的问题是误解,所以我只想问我开发它的方式。
问题:我想做一个listView,由自定义cursorAdapter提供。
为什么要自定义cursorAdapter?
因为现在,我希望在listView的第一行有一个editText,然后是数据库中的项目,然后是listView最后一行的另一个editText。我可以用页眉和页脚解决它,但后来我想在同一个listView中有很多其他行模板,甚至可能是很多游标,这就是原因。
我尝试按照本教程使用适配器中的多种类型:Link about having many row types in one listView
当然我覆盖了bindView和newView。
BUT
失败了。我有很多错误,比如我不知道怎么直接将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:以防万一,这是我的主要活动代码
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()==&gt;它的工作原理
2)createNoteTop函数也可以工作,它在数据库中插入一行。
感谢阅读,寻找答案。
编辑:好的,所以在一些looooooong工作不是很多之后,我越来越接近我想要的了。 不幸的是我还有一个显示错误,当我修改一个字段时,我不知道为什么,他只是把这个字段放在列表中的其他地方。我认为这是一个很大的错误(在bindView或newView方法上)很容易修复,但我很累,我找不到它来自哪里。因此,为了一举两得,我发布了我的customAdapter的修改代码。答案 0 :(得分:1)
它子类CursorAdapter
很常见,因为它意味着以这种方式完成。如果您有简单的需求,可以使用ResourceCursorAdapter
等。
所以只需要一些背景知识:ListView
回收视图。因此,仅调用newView(屏幕上的项目数)+ 1(在您开始滚动时部分可见的那个)。然后这些项目在滚动屏幕时重复使用。因此,在newView中设置文本标签几乎没用,因为无论如何它都会在bindView中被覆盖(这是你应该这样做的地方),因为不会为每个TYPE_ITEM调用newView。
所以我猜主要的问题是你是通过修改newView
方法中的addNoteBottomPosition来改变列表视图的内容,这是你能做的最糟糕的事情。列表适配器旨在产生稳定的结果。这意味着如果您说getItemViewType(8)
的类型为TYPE_ADD_NOTE_BOTTOM,则您无法在下次转身并说“yay,现在是TYPE_ITEM”。这是你在做什么。您的代码依赖于以特定顺序调用newView
的事实。另一个问题是你正在弄乱CursorAdapter
所依赖的职位。
那你怎么解决这个问题?
有很多方法,我认为你使用的可能更复杂。
是最简单的方法仅对项目使用ResourceCursorAdapter
,并使用ListView.addHeaderView()
和ListView.addFooterView()
添加页眉和页脚。
如果您查看ListView的源代码,那么您会注意到addHeaderView
实际上将使用HeaderViewListAdapter
(http://developer.android.com/reference/android/widget/HeaderViewListAdapter.html)这基本上是一个包装器列表适配器,它包装了您随后提供的嵌套ListAdapter
。
使用这种方法,您无需担心不同的视图类型等。
如果我无法说服你,你仍然想要继承CursorAdapter
,那么你需要检查它的实现。您会注意到它依赖于正确的位置,因此,如果您真的想要混淆位置并将它们与光标行位置分开,那么您需要覆盖各种方法,例如getItem()
,{{ 1}}。
长话短说,你不想去那里。