0

I am using odoo mobile framework. My android app will connect to odoo server. I fetch the product from server and display in listview. I want to get multiple select value from listview. Here is my code. When I click a checkbox, another checkboxs also checked automatically. I am not sure it is due to OEListAdapter or my wrong code.

product_list.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ListView
            android:id="@+id/lvProductListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:paddingTop="?android:attr/actionBarSize" >
    </ListView>

</LinearLayout>

product_list_row.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:padding="5dp"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ImageView
            android:id="@+id/imgvProductPic"
            android:layout_width="42dp"
            android:layout_height="42dp"
            android:layout_gravity="center_vertical"
            android:src="@drawable/ic_launcher" />

    <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:padding="5dp" >

        <TextView
                android:id="@+id/txvProductName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Product Name"
                android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
                android:id="@+id/txvQty"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Quantity"
                android:textAppearance="?android:attr/textAppearanceSmall" />

        <TextView
                android:id="@+id/txvPrice"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:singleLine="true"
                android:text="Price"
                android:textAppearance="?android:attr/textAppearanceSmall" />
    </LinearLayout>

    <CheckBox
            android:id="@+id/check"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginLeft="4dip"
            android:layout_marginRight="10dip"
            android:focusable="false"
            android:focusableInTouchMode="false" >
    </CheckBox>

</LinearLayout>

Here is my activity code.

    public class Products extends BaseFragment implements OETouchListener.OnPullListener,AdapterView.OnItemClickListener{

    public static final String TAG = "com.odoo.addons.products.Products";

    View mView = null;
    ListView mListView = null;
    OEListAdapter mListAdapter = null;
    List<Object> mProductItems = new ArrayList<Object>();
    OETouchListener mTouchAttacher;
    ProductsLoader mProductsLoader = null;
    ArrayList<Integer> checkedPositions = new ArrayList<Integer>();
    CheckBox ckProduct;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);

        mView = inflater.inflate(R.layout.products_list_layout, container, false);
        scope = new AppScope(getActivity());
        init();
        return mView;
    }

    /**
     * Map View and Product Items
     */
    private void init() {
        Log.d(TAG, "call init()");
        mListView = (ListView) mView.findViewById(R.id.lvProductListView);
        mListAdapter = new OEListAdapter(getActivity(),R.layout.products_list_row, mProductItems) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View mView = convertView;
                final int holder = position;
                if (mView == null)
                    mView = getActivity().getLayoutInflater().inflate(getResource(), parent, false);

                Log.d(TAG,"This is "+position+".");

                OEDataRow row = (OEDataRow) mProductItems.get(position);

                ImageView imgProduct = (ImageView) mView.findViewById(R.id.imgvProductPic);
                Bitmap bitmap = null;

                if(row != null){
                    String base64Image = row.getString("image_small");
                    bitmap = Base64Helper.getBitmapImage(getActivity(), base64Image);
                }
                imgProduct.setImageBitmap(bitmap);

                TextView txvProductName, txvQty, txvPrice;
                ckProduct = (CheckBox) mView.findViewById(R.id.check);
                txvProductName = (TextView) mView.findViewById(R.id.txvProductName);
                txvQty = (TextView) mView.findViewById(R.id.txvQty);
                txvPrice = (TextView) mView.findViewById(R.id.txvPrice);

                txvProductName.setText(row.getString("name"));
                txvQty.setText(row.getString("qty_available"));
                txvPrice.setText(row.getString("lst_price"));

                // when checkbox is clicked, we add/remove its position to/from the list
                ckProduct.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        if (((CheckBox) v).isChecked()) {
                            // if checked, we add it to the list
                            checkedPositions.add(holder);
                        }
                        else if(checkedPositions.contains(holder)) {
                            // else if remove it from the list (if it is present)
                            checkedPositions.remove(holder);
                        }

                    }
                });
                // set the state of the checbox based on if it is checked or not.
                ckProduct.setChecked(checkedPositions.contains(holder));

                return mView;
            }
        };
        mTouchAttacher = scope.main().getTouchAttacher();
        mTouchAttacher.setPullableView(mListView, this);
//        mListView.setOnItemClickListener(this);
        mProductsLoader = new ProductsLoader();
        mProductsLoader.execute();
    }

//    View.OnItemClickListener productCheckboxClickListener = new View.OnClickListener() {
//        @Override
//        public void onClick(View v) {
//            Toast.makeText(getActivity(),"got",Toast.LENGTH_SHORT).show();
//        }
//    };

    // Call ProductDB aka ORM Object
    @Override
    public Object databaseHelper(Context context) {
        return new ProductsDB(context);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        Log.d(TAG,"call onCreateOptionMenu");
        inflater.inflate(R.menu.menu_fragment_products, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Log.d(TAG,"call onOptionsItemSelected");
        switch (item.getItemId()) {
            case R.id.menu_product_next:
                    Toast.makeText(getActivity(),"Test"+checkedPositions+"test",Toast.LENGTH_SHORT).show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    // Add Menu Drawer Item
    @Override
    public List<DrawerItem> drawerMenus(Context context) {
        List<DrawerItem> menu = new ArrayList<DrawerItem>();

        menu.add(new DrawerItem(TAG, "Products", true));
        menu.add(new DrawerItem(TAG, "Products", 0, R.drawable.ic_action_todo,getFragment("Products")));

        return menu;
    }

    // Define Fragment
    private Fragment getFragment(String value) {
        Products products = new Products();
        Bundle bundle = new Bundle();
        bundle.putString("name", value);
        products.setArguments(bundle);
        return products;
    }

    /**
     * Loading product list from another thread
     */
    class ProductsLoader extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected Boolean doInBackground(Void ...params){
            Log.d(TAG,"Call ProductsLoader()");
            mProductItems.clear();
            ProductsDB db = new ProductsDB(getActivity());
            mProductItems.addAll(db.select());
            return true;
        }

        @Override
        protected void onPostExecute(Boolean success) {
            Log.d(TAG,"Call onPostExecute");
            checkProducts();
        }
    }

    /**
     * Check empty database or not
     * TODO Need to fix check status
     */
    private void checkProducts() {
        if(mProductItems.size() != 0){
            mListAdapter.notifiyDataChange(mProductItems);
            mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
            mListView.setAdapter(mListAdapter);
            mListView.setOnItemClickListener(this);
        }
    }

    /**
     * On Product item click
     */
    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position,
                            long id) {

        OEDataRow row = (OEDataRow) mProductItems.get(position);

        Toast.makeText(getActivity(),row.getString("id"),Toast.LENGTH_SHORT).show();

    }


    /**
     * Watch Sync status and inform ProductsLoader
     */
    @Override
    public void onResume() {
        super.onResume();
        getActivity().registerReceiver(mSyncFinish, new IntentFilter(SyncFinishReceiver.SYNC_FINISH));
    }

    @Override
    public void onPause() {
        super.onPause();
        getActivity().unregisterReceiver(mSyncFinish);
    }

    SyncFinishReceiver mSyncFinish = new SyncFinishReceiver() {
        public void onReceive(Context context, android.content.Intent intent) {
            mTouchAttacher.setPullComplete();
            mProductsLoader = new ProductsLoader();
            mProductsLoader.execute();
        }
    };

    /**
     * on pulled for sync message
     */
    @Override
    public void onPullStarted(View arg0) {
        scope.main().requestSync(ProductsProvider.AUTHORITY);
    }

}
Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159
Zaw Myo Htet
  • 540
  • 2
  • 7
  • 23
  • Why checkbox is not there inside `getView()`? – Aniruddha Jun 18 '14 at 08:18
  • Updated. Now I can check the single checkbox but when I uncheck the check,it broken. – Zaw Myo Htet Jun 18 '14 at 09:11
  • it broken? what do you mean by that? Explain – Aniruddha Jun 18 '14 at 09:12
  • When I un-check the checkbox, I got this error.E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IndexOutOfBoundsException: Invalid index 3, size is 1 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) at java.util.ArrayList.remove(ArrayList.java:403) at com.odoo.addons.products.Products$1$1.onClick(Products.java:105) at android.view.View.performClick(View.java:4240) at android.widget.CompoundButton.performClick(CompoundButton.java:100) – Zaw Myo Htet Jun 18 '14 at 09:18

1 Answers1

0

I know this is too late for this question , but for handling checkbox inside a listview you should use viewholder pattern , create a arraylist of boolean that will store your selection here is sample code

Declaration of arraylist

public static ArrayList<Boolean> arrChecked;

initialise the list

for (int i = 0; i < data.size(); i++) {
            arrChecked.add(false);
        }

then in getView method use holder like this ,

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.listview_item, null);

            ViewHolder viewHolder = new ViewHolder();

                viewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkbox);

            // The tag can be any Object, this just happens to be the ViewHolder
            convertView.setTag(viewHolder);
        }


       holder = (ViewHolder) convertView.getTag();


        // set position as id
        holder.cb.setId(position);

        holder.cb.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                int id = v.getId();

                if (arrChecked.get(id)) {
                    arrChecked.set(id, false);

                    // unchecked state of checkbox


                } else {
                    arrChecked.set(id, true);

//do what you want to do in checked state here
                }

            }
        });

        holder.cb.setChecked(arrChecked.get(position));
Nibha Jain
  • 7,742
  • 11
  • 47
  • 71