2012-03-22 76 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