2012-05-30 37 views
2

我在ListView中遇到Spinners問題。我有一個ListViewCheckBox,一個標籤,和兩個Spinners。從SQLite填充Spinner並且工作正常。我沒有使用ViewHolder方法,因爲到目前爲止,當單擊ListView行時,CheckBoxes被選中或取消選中,並且更改立即保存到數據庫。當檢查行時,Spinners變得可見,但在未檢查行時不可見。Android Spinners在ListView中,我必須使用ViewHolder嗎?

所以我還沒有設法找到解決方案的問題是,我不知道如何獲得實際的Spinner甚至得到點擊SpinnerListItem行。 Activity延伸ListActivity。任何人都知道一種方法,我可以做到這一點,而不使用ViewHolder或我必須使用ViewHolder

下面是聲明並填充ListView代碼:

mSsCursor = mDbHelper.fetchAllSsPlaylistSs(mPlId); 
     startManagingCursor(mSsCursor); 

     String[] from = new String[]{"pl_selected", BTDbAdapter.KEY_NAME, BTDbAdapter.KEY_NAME2}; 

     int[] to = new int[]{R.id.pl_selected, R.id.name, R.id.name2}; 

     mAllSs = new SimpleCursorAdapter(this, R.layout.pl_edit_ss_row, mSsCursor, from, to); 
     mAllSs.setViewBinder(new SimpleCursorAdapter.ViewBinder() { 
     //custom handling of setting the value 
     public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 
      if(columnIndex == 3) { 
        ViewGroup row = (ViewGroup)view.getParent().getParent(); 
        mSId = cursor.getInt(0); 
        if (cursor.getInt(3) > 0) { 
         mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected); 
         mCheckBox.setChecked(true); 
         mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin); 
         mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin); 
         mtvT = (TextView) row.findViewById(R.id.pl_t); 
         mtvM = (TextView) row.findViewById(R.id.pl_m); 
         mTSpin.setVisibility(View.VISIBLE); 
         mtvT.setVisibility(View.VISIBLE); 
         mMSpin.setVisibility(View.VISIBLE); 
         mtvM.setVisibility(View.VISIBLE); 
         //set the values in the t spinner 
         PopulateTSpinner(cursor.getInt(4)); 
         //set the values in the m spinner 
         PopulateMSpinner(cursor.getInt(5)); 
        } 
        else { 
         mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected); 
         mCheckBox.setChecked(false); 
         mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin); 
         mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin); 
         mtvT = (TextView) row.findViewById(R.id.pl_t); 
         mtvM = (TextView) row.findViewById(R.id.pl_m); 
         mTSpin.setVisibility(View.GONE); 
         mtvT.setVisibility(View.GONE); 
         mMSpin.setVisibility(View.GONE); 
         mtvM.setVisibility(View.GONE); 
        }     
        return true; 
      } 
      return false; 
     } 
    }); 
    setListAdapter(mAllSs); 

感謝。

+2

添加適配器的代碼。 – Luksprog

+0

我意識到我可能會通過使用'ViewHolder'來避免在每次調用setViewValue時查看視圖,但我對此並不熟悉,並且還沒有弄清楚它們的工作方式以及if我可以立即將更改提交給數據庫。 – collusionbdbh

+0

你想要什麼樣的紡紗廠? 「CheckBoxes」真的有效嗎?現在你從數據庫中正確地設置了CheckBoxes的值,但是你沒有連接到它們的監聽器,所以可能他們正在工作,但它不應該能夠將新狀態保存到數據庫中。 – Luksprog

回答

1

我不知道如果我理解你的問題:如果你的程序流程是:

顯示(CheckBox + TextViewSpinners隱藏))的數據列表 - >
用戶點擊一個行(該Spinners出現用於與(個體)的數據行) - >
用戶選擇那些Spinners東西 - 在數據庫> 節省該選擇

然後我認爲你應該使用一個自定義的適配器,並保持自己的行創建+數據綁定(我沒有看到你將如何爲Spinners設置一個偵聽器)。下面是你會如何做一個小例子(儘管可能不是做一個漂亮的方式):

public class CustomAdapter extends SimpleCursorAdapter { 

     private LayoutInflater mInflater; 

     public CustomAdapter(Context context, int layout, Cursor c, 
       String[] from, int[] to) { 
      super(context, layout, c, from, to); 
      mInflater = LayoutInflater.from(context); 
     } 

     @Override 
     public void bindView(View view, Context context, Cursor cursor) { 
      ViewHolder holder = (ViewHolder) view.getTag(); // the holder 
                  // pattern 
      // set the text for the TextView in your row 
      holder.name 
        .setText(cursor.getString(cursor.getColumnIndex("name"))); 
      // status of the CheckBox from the database 
      int status = cursor.getInt(cursor.getColumnIndex("pl_selected")); 
      // set the CheckBox status 
      holder.ckb.setChecked((status > 0) ? true : false); 
      // get the id of this particular row, we'll use this later in the 
      // Spinner's listeners 
      long theId = cursor.getLong(cursor.getColumnIndex("_id")); 
      // see if it is time to show the Spinners 
      if (status > 0) { 
       // it is time to show the Spinners. Here you would do stuff 
       // like: setting up the Spinner's adapters + setting the 
       // listener 
       // I used a Spinner with entries set in the xml layout(so my 
       // selection result is a String) 
       holder.spin1.setVisibility(View.VISIBLE); 
       holder.spin2.setVisibility(View.VISIBLE); 
       // set theId as a tag so you know which Spinner was acted on 
       holder.spin1.setTag(new Long(theId)); 
       holder.spin1 
         .setOnItemSelectedListener(new OnItemSelectedListener() { 

          @Override 
          public void onItemSelected(AdapterView<?> parent, 
            View view, int position, long id) { 
           Long realRowId = (Long) parent.getTag(); 
           // I don't know 
           ContentValues cv = new ContentValues(); 
           // the column where I saved the spinner selected 
           // item is called "saved_item" 
           cv.put("saved_item", (String) parent 
             .getItemAtPosition(position)); 
           // mDb is my SQLiteDatabase instance 
           mDb.update("tbl", cv, "_id = ?", 
             new String[] { String 
               .valueOf(realRowId) }); 
           // I don't know how you saved the data, the 
           // above is just an example 
          } 

          @Override 
          public void onNothingSelected(AdapterView<?> parent) { 

          } 
         }); 
       // also implement the second Spinner like the first one 
      } else { 
       // required to prevent a recycled View from causing damage 
       holder.spin1.setVisibility(View.GONE); 
       holder.spin2.setVisibility(View.GONE); 
      } 
     } 

     @Override 
     public View newView(Context context, Cursor cursor, ViewGroup parent) { 
      View v = mInflater.inflate(R.layout.adapters_listspinner_row, 
        parent, false); 
      ViewHolder holder = new ViewHolder(); 
      holder.spin1 = (Spinner) v.findViewById(R.id.spinner1); 
      holder.spin1.setFocusable(false); 
      holder.spin2 = (Spinner) v.findViewById(R.id.spinner2); 
      holder.spin2.setFocusable(false); 
      holder.name = (TextView) v.findViewById(R.id.textView1); 
      holder.ckb = (CheckBox) v.findViewById(R.id.checkBox1); 
      holder.ckb.setFocusable(false); 
      v.setTag(holder); 
      return v; 
     } 

     class ViewHolder { 
      Spinner spin1, spin2; 
      TextView name; 
      CheckBox ckb; 
     } 

    } 

此外,需要onListItemcClick方法:

@Override 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
     // manage the CheckBox state 
     CheckBox ckb = (CheckBox) v.findViewById(R.id.checkBox1); 
     ckb.setChecked(!ckb.isChecked()); 
     ContentValues cv = new ContentValues(); 
     cv.put("pl_selected", ckb.isChecked() ? 1 : 0); 
     mDb.update("tbl", cv, "_id = ?", 
       new String[] { String.valueOf(id) }); 
     // requery the database so the changes are seen by the adapter, this is horrible! 
     Cursor re = mDb.query("tbl", null, null, null, null, null, null); 
     mAllSs.changeCursor(re); 
    } 

作爲一個建議,也許你可以修改您的應用程序的佈局,並將Spinners移出ListView行。

+0

我曾經想過通過顯示不同的視圖簡化佈局,當用戶檢查行選擇附加值,但這是我想盡可能避免的事情。我認爲如果我能這樣做,界面會更好。無論如何,非常感謝您的幫助,當我有機會時會嘗試您建議的方法,並會告訴您我是否能夠正常工作。再次感謝@Luksprog,我非常感謝你的幫助。 – collusionbdbh

+0

只是想我會給這個快速更新,似乎工作正常,仍然有一些工作來清理這件事,我仍然在爲spinners的setOnItemSelectedListeners獲取我需要的數據,但事件正在觸發時我幾乎從那裏選擇紡紗工的東西。感謝您的幫助Luksprog。 – collusionbdbh

相關問題