2012-03-22 58 views
0

我尝试了Stackoverflow来发布我的代码,但我认为有太多的错误需要修复。CustomAdapter与不同的行类型解释

所以,作为我最大的问题是一个误解,我只是要求我必须开发它的方式。

问题:我想做一个listView,由自定义cursorAdapter传递。

为什么要自定义cursorAdapter?

因为现在,我想在listView的第一行有一个editText,然后是来自数据库的项目,然后是listView最后一行的其他editText。我可以用页眉和页脚来解决这个问题,但后来我想在同一个listView中使用很多其他的行模板,甚至可能使用许多光标,这就是原因。

我tryied的适配器使用多种类型下面这个教程Link about having many row types in one listView

当然我overrided 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:万一,这里是我的主要活动代码

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

       } 

      } 
     }); 

    } 

和Don”吨担心:

1)函数showAlertWindowblabla()==>它的工作原理

2)createNo teTop函数也可以工作,它在数据库中插入一行。

感谢您的阅读,寻找您的答案。

编辑:好吧,所以在一些looooooong工作不是很多,我越来越接近我想要的。 不幸的是,我仍然有一个显示错误,当我修改一个字段时,我不知道为什么,他只是将这个字段放在列表中的其他位置。我认为这是一个很大的错误(在bindView或newView方法上)很容易修复,但我很累,而且我也找不到它的来源。因此,为了一石二鸟,我发布了自定义适配器的修改后的代码。

回答

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(),getItemId()

长话短说,你不想去那里。

+0

一个很好的解释,我在找什么。我认为你的解决方案和我的项目之间仍然存在不匹配。关键是最后的模板必须是这样的: - EditText上 - EditText上 - - 空白 - 从数据库表 行标题(在一个TextView) - 从其他数据库表行。 在同一个ListView中的所有内容。 所以我认为页眉页脚解决方案不符合我的需求。恐怕我真的必须做一个自定义的CursorAdapter。但无论如何谢谢,你的帖子真的很有帮助。 – 2012-03-22 08:44:57

+1

在这种情况下,您将创建一个列表适配器,它将连接多个嵌套列表适配器,然后为这两个表创建2个resourcecursoradapters。那个wrappedlistadapter的功能与HeaderViewListAdaptera类似,只是追加多个嵌套适配器,并将标头放在两者之间。另一种方法就像我之前描述的那样,可能实现了你自己的基类适配器子类,它的实现看起来与android的CursorAdapter非常相似,只不过需要为getItem,getItemId等返回有意义的值。 – RaB 2012-03-22 23:19:15

+0

好吧,要去试试这个,所以如果我总结: - 子baseAdapter - baseAdapter的子类实际上是listAdapter的列表(例如,如果我想的CursorAdapter或其他),我可以用ressourceCursorAdapter养活他们。 - 我实际上可以为每个子列表添加页眉和页脚。 是吗? – 2012-03-23 06:52:43