2013-03-25 43 views
1

這是我在計算器上的第一個問題,我平時總是自己找到一個答案,但我真的被困在一個奇怪的問題,我會在這裏解釋:預填CheckedTextViews在ListView

我實現了一個ListView在片段活動中,此列表視圖包含與從SQLLite數據庫中獲取的當前記錄相關的類別列表。

所有工作正常,我創建了一個SimpleCursorAdapter從數據庫中檢索數據,並在ListView中正確顯示類別。 這個問題是關於預填充的複選框(它是一個多選列表),取決於我如何嘗試預先檢查複選框,我得到2個案例:

首先,複選框預先填好,選中,但我不能通過點擊複選框來切換複選框。第二點擊切換以及複選框,但他們沒有預先檢查了...

這裏是代碼的一部分,我有問題:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    //super.onCreate(savedInstanceState); 
    View v = inflater.inflate(R.layout.rate_fragment, container,false); 

    dbCategories = ""; 
    displayCategories = resources.getText(R.string.no_categories).toString(); 


    /** INITIALIZATION */ 
    mViewSwitcher = (ViewSwitcher)v.findViewById(R.id.profileSwitcher); 

    /** Edition view */ 
    rateGroup = (RadioGroup)v.findViewById(R.id.rate_group); 
    rateOne = (RadioButton)v.findViewById(R.id.one_button); 
    rateOne.setTag(1); 
    rateTwo = (RadioButton)v.findViewById(R.id.two_button); 
    rateTwo.setTag(2); 
    rateThree = (RadioButton)v.findViewById(R.id.three_button); 
    rateThree.setTag(3); 
    rateFour = (RadioButton)v.findViewById(R.id.four_button); 
    rateFour.setTag(4); 
    rateFive = (RadioButton)v.findViewById(R.id.five_button); 
    rateFive.setTag(5); 

    descET = (EditText)v.findViewById(R.id.editdescription); 
    descTextSize = descET.getTextSize(); 
    descET.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 

     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

     } 

     @Override 
     public void afterTextChanged(Editable s) { 

     } 
    }); 

    categoriesTV_edit = (TextView)v.findViewById(R.id.edit_categories); 
    categoriesBT = (Button) v.findViewById(R.id.select_categories); 
    categoriesBT.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 

      View categoriesListTitle = getActivity().getLayoutInflater().inflate(R.layout.category_list_title, null); 
      AlertDialog.Builder alt_bld = new AlertDialog.Builder(v.getContext()).setCustomTitle(categoriesListTitle); 

      categories = db.getAllCategoriesByRate(currentRate); 
      categoriesList = new ListView(getActivity()); 
      categoriesList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);     
      categoriesList.setClickable(true); 

      String[] fromColumns = new String[] { 
        DatabaseHandler.CATEGORY_NAME 
      }; 
      int[] toViews = new int[]{ 
        R.id.cat_checked 
      }; 

      //mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_multiple_choice, categories, fromColumns, toViews, 0); 
      mAdapter = new SimpleCursorAdapter(getActivity(), R.layout.category_item, categories, fromColumns, toViews, 0); 

      mAdapter.setViewBinder(new ViewBinder() { 
       public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 

        if (columnIndex == 1) {      

         CheckedTextView categRow = (CheckedTextView) view; 

         String catName = cursor.getString(1); 
         mAdapter.setViewText((TextView) view, catName); 

         int catChecked = cursor.getInt(2); 
         //boolean checkedCat = catChecked==1; 
         //categoriesList.setItemChecked(cursor.getPosition(),checkedCat); 
         categRow.setChecked(catChecked==1); 

         int catID = cursor.getInt(0); 
         categRow.setTag(catID); 
         return true; 
        } 
        else { 
         return false; 
        } 
       } 
      }); 

      categoriesList.setAdapter(mAdapter); 

      alt_bld.setView(categoriesList); 

爲了有一個案例或其他,全部取決於以下兩行:

//boolean checkedCat = catChecked==1; 
//categoriesList.setItemChecked(cursor.getPosition(),checkedCat); 

如果他們被評論,複選框沒有預先檢查,但點擊切換正在工作。但是,如果我將這些行註釋掉,切換不再有效,但類別會被預先檢查。

什麼我也弄不明白的是,這條線是不工作:

categRow.setChecked(catChecked==1); 

但是,這是一個很好的工作(我成功檢索標籤):

categRow.setTag(catID); 

所以我希望有人會成功向我解釋我做錯了什麼,我猜這裏有一些我誤解了的東西...

注意:我得到3列在遊標「類別」中,第一個是類別的ID,第二個是名稱,第三個是狀態:是否選中(1或0)。

提前感謝您的時間。

回答

0

最後我最終創建了自己的自定義適配器,這樣我至少可以更容易地理解發生了什麼。

我不得不創建幾個多選列表,其中一些填充了來自數據庫的數據,另一些填充了共享首選項。

對於這一個從數據庫顯示的數據,我創建了下面的適配器(我註釋掉對圖標的線,因爲我並沒有設置它們還):

public class CategoriesLVAdapter extends BaseAdapter { 
private Context mContext; 
private LayoutInflater mInflater; 
private List<Category> categoriesList; 

// Constructor 
public CategoriesLVAdapter(Context c, List<Category> categories_list){ 
    mContext = c; 
    mInflater = LayoutInflater.from(c); 
    categoriesList = categories_list; 
} 

public List<Category> getCategoriesList(){ 
    return categoriesList; 
} 

@Override 
public int getCount() { 
    return categoriesList.size(); 
} 

@Override 
public Object getItem(int position) { 
    return categoriesList.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return categoriesList.get(position).getID(); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder holder = null; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.categories_list_row, null); 
     //convertView.setLayoutParams(new ListView.LayoutParams(200, 90)); 
     holder = new ViewHolder(); 
     holder.title = (TextView) convertView.findViewById(R.id.categories_list_row_tv); 
     //holder.icon = (ImageView) convertView.findViewById(R.id.categories_list_row_iv); 

     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag();   
    } 

    //holder.icon.setImageResource(categoriesList.get(position).getDrawableID()); 
    //holder.icon.setAdjustViewBounds(true); 
    //holder.icon.setScaleType(ImageView.ScaleType.CENTER_CROP);   
    holder.title.setText(categoriesList.get(position).getName()); 

    return convertView; 
} 

static class ViewHolder { 
    TextView title; 
    //ImageView icon; 
} 

}

在我的活動,我用這個適配器時的AlertDialog被調用來填充ListView,然後我使用保存在共享偏好的最後的預選類:

private void categoriesFilter(){ 
    AlertDialog.Builder alt_bld = new AlertDialog.Builder(this); 
    alt_bld.setTitle(resources.getText(R.string.select_categories).toString()); 

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 
    View layout = inflater.inflate(R.layout.categories_list,(ViewGroup) findViewById(R.id.categories_layout_root)); 
    categoriesLV = (ListView) layout.findViewById(R.id.categories_list); 

    alt_bld.setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      String selectedCategoriesString = getSelectedValues(categoriesLV); 

      //Update the shared preferences 
      prefs.edit().putString(RateDayApplication.PREF_KEY_CATEGORIES, selectedCategoriesString).commit(); 

      updateFilterDisplay(resources.getText(R.string.cat_title).toString(), selectedCategoriesString, searchedCategoriesTV, "Category"); 
     } 
    }); 

    alt_bld.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      dialog.cancel(); 
     } 
    }); 

    String selectedCategoriesString = prefs.getString(RateDayApplication.PREF_KEY_CATEGORIES, new String()); 
    categoriesLV.setAdapter(new CategoriesLVAdapter(this, categoriesList)); 

    String[] selectedCategoriesArray = selectedCategoriesString.split(","); 

    int categoriesLVLength = categoriesLV.getCount(); 
    for(int i = 0; i < categoriesLVLength; i++){ 
     int categoryID = ((Category) categoriesLV.getItemAtPosition(i)).getID(); 
     if(Arrays.asList(selectedCategoriesArray).contains(String.valueOf(categoryID))){ 
      categoriesLV.setItemChecked(i, true); 
     } 
    } 

    alt_bld.setView(layout); 

    AlertDialog alert = alt_bld.create(); 
    alert.show(); 
} 

最後,這裏是我從我的數據庫處理程序調用該函數來獲取名作的名單:

// Getting All Categories By ID desc 
    public List<Category> getCategoriesList() { 
     String selectQuery = "SELECT " + CATEGORY_ID + ", " + CATEGORY_NAME + " FROM " + CATEGORY_TABLE + " ORDER BY " + CATEGORY_ID + " ASC"; 
     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     List<Category> categoriesList = new ArrayList<Category>();//String[] categoriesList = {}; 

     // looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       Category category = new Category(cursor.getInt(0), cursor.getString(1), false); 
       categoriesList.add(category); 
      } while (cursor.moveToNext()); 
     } 

     cursor.close(); 
     db.close(); 
     return categoriesList; 
    } 

我想我的問題之前,從事實,即功能「setItemChecked」未來是有點誤導,因爲它不意味着必須檢查任何東西。 當您使用函數「setItemChecked」時,列表視圖中的項目被選中,帶或不帶複選框(我的行只包含文本視圖)。

在我的列表中選擇的行以不同的顏色顯示,我認爲這對於簡單的多選列表來說足夠了。

我使用的佈局非常簡單,「categories_list」包含LinearLayout中的ListView,「categories_list_row」包含LinearLayout中的TextView。

希望它可以引導某人!