1

これがStackOverFlowに関する私の最初の質問です。私は通常、自分で答えを見つけますが、ここで説明する奇妙な問題に本当に悩まされています。

フラグメントアクティビティにListViewを実装しました。このリストビューには、SQLLiteデータベースから取得した現在のレコードに関連するカテゴリのリストが含まれています。

すべて正常に機能しています。DBからデータを取得するための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);

いずれかのケースがあるためには、すべてがこれらの2行に依存します。

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

コメントされている場合、チェックボックスは事前にチェックされていませんが、クリックの切り替えは機能しています。しかし、これらの行をコメントアウトすると、トグルは機能しなくなりますが、カテゴリは事前にチェックされています。

私も理解していないのは、この行が機能していないということです。

 categRow.setChecked(catChecked==1);

しかし、これはうまく機能しています(私はタグを取得することに成功しました):

 categRow.setTag(catID);

だから誰かが私が間違っていることを私に説明してくれることを願っています、私がここで誤解していることがあると思います...

:カーソル「categories」から3つの列を取得します。最初の列はカテゴリのID、2番目の列は名前、3番目の列はステータス:チェック済みかどうか(1または0)です。

よろしくお願いします。

4

1 に答える 1

0

最終的に私は自分のカスタムアダプタを作成することになりました。こうすることで、少なくとも何が起こっているのかをより簡単に理解することができました。

私は実際にいくつかの複数選択リストを作成する必要がありました。データベースからのデータが入力されたものもあれば、共有設定からのデータが入力されたものもあります。

DBからのデータを表示するこのアダプター用に、次のアダプターを作成しました(まだセットアップしていないため、アイコンに関する行をコメントアウトしました)。

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が含まれています。

それが誰かを導くかもしれないことを願っています!

于 2013-04-13T06:22:21.557 に答える