【问题标题】:Checkbox with ListView and Custom Adapter withouth using Array带有 ListView 和自定义适配器的复选框,而不使用数组
【发布时间】:2017-05-20 15:38:30
【问题描述】:

这个问题很简单,因为它已经在这里讨论过 - 广泛! -,关于带有复选框的 Listview 在滚动后失去状态或无法保持其状态。 在我的情况下,当滚动出视图时,选中的框会被取消选中。 在这篇文章中:Listview, custom adapter and checkboxes,我几乎实现了期望的行为;但是,它使用的是 ArrayList,而且我读过这个实现的重绘次数,当你有一个很长的列表时,这是值得的...... 我在这里使用了 20 多个可用的实现。不幸的是,我无法找出为什么不起作用。 所以,请耐心等待我。 我只会发布我认为对我的问题至关重要的内容。 在 ShowChosenItensFromCategoriaActivity 下方。 注意:我将 dbAdapter 与 SimpleCursorAdapter 一起传递。

    public class ShowChosenItensFromCategoriaActivity1 extends AppCompatActivity
{ 

    private ListView mListView;
    private SimpleCursorAdapter mCursorAdapter;
    private Cursor mCursor;
    private Bundle bundle;
    private DBAdapter dbAdapter;
    private int CATEGORIA_ID;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
    
        super.onCreate(savedInstanceState);
        bundle = this.getIntent().getExtras();
        CATEGORIA_ID = bundle.getInt("CATEGORIA_ID");

        setContentView(R.layout.show_all_produtos_from_chosen_categoria);
        dbAdapter = new DBAdapter(this);
        dbAdapter.open();
        mCursor = dbAdapter.getChosenProdutosFromCategoria(CATEGORIA_ID);

        String[] From = new String[]{"produtoname", "checked"};
        int[] To = new int[]{R.id.idlistitem, R.id.idcheck};

        mCursorAdapter = new ShowChosenItensFromCategoriaAdapter1(this,
                                                                  R.layout
                                                                  .show_all_produtos_from_chosen_categoria_row,
                                                                  mCursor, From, To, 0, dbAdapter);
        mListView = (ListView) findViewById(R.id.produtos_listview);
        mListView.setAdapter(mCursorAdapter);
        }
    }

现在是 show_all_produtos_from_chosen_categoria.xml,方法 getChosenProdutosFromCategoria(CATEGORIA_ID).show_all_produtos_from_chosen_categoria_row.xml

代码:show_all_produtos_from_chosen_categoria.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

      <ListView
            android:id="@+id/produtos_listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/toolbar"
            android:layout_marginBottom="@dimen/list_padding"
            android:layout_marginTop="@dimen/list_padding"
            android:background="@color/lime_100"
            android:padding="@dimen/list_padding"
            android:scrollbarStyle="outsideOverlay"
      tools:listitem="@layout/show_all_produtos_from_chosen_categoria_row"/>
    </RelativeLayout>

getChosenProdutosFromCategoria(CATEGORIA_ID) 的代码:

    public Cursor getChosenProdutosFromCategoria(int categoriaID)
    {
        mCursor = mDB.rawQuery(
            "SELECT l._id, l.listaprodutoid as produtoID, p.produtoname as produtoname, " +
            "l.listacheckbox as checked " +
            "FROM tbllistadecompras l, tblprodutos p WHERE l.listaprodutoid = p._id and " +
            "l.listacategoriaid=" + categoriaID + " ORDER BY p.produtoname", null);


        if (mCursor != null) mCursor.moveToFirst();
        assert mCursor != null;
        return mCursor;
    }

代码:show_all_produtos_from_chosen_categoria_row.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="?android:attr/activatedBackgroundIndicator"
                android:orientation="horizontal"
                tools:context=".ShowChosenItensFromCategoriaActivity">

        <TextView
            android:id="@+id/idlistitem"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:elegantTextHeight="true"
            android:ellipsize="end"
            android:scrollHorizontally="false"
            android:textColor="@color/blue"
            android:textSize="20sp"/>

        <CheckBox
            android:id="@+id/idcheck"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_marginEnd="10dip"
            android:layout_marginStart="4dip"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:gravity="center">
        </CheckBox>
    </RelativeLayout>

现在,最大的问题是适配器 ShowChosenItensFromCategoriaAdapter。 我已经单独尝试了 newView/bindView 和 getView 。 在这里,我插入了 getView: 方法:

    class ShowChosenItensFromCategoriaAdapter extends SimpleCursorAdapter
    {
        private DBAdapter dbAdapter;
        private final Context context;

        public ShowChosenItensFromCategoriaAdapter1(Context context, int 
     layout, Cursor c, String[] from, int[] to, int flags,DBAdapter dbAdapter)
        {
            super(context, layout, c, from, to, flags);
            this.context = context;
            this.dbAdapter = dbAdapter;
     
            dbAdapter.open();
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup 
    parent)
        {
            ViewHolder viewHolder;
            final int auxProdutoID; // has to be, to be used inside the 
        checkbox.method
            if (mCursor.moveToPosition(position))
           {
               if (convertView == null)
               {
                   LayoutInflater inflator = (LayoutInflater) 
        content.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                   viewHolder = new ViewHolder();
                   viewHolder.produtoID = 
    mCursor.getInt(mCursor.getColumnIndex("produtoID"));
                   auxProdutoID = viewHolder.produtoID;
                   viewHolder.textviewProduto = (TextView) 
    convertView.findViewById(R.id.idlistitem);
                   viewHolder.checkBox = (CheckBox) 
    convertView.findViewById(R.id.idcheck);
                   viewHolder.checkBox.setOnCheckedChangeListener(
                       new CompoundButton.OnCheckedChangeListener()
                       {
                        @Override
                        public void onCheckedChanged(CompoundButton 
     buttonView,boolean isChecked)
                       {
                           dbAdapter.setCheckBox(auxProdutoID, isChecked ? 1 
    : 0);
                           viewHolder.checkBox.setSelected(isChecked);
                           //int getPosition = (Integer) 
    buttonView.getTag();
                       }
                      });
        
               convertView.setTag(viewHolder);
          }
          else
          {
             viewHolder = (ViewHolder) convertView.getTag();
          } 

         viewHolder.checkBox.setTag(position)
         viewHolder.textviewProduto.setText(
         mCursor.getString(mCursor.getColumnIndex("produtoname")));
         viewHolder.checkBox.setChecked(
         mCursor.getInt(mCursor.getColumnIndex("checked")) == 1);
 
         return convertView;
        }
    }
}

【问题讨论】:

    标签: android listview checkbox


    【解决方案1】:

    要确定是否应检查视图,您使用的是数据库中列的值:

    viewHolder.checkBox.setChecked(mCursor.getInt(mCursor.getColumnIndex("checked")) == 1);
    

    但是要将视图标记为选中,您使用的是 DBAdapter 类:

    dbAdapter.setCheckBox(auxProdutoID, isChecked ? 1 : 0);
    

    您应该使用相同的代码来控制复选框状态,如果您在 DBAdapter 类中控制状态,则要决定是否应该检查检查,您应该检查 DBAdapter 类或者如果您更喜欢使用数据库,在onClickListener 你应该更新数据库中的数据。

    【讨论】:

    • 您好。感谢您的回答。方法 dbAdapter.setCheckBox(...) 正是这样做的:我将数据库列标记为已检查,并进行更新。事实上,当我离开活动并返回活动时,所有选中的复选框都在那里。问题依赖于 Listview 的滚动、Recyclerview 特性,我无法完全理解。谢谢你的见解。
    【解决方案2】:

    由于列表视图中使用的自定义项目布局,有时会出现维护问题。 你试过吗?

    mCursorAdapter = new ShowChosenItensFromCategoriaAdapter1(this,
                                                              android.R.layout.simple_list_item_checked,
                                                              mCursor, From, To, 0, dbAdapter);
    mListView = (ListView) findViewById(R.id.produtos_listview);
    mListView.setAdapter(mCursorAdapter);
    mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2021-08-19
      • 2015-10-08
      • 1970-01-01
      • 2015-08-22
      相关资源
      最近更新 更多