在Android的ListView的纱厂,我必须用一个ViewHolder? [英] Android Spinners in ListView, do I have to use a ViewHolder?

查看:206
本文介绍了在Android的ListView的纱厂,我必须用一个ViewHolder?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的ListView 纱厂的问题。我有一个的ListView 复选框,标签和两个纱厂。在微调从SQLite的居住和工作正常。我没有使用 ViewHolder 方法,因为到目前为止,在单击的ListView 排在的CheckBox 被选中或取消选中,变化被立即保存到数据库中。当行检查纱厂是由可见的,但不是当行未选中可见。

所以,我没有设法找到解决办法的问题是,我不知道如何获得实际的微调甚至获得列表项一行被点击微调是。在活动扩展 ListActivity 。任何人都知道一种方法,我可以做到这一点,而无需使用 ViewHolder 或者我必须使用 ViewHolder <?/ p >

下面是code,声明并填充的ListView

  mSsCursor = mDbHelper.fetchAllSsPlaylistSs(mPlId);
        startManagingCursor(mSsCursor);        的String [] =由新的String [] {pl_selected,BTDbAdapter.KEY_NAME,BTDbAdapter.KEY_NAME2};        INT []为= INT新[] {R.id.pl_selected,R.id.name,R.id.name2};        mAllSs =新SimpleCursorAdapter(这一点,R.layout.pl_edit_ss_row,mSsCursor,从,到);
        mAllSs.setViewBinder(新SimpleCursorAdapter.ViewBinder(){
        //设置值的自定义处理
        公共布尔setViewValue(查看视图,光标光标,诠释参数:columnIndex){
            如果(参数:columnIndex == 3){
                    连续的ViewGroup =(ViewGroup中)view.getParent()的getParent()。
                    MSID = cursor.getInt(0);
                    如果(cursor.getInt(3)大于0){
                        mCheckBox =(复选框)row.findViewById(R.id.pl_selected);
                        mCheckBox.setChecked(真);
                        mTSpin =(微调)row.findViewById(R.id.pl_t_spin);
                        mMSpin =(微调)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);
                        //在T微调设置的值
                        PopulateTSpinner(cursor.getInt(4));
                        //在M微调设置的值
                        PopulateMSpinner(cursor.getInt(5));
                    }
                    其他{
                        mCheckBox =(复选框)row.findViewById(R.id.pl_selected);
                        mCheckBox.setChecked(假);
                        mTSpin =(微调)row.findViewById(R.id.pl_t_spin);
                        mMSpin =(微调)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);
                    }
                    返回true;
            }
            返回false;
        }
    });
    setListAdapter(mAllSs);

感谢。


解决方案

我不知道如果我理解你的问题:如果你的程序流程是:


  

显示数据(名单复选框 + 的TextView 纱厂隐藏)) - >

  用户点击一个行(纱厂显示与(个体)的数据行) - >

  用户选择那些东西纱厂 - >
  保存在数据库中选择


那么我认为你应该用自定义适配器去照顾该行创立+数据绑定的自己(我不知道你将如何设置为纱厂)。以下是你可能会怎么做这样的小例子(尽管可能不是$ P做的$ ptty方式):

 公共类CustomAdapter扩展SimpleCursorAdapter {        私人LayoutInflater mInflater;        公共CustomAdapter(上下文的背景下,INT布局,光标C,
                的String []从,INT []到){
            超(背景下,布局,C,从,到);
            mInflater = LayoutInflater.from(上下文);
        }        @覆盖
        公共无效bindView(查看视图,上下文的背景下,光标光标){
            ViewHolder支架=(ViewHolder)view.getTag(); //持有人
                                                            //模式
            //设置TextView的文本的行
            持有人名称
                    .setText(cursor.getString(cursor.getColumnIndex(名称)))​​;
            //将CheckBox的状态从数据库
            INT状态= cursor.getInt(cursor.getColumnIndex(pl_selected));
            //设置状态的CheckBox
            holder.ckb.setChecked((状态&gt; 0)真:假的?);
            //获取这个特殊行的id,我们将在以后的使用
            //微调的听众
            长theId = cursor.getLong(cursor.getColumnIndex(_ ID));
            //看看它是否是时间显示纱厂
            如果(状态&gt; 0){
                //现在是时候展现纱厂。在这里,你会做的东西
                //喜欢:设置Spinner的适配器+设置
                //监听器
                //我用的XML布局设置条目的微调(所以我
                //选择的结果是一个字符串)
                holder.spin1.setVisibility(View.VISIBLE);
                holder.spin2.setVisibility(View.VISIBLE);
                //设置theId作为一个标签,所以你知道哪些是微调采取行动
                holder.spin1.setTag(新龙(theId));
                holder.spin1
                        .setOnItemSelectedListener(新OnItemSelectedListener(){                            @覆盖
                            公共无效onItemSelected(适配器视图&LT;&GT;母公司,
                                    查看查看,INT位置,长的id){
                                龙realRowId =(长)parent.getTag();
                                // 我不知道
                                ContentValues​​ CV =新ContentValues​​();
                                //我在这里保存了微调的列中选择
                                //项目被称为saved_item
                                cv.put(saved_item(字符串)父
                                        .getItemAtPosition(位置));
                                // MDB是我的SQLiteDatabase实例
                                mDb.update(TBL,CV,_id =?,
                                        新的String [] {字符串
                                                .valueOf(realRowId)});
                                //我不知道你是怎么保存的数据中,
                                //以上只是一个例子
                            }                            @覆盖
                            公共无效onNothingSelected(适配器视图&LT;&GT;母公司){                            }
                        });
                //也实现了第二微调像第一个
            }其他{
                //需要prevent一个循环查看从造成损害
                holder.spin1.setVisibility(View.GONE);
                holder.spin2.setVisibility(View.GONE);
            }
        }        @覆盖
        公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){
            视图V = mInflater.inflate(R.layout.adapters_listspinner_row,
                    父母,假);
            ViewHolder持有人=新ViewHolder();
            holder.spin1 =(微调)v.findViewById(R.id.spinner1);
            holder.spin1.setFocusable(假);
            holder.spin2 =(微调)v.findViewById(R.id.spinner2);
            holder.spin2.setFocusable(假);
            holder.name =(TextView中)v.findViewById(R.id.textView1);
            holder.ckb =(复选框)v.findViewById(R.id.checkBox1);
            holder.ckb.setFocusable(假);
            v.setTag(保持器);
            返回伏;
        }        类ViewHolder {
            微调SPIN1,spin2;
            TextView的名称;
            复选框CKB;
        }    }

此外,需要 onListItemcClick 方法:

  @覆盖
    保护无效onListItemClick(ListView中升,视图V,INT位置,长的id){
        //管理状态的CheckBox
        复选框CKB =(复选框)v.findViewById(R.id.checkBox1);
        ckb.setChecked(ckb.isChecked()!);
        ContentValues​​ CV =新ContentValues​​();
        cv.put(pl_selected,ckb.isChecked()?1:0);
        mDb.update(TBL,CV,_id =?,
                新的String [] {将String.valueOf(ID)});
        //重新查询所以变化是由适配器看到的数据库,这是可怕的!
        游标重新= mDb.query(TBL,NULL,NULL,NULL,NULL,NULL,NULL);
        mAllSs.changeCursor(重);
    }

作为一个建议,也许你可以修改你的应用程序的布局和移动纱厂的ListView 一行。

I have an issue with Spinners in a ListView. I have a ListView with a CheckBox, a label, and two Spinners. The Spinner are populated from SQLite and that is working fine. I am not using the ViewHolder method because so far when the ListView row is clicked the CheckBoxes are checked or unchecked and the change is immediately saved to the database. When the row is checked the Spinners are made visible but are not visible when the row is not checked.

So the issue that I haven't managed to find a solution for is that I have no idea how to get the actual Spinner or even get the ListItem row that the clicked Spinner is on. The Activity extends ListActivity. Anyone know a way I can do this without using a ViewHolder or do I have to use a ViewHolder?

Here is the code that declares and populates the 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);

Thanks.

解决方案

I don't know if I understood your question: If your app flow is:

show a list of data(CheckBox + TextView(Spinners hidden)) ->
user clicks a row(the Spinners appear for that row with(individual) data) ->
user selects something in those Spinners-> save that selection in the database

then I think you should go with a custom adapter and take care yourself of the row creation + data binding(I don't see how you would set a listener for the Spinners). Below is a small example on how you might do this(although probably not a pretty way of doing it):

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;
        }

    }

Also, the required onListItemcClick method:

@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);
    }

As an advice, maybe you could modify the layout of your app and move the Spinners out of the ListView row.

这篇关于在Android的ListView的纱厂,我必须用一个ViewHolder?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆