2012-03-22 18 views
0

私はStackoverflowを使ってコードを投稿していますが、修正するにはあまりにも多くの間違いがあると思います。異なる行の型を持つCustomAdapter

私の最大の問題は誤解であるため、私はそれを開発する必要があるかどうかを尋ねます。

問題:私はカスタムのcursorAdapterによってフィードされたlistViewを行いたいと思います。

なぜカスタムcursorAdapterですか?

今のところ、私はlistViewの最初の行にeditTextを、次にデータベースから項目を、そしてlistViewの最後の行に他のeditTextを配置したいと考えています。私はヘッダーとフッターでそれを解決することができますが、後で私は同じリストビュー内の多くの他の行のテンプレートを望んで、多分多くのカーソル、それは理由です。もちろんLink about having many row types in one listView

私はbindViewとnewViewをオーバーライド:

私はこのチュートリアル次のアダプターには多くの種類を使用することをtryied。

しかし

それは失敗しています。私はlistViewなどにeditTextを直接追加する方法がわからないような多くのバグを持っています...私の最大の問題は理解です。私はそれを行う方法の説明が必要です。 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()==>それは

2)createNoの作品teTop関数も機能し、データベースに行を挿入します。

あなたの答えを探してくれてありがとう。

EDIT:大丈夫ですので、あまり好きではありません。 残念ながら私はまだ表示のバグがあります。フィールドを変更すると、なぜこのフィールドがリストのどこかにドロップされます。私はそれが大きな間違い(bindViewまたはnewViewメソッドで)簡単に修正可能だと思うが、私は疲れていて、どこから来たのか分からない。したがって、1つの石で2羽の鳥を殺すために、私はcustomAdapterの修正コードを掲載します。

答えて

1

サブタイトルCursorAdapterは、そのようにすることがかなり一般的です。単純なニーズがある場合に備えて、ResourceCursorAdapterなどを使用します。

ちょっとした背景:ListViewは再生回数を表示します。したがって、newViewは、(画面上の項目の数)+ 1(スクロールを開始すると部分的に表示される項目)のみ呼び出されます。次に、これらの項目はスクリーンからスクロールするときに再利用されます。そのため、newViewはすべてのTYPE_ITEMに対してnewViewが呼び出されないため、newViewにテキストラベルを設定するのは無駄です。これはbindView(これを行うべき場所)でオーバーライドされるためです。

私は主な問題は、リストビューの内容をnewViewメソッドでaddNoteBottomPositionを変更して変更していることです。これは実際には最悪のことです。リストアダプターは、安定した結果を得るためのものです。つまり、getItemViewType(8)がタイプTYPE_ADD_NOTE_BOTTOMであったとすると、次回には回り込むことができず、「今、そのTYPE_ITEM」と言うことはできません。あなたは何をしているのですか?あなたのコードはnewViewが特定の順序で呼び出されているという事実に依存しています。もう1つの問題は、CursorAdapterが依存しているポジションを使いこなしていることです。

これをどのように解決しますか?

多くのアプローチがありますが、おそらくもっと複雑なものを使用したと思います。最も簡単な方法は、

項目のみのためResourceCursorAdapterを使用し、ヘッダーとフッターを追加するためのListView.addHeaderView()ListView.addFooterView()を使用することです。 ListViewのソースコードをチェックすると、addHeaderViewは実際にはHeaderViewListAdapter(http://developer.android.com/reference/android/widget/HeaderViewListAdapter.html)を使用します。これは基本的にはラッパーリストアダプターですあなたが提供するネストされたListAdapterの周りを包み込む。場合

あなたはなど、さまざまなビュータイプを心配する必要はありません。このアプローチでは

私はあなたを納得させることができなかったとあなたはまだ、あなたがその実施を検討する必要がCursorAdapterをサブクラス化します。正しい位置に依存していることに気づくでしょう。実際に位置を混乱させ、カーソル位置から分離させたい場合は、getItem(),などのすべての種類のメソッドをオーバーライドする必要があります。

短いストーリー、あなたはそこに行きたくありません。

+0

良い説明、私が探していたもの。あなたのソリューションと私のプロジェクトとの間にまだ不一致があると思います。他のデータベースのテーブルから行 - のEditText - - データベーステーブル から行 - のEditText - ブランク - (TextViewの中)タイトル :事は、最終的なテンプレートのようなものでなければなりません。 同じListViewのすべてです。 ヘッダーフッターのソリューションは私のニーズに対応していないと思います。私は本当にカスタムCursorAdapterを実行しなければならないのではないかと心配しています。しかし、とにかく、あなたの投稿は本当に役に立ちました。 –

+1

その場合、複数のネストされたリストアダプターを連結し、次に2つの表の2つのresourcecursorアダプターを持つリストアダプターを作成します。そのwrappedlistadapterは、HeaderViewListAdapterのように機能し、複数のネストされたアダプタを追加し、その間にヘッダを配置するだけです。代わりに、おそらくあなた自身のベースアダプタサブクラスを実装することでこれまで説明したように、その実装は、getItem、getItemIdなどの意味のある値を返さなければならないという難点があり、アンドロイドのCursorAdapterと非常に似ています。 – RaB

+0

私は、これを試してみましょう。 - サブクラスBaseAdapter - このbaseAdapterのサブクラスは実際にはlistAdapterのリストです(cursorAdapterなどが必要な場合など)。ressourceCursorAdapterを使用してフィードできます。 - 私は実際に各サブリストにヘッダーとフッターを追加できます。 それは? –

関連する問題