Question

I have defined onCheckedChanged for the checkbox in my listview. When i click on the check box to check / uncheck it this function is getting invoked. But when i setthe state of the check box from code like

check.setChecked(true);

the onCheckedChanged is not getting invoked.

Please help.

Adapter file :

 package com.idg.project.adapters;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.idg.project.R;
import com.idg.project.activities.ScanListActivity;
import com.idg.project.activities.SearchResultActivity;
import com.idg.project.adapters.WishListAdapter.ViewHolder;
import com.idg.project.entity.ScannedProduct;

public class ScanListAdapter extends BaseAdapter {
    private Context context;
    private List<ScannedProduct> productList;
    protected LayoutInflater mInflater;
    Button showOrHideButton;
    static public int count = 0;
    String barcodeForSelectedRow;
    String formatForSelectedRow;
    OnItemClickListener rowListener;
    Activity parentActivity;
    boolean isWishList;

    public ScanListAdapter(Context context, List<ScannedProduct> objects,
            Button button, Activity parentActivity) {

        super();
        this.productList = objects;
        this.context = context;
        this.mInflater = LayoutInflater.from(context);
        showOrHideButton = button;
        this.parentActivity = parentActivity;
        this.isWishList = isWishList;
    }

    public int getCount() {

        return productList.size();
    }

    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }
@Override
public void notifyDataSetChanged() {
    // TODO Auto-generated method stub
    super.notifyDataSetChanged();
}
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        final int pos = position;
        Log.i("checkboxflag at : ", pos+"is"+(productList.get(pos).getCheckboxflag()));


            Log.i("getview : fresh", "getview"+pos);
            convertView = mInflater.inflate(R.layout.product_list_row, null);

            holder = new ViewHolder();
            holder.text1 = (TextView) convertView.findViewById(R.id.productid);
            holder.text1.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    Intent intent = new Intent(parentActivity,
                            SearchResultActivity.class);
                    intent.putExtra("barcode", productList.get(pos)
                            .getBarcode());
                    intent.putExtra("format", productList.get(pos).getFormat());
                    intent.putExtra("IsScan", false);
                    Log.i("", "" + productList.get(pos).getBarcode());
                    parentActivity.startActivity(intent);
                    Log.i("", "" + pos);

                }
            });
            holder.text2 = (TextView) convertView.findViewById(R.id.price);
            // holder.text2.setOnClickListener(listener);
            holder.image = (ImageView) convertView
                    .findViewById(R.id.productimageid);
            convertView.setTag(holder);
            // holder.image.setOnClickListener(listener);




        holder.text1.setText(productList.get(position).getTitle());
        holder.text2.setText(productList.get(position).getPrice().toString());
        if (productList.get(position).getSmallImage() != null) {
            byte[] bb = (productList.get(position).getSmallImage());
            holder.image.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0,
                    bb.length));
        } else {
            holder.image.setImageBitmap(null);
            holder.image.setBackgroundResource(R.drawable.highlight_disabled);
        }

        // holder.image.setImageBitmap(Utils.loadBitmap(productList.get(position).getSmallImage()));
        final CheckBox check = (CheckBox) convertView
                .findViewById(R.id.checkbox);
        check.setClickable(true); // to remove anything carried over from prev convert view
        if(productList.get(pos).getCheckboxflag()==1)
        {
            Log.i("CheckBox set checked",""+pos);
            check.setChecked(true);

        }
        else{
            Log.i("CheckBox set unchecked",""+pos);
            check.setChecked(false);
        }
        setWishListItemsInScanList(pos, convertView);
        check.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                Log.i("OnclickListener","Current Position"+pos);
                if (check.isChecked()
                        && productList.get(pos).getWishListFlag() == 0) {

                    if(check.isClickable()){
                        Log.i("CheckBox check",""+pos);
                    ScanListActivity.updateCheckBoxSelection(1, pos);
                    ScanListAdapter.count++;
                    }

                } else if (!check.isChecked()
                        && productList.get(pos).getWishListFlag() == 0){
                    if(check.isClickable()){
                        ScanListActivity.updateCheckBoxSelection(0, pos);
                        ScanListAdapter.count--;
                        Log.i("CheckBox UNcheck",""+pos);
                        }



                }
                if (ScanListAdapter.count == 0) {
                    // showOrHideButton.setClickable(false);
                    // showOrHideButton.setVisibility(View.GONE);
                    showOrHideButton.setEnabled(false);
                } else {
                    // showOrHideButton.setVisibility(View.VISIBLE);
                    showOrHideButton.setEnabled(true);
                }

            }

        });
        return convertView;
    }

    private void setWishListItemsInScanList(int pos, View convertView) {
        if (productList.get(pos).getWishListFlag() == 1) {
            Log.i("CheckBox set checked from wish list",""+pos);
            CheckBox check = (CheckBox) convertView.findViewById(R.id.checkbox);
            check.setClickable(false);
            check.setChecked(true); 
        }

    }

    static class ViewHolder {
        TextView text1;
        ImageView image;
        TextView text2;
    }

}

List activity file :

   package com.idg.project.activities;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.idg.project.R;
import com.idg.project.adapters.WishListAdapter;
import com.idg.project.adapters.ScanListAdapter;
import com.idg.project.entity.ScannedProduct;
import com.idg.project.services.ScannedProductDataAccessManager;

public class ScanListActivity extends BaseActivity {
    static Button scanlist;
    ScanListAdapter listAdapter;
    static List<ScannedProduct> productList;

    /* Notes for the Developer : 
     * For tracking the checked items  Checkboxflag 
     * is maintained. 
     * Point1 : Select all will just set this flag in the local list and then call notifyDatachange of the adapter
     * within adapter the check box is set or reset based on this flag for each row
     * 
     * Point 2: When individual rows are selected , there is an onclick of the check box is invoked
     * Here the Checkboxflag of the local list is set /unset . Also we need a way to knpw the select all button is 
     * to enabled or diabled. for that Count variable is updated here. 
     * Now Important point is these two actions shoulnt be taking place if the checkbox state change due to select all
     * So there is a special check of isclickable in the onclicklistener 
     * 
     * Point 3: In scan list the items in the wish list are to be marked. This again needs special logic. 
     * This is done in the adapter code by checking all the rows whose wishListFlag is 1 and making it non clickable
     * 
     * Important : Listview has the concept of ViewGroup and each view group is usually the rows fitting in the display screen
     * so when we scroll, the viewGropu changes. 
     * Convertview is get reused for view groups. So need to careful undesired values that will be carried to next viewgroup*/

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.scan_list);
        productList = new ArrayList<ScannedProduct>();
        productList = getProductList();
        for(int i=0;i<productList.size();i++){
            Log.i("checkboxflag at : ", i+"is"+(productList.get(i).getCheckboxflag()));
        }
        final ListView lv = (ListView) findViewById(R.id.list);
        scanlist = (Button) findViewById(R.id.addtowishlist);
        scanlist.setEnabled(false);
        listAdapter = new ScanListAdapter(this, productList, scanlist, this);
        lv.setAdapter(listAdapter);
    }

    private List<ScannedProduct> getProductList() {
        List<ScannedProduct> productList = new ArrayList<ScannedProduct>();
        ScannedProductDataAccessManager productDataBaseManager = new ScannedProductDataAccessManager(
                getApplicationContext());
        String[] colList = { "title", "smallImage", "price" };
        productList = productDataBaseManager.fetchAllProducts();
        return productList;
    }

    static boolean selectFlag = false;

    public void selectAll(View view) {
        ListView listView = (ListView) findViewById(R.id.list);
        view = findViewById(R.id.select_all);
        if (selectFlag == false) {
            for (int i = 0; i < listView.getAdapter().getCount(); i++) {
                productList.get(i).setCheckboxflag(1);
            }
            view.setBackgroundResource(R.drawable.login_remme_dwn_btn);
            selectFlag = true;
            TextView text=(TextView) findViewById(R.id.select);
            text.setText("Unselect All");
            scanlist.setEnabled(true);
        } else {
            for (int i = 0; i < listView.getAdapter().getCount(); i++) {
                productList.get(i).setCheckboxflag(0);
            }
            view.setBackgroundResource(R.drawable.login_remme_up_btn);
            selectFlag = false;
            TextView text=(TextView) findViewById(R.id.select);
            text.setText("Select All");
            scanlist.setEnabled(false);

        }
        ((BaseAdapter)listView.getAdapter()).notifyDataSetChanged(); // we are only setting the flags in the list
                                            // so need to notify adapter to reflect same on checkbox state
        //listView.refreshDrawableState();
    }

    public void addToWishList(View view) {
        ListView listView = (ListView) findViewById(R.id.list);
        for (int i = 0; i < listView.getAdapter().getCount(); i++) {

                ScannedProduct product = productList.get(i);
                if (product.getWishListFlag() == 0 && product.getCheckboxflag()==1) {
                    product.setWishListFlag(1);
                    new ScannedProductDataAccessManager(getApplicationContext())
                            .updateProduct(product, "title",
                                    new String[] { product.getTitle() });
                    product.setCheckboxflag(0);
                    //ScanListAdapter.count--;
                }
                Log.i("ScanList selected", product.getTitle());

            }


        Toast.makeText(getApplicationContext(),
                "Added selected items to Wish List", Toast.LENGTH_SHORT).show();
        scanlist.setEnabled(false);
        ((BaseAdapter)listView.getAdapter()).notifyDataSetChanged();

    }
    static public void updateCheckBoxSelection(int flag,int pos){   // when individual row check box is checked/ unchecked
                                                                // this fn is called from adapter to update the list
        productList.get(pos).setCheckboxflag(flag);
    }

}
Was it helpful?

Solution 2

I got the answer / bug in my code

  1. i am not reusing convertview so its every time a new holder.

  2. I am changing the flag of the checkbox and then assigning a statechange listener for the checkbox thus its not getting invoked

when i changed the order to assign checkchangelistener before actually changing the state , its working as expected. The listener is getting called.

thanks all of you

OTHER TIPS

Since your checkbox is inside listview, so you need to call notifyDataSetChanged method on your list's adapter to refresh it's contents.


update

instead of ((BaseAdapter)listView.getAdapter()).notifyDataSetChanged();, try calling listAdapter.notifyDataSetChanged();

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top