2012-04-12 56 views
0

我正在開發一個應用程序,其中我需要一個ListView,其行具有TextView,2 CheckBox和Spinner。如何讓List內的Spinner在Android中工作?

但是,我遇到了Spinner的onItemSelected()問題,因爲每次顯示每行時都會調用它。在這種方法中,我使用選定的選項更新數據庫記錄,但是由於Android會自動調用它,所以每當項目被重置時,Android都會調用它的位置爲0,並且這是數據庫中更新的值。

我已閱讀了很多有關onItemSelected()和一些黑客問題的鏈接,但它們都是在沒有ListView的情況下使用的。這裏的任何觀點?

我試圖在列表中追蹤哪些位置實際顯示以使其工作,但事實並非如此。我認爲這是因爲在Android中的回收,導致調試方法被調用Spinners已經顯示!

因此,問題是:由於用戶在顯示微調器時從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變..像this ..和創造最初具有第一選擇作爲其文本和按鈕的基礎上,選擇AlertDialog改變..

+0

非常感謝您的回答!明天我會嘗試並向你說點什麼!但是我會使用'public AlertDialog.Builder setCursor(Cursor cursor,DialogInterface.OnClickListener listener,String labelColumn)'代替,因爲我在db表中有原始數據。我認爲,通過這種方法,我將能夠讓用戶不選擇任何選項,這是我實際需要的,並且不可能使用微調器。 – Caumons 2012-04-12 16:58:19

+0

@卡路里..祝你好運.. – ngesh 2012-04-13 05:28:15

+0

非常感謝,非常感謝!按照您的建議,我最終在ListView中使用按鈕和alertDialog實現了選擇。這很好用!我在對話框中使用了'setSingleChoiceItems()'方法,因爲它允許您定義默認選擇。我已upvoted並接受你的答案給你+25代表! :) – Caumons 2012-04-16 11:31:38

2

如何使用小標記放棄第一次調用ItemSelected?

+0

在哪裏,我怎麼會做這個?我沒有想法...... :(我已經跟蹤了一個顯示位置的List ...所以,如果當前位置不存在,並且調用了'onItemSelected()',那麼它由Android創建,否則它是一個用戶點擊,但...似乎Android已經回憶它已經顯示,這是傷害我!我認爲這是因爲Android(convertView) – Caumons 2012-04-12 12:49:05

+0

完成的回收模式我認爲你應該每次重置您的計數器一個視圖被創建或回收(方法getView你的適配器)爲每個視圖保留一個計數器,重新設置視圖被getView方法要求放棄每個視圖的第一個事件 – Snicolas 2012-04-12 12:51:17

+0

我認爲這種方法會讓我的因爲我不知道究竟是如何實施循環利用和我應該重置櫃檯的地方,我會嘗試@sandy提出的另一個解決方案,這似乎更容易,我一直認爲谷歌男孩應該改善這種方法的不良行爲。 .. 謝謝你ou無論如何! :) – Caumons 2012-04-12 17:03:48

相關問題