2012-04-12 14 views
0

私は、TextView、2 CheckBox、およびSpinnerを持つ行を持つListViewが必要なアプリケーションを開発しています。SpinnerをAndroidのListViewの中で使うには?

ただし、各行に表示されるたびに呼び出されるため、SpinnerのonItemSelected()に関する問題が発生しています。このメソッドでは、選択したオプションでデータベースレコードを更新していますが、Androidが自動的に呼び出すときに、Androidが位置0で呼び出すのでアイテムがリセットされるたびに、データベースに値が更新されます。

私はonItemSelected()といくつかのハックでこの問題に関する多くのリンクを読みましたが、それらのすべてがListViewなしで使用されます。ここにポイントはありますか?

実際に表示される位置をリストで追跡しようとしましたが、実際には表示されませんでした。私はそれがトラブルシューティングの方法を引き起こすAndroidのリサイクルのためだと思うスピナーがすでに表示されます!

したがって、ポイントはです。スピナーを表示する際のAndroidコールのユーザー選択のため、onItemSelected()への実際の呼び出しをどのように区別できますか?

SimpleCursorAdapterを拡張している私のアダプタのコードです。

ありがとうございます。

public ParticipationAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 
    super(context, layout, c, from, to); 
    mActivity = (Activity)context; 
    ParticipationComment.ParticipationCommentManager commentManager = new ParticipationComment.ParticipationCommentManager(mActivity); 
    mParticipationCommentsCursor = commentManager.get(); 
    mActivity.startManagingCursor(mParticipationCommentsCursor); 
    commentManager.detach(); 
    mPositionsOfCursorIds = getPositionsOfCursorIds(mParticipationCommentsCursor); 
    mSpinnerPositionsDisplayed = new ArrayList<Integer>(); 
} 

@Override 
public View getView(final int participationPosition, View convertView, ViewGroup parent) { 
    final Cursor participationsCursor = getCursor(); 
    mActivity.startManagingCursor(participationsCursor); 
    participationsCursor.moveToPosition(participationPosition); 
    View participationRow; 
    if (convertView == null) { 
     participationRow = LayoutInflater.from(mActivity).inflate(R.layout.participation_row_student, null); 
    } else { 
     mSpinnerPositionsDisplayed.remove((Integer)convertView.getTag()); 
     participationRow = convertView; 
    } 
    participationRow.setTag(participationPosition); 
    Spinner commentSpinner = (Spinner)participationRow.findViewById(R.id.participation_comment_id_spinner); 
    SimpleCursorAdapter commentSpinnerAdapter = new SimpleCursorAdapter(
      mActivity, 
      android.R.layout.simple_spinner_item, 
      mParticipationCommentsCursor, 
      new String[] {DatabaseManager.NAME}, 
      new int[] {android.R.id.text1} 
    ); 
    commentSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    commentSpinner.setAdapter(commentSpinnerAdapter); 
    long participationCommentId = participationsCursor.getLong(participationsCursor.getColumnIndex(DatabaseManager.PARTICIPATION_COMMENT_ID)); 
    if (participationCommentId != 0) { 
     commentSpinner.setSelection(mPositionsOfCursorIds.get(participationCommentId)); 
    } 
    commentSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
     @Override 
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
      participationsCursor.moveToPosition(participationPosition); 
      if (!mSpinnerPositionsDisplayed.contains(participationPosition)) { 
       // Android calls this method the first time a Spinner is displayed, 
       // to differentiate from a real user click we check if the current Spinner's position 
       // in the ListView is being shown 
       mSpinnerPositionsDisplayed.add(participationPosition); 
      } else { 
       ParticipationComment participationComment = new ParticipationComment((Cursor)parent.getItemAtPosition(position)); 
       Participation.ParticipationManager participationManager = new Participation.ParticipationManager(mActivity); 
       Participation participation = new Participation(participationsCursor); 
       participation.setConnectionProfileParticipationCommentId(participationComment.getConnectionProfileId()); 
       participation.setParticipationCommentId(participationComment.getIdOpenErp()); 
       participation.setChanged(true); 
       participationManager.update(participation); 
       participationManager.detach(); 
      } 
     } 

     @Override 
     public void onNothingSelected(AdapterView<?> parent) { 
      // Not used 
     } 
    }); 
    TextView studentName = (TextView)participationRow.findViewById(R.id.participation_student_name); 
    studentName.setText(participationsCursor.getString(participationsCursor.getColumnIndex(DatabaseManager.NAME))); 
    CheckBox expectedPresent = (CheckBox)participationRow.findViewById(R.id.participation_expected_present_value); 
    expectedPresent.setChecked(participationsCursor.getInt(participationsCursor.getColumnIndex(DatabaseManager.EXPECTED_PRESENT)) == 1); 
    CheckBox present = (CheckBox)participationRow.findViewById(R.id.participation_present_value); 
    present.setChecked(participationsCursor.getInt(participationsCursor.getColumnIndex(DatabaseManager.PRESENT)) == 1); 
    return participationRow; 
} 

答えて

3

良い方法はそのAlertDialogの選択に基づいて変更.. AlertDialogバリアントを使用するようthis ..ですし、最初にそのテキストととして最初の選択をしているボタンを作成

+0

ありがとうございました!明日私はそれを試し、あなたに何かを言う!しかし、元のデータがdbテーブルにあるので、代わりに 'public AlertDialog.Builder setCursor(Cursor cursor、DialogInterface.OnClickListener listener、String labelColumn)'を使用します。私は、このアプローチでは、私は実際に必要とし、Spinnerを使用することができない選択肢をユーザーが選択できないようにすることができると考えています。 – Caumons

+0

@カウモンズ..幸運.. – ngesh

+0

ありがとう、そんなに!私は最終的にあなたが提案したボタンとalertDialogsとリストビュー内の選択を実装しました。これは素晴らしい作品です!ダイアログで 'setSingleChoiceItems()'メソッドを使いました。デフォルト選択を定義することができます。私はあなたの答えをアップアップして受け入れてくれました。 :) – Caumons

2

ItemSelectedの最初の呼び出しを破棄するには小さなフラグを使用しますか?

+0

とどのように私ができましたこれを行う?私はアイデアがありません:(私はすでにリストの位置を表示しています...現在の位置が存在せず、 'onItemSelected()'が呼び出されていればAndroidによって作られます。それはユーザーのクリックですが...それはすでに表示され、これは私を傷つけているときにAndroidをリコールするようだ!私はこれは、Android(convertView)で行わリサイクルパターンのためだと思う – Caumons

+0

私は毎回あなたのカウンターをリセットする必要があると思いますビューが作成またはリサイクルされる(アダプタのgetViewメソッド)各ビューのカウンタを保持し、getViewメソッドによってビューが要求されるとリセットする – Snicolas

+0

このアプローチを使用すると、リサイクルをどのように実施しているのか、どこでカウンターをリセットするべきか正確にはわかっていないからです。@ sandyが提案した解決方法を試してみてください。 .. ありがとうとにかく! :) – Caumons