abdfahim
abdfahim

Reputation: 2553

Android - Multiple selection in ListView

Okay, I am stuck whole day trying to get Checkbox added in listview. I have two part

  1. If I click on any item in the listbox, it will load something (this part is already implemented).
  2. There is a checkbox with each item. I want to be able to check any 10 or whatever number of items so that even if I scroll through the list, the selection will not get lost.

Can anyone please help me regarding that? One of the solution I checked is this solution, but I don't want to restructure whole code unless it is necessary.

MAINACTIVITY:

public class ShowList  extends Activity{

    static final String LIST_KEY_ID = "bookid";
    static final String LIST_KEY_NAME = "bookname";
    static final String LIST_KEY_WRITER = "writer";

    ListView list;
    MylibmanList adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_list);
        setupActionBar();

        mylibmandbhandler db = new mylibmandbhandler(this);
        List<mylibman> allfld = db.getAllRecord();
        db.close();
        ArrayList<HashMap<String, String>> allbookList = new ArrayList<HashMap<String, String>>();
        for (mylibman cn : allfld) {
            HashMap<String, String> map = new HashMap<String, String>();
                map.put(LIST_KEY_ID, Integer.toString(cn.getBookid()));
            map.put(LIST_KEY_NAME, cn.getBookname());
                map.put(LIST_KEY_WRITER, cn.getWriter());

                allbookList.add(map);
        }
        list=(ListView)findViewById(R.id.list);
        adapter=new MylibmanList(this, allbookList);
        list.setAdapter(adapter);

        list.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                batchid.clear();
                HashMap<String, String> list_hashMap = (HashMap<String, String>) parent.getItemAtPosition(position);
                String currlist = list_hashMap.get(LIST_KEY_ID);
                Intent returnIntent  = new Intent();
                returnIntent.putExtra("bookid",currlist);
                setResult(RESULT_OK,returnIntent );
                finish();
            }
        });

ADAPTER CLASS:

public class MylibmanList extends BaseAdapter {
        private Activity activity;
        private ArrayList<HashMap<String, String>> data;
        private static LayoutInflater inflater=null;

        public MylibmanList(Activity a, ArrayList<HashMap<String, String>> d) {
            activity = a;
            data=d;
            inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        static class ViewHolder {
            TextView title;
            TextView artist;
            TextView duration;
            CheckBox check;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View vi=convertView;
            if(convertView==null)
                vi = inflater.inflate(R.layout.listrow_row, null);

            ViewHolder holder = new ViewHolder();
            holder.title = (TextView)vi.findViewById(R.id.title);
            holder.artist = (TextView)vi.findViewById(R.id.artist);
            holder.duration = (TextView)vi.findViewById(R.id.duration);
            holder.check = (CheckBox)vi.findViewById(R.id.check);

            holder.check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Log.d("test","t3"); // Don't know what to do 
                }
            });
            vi.setTag(holder);
            holder.check.setTag(data.get(position));

            HashMap<String, String> book = new HashMap<String, String>();
            book = data.get(position);

            ViewHolder holderfin = (ViewHolder) vi.getTag();
            holderfin.title.setText(book.get(ShowList.LIST_KEY_NAME));
            holderfin.artist.setText(book.get(ShowList.LIST_KEY_WRITER));
            holderfin.duration.setText(book.get(ShowList.LIST_KEY_ID));
            holderfin.check.setChecked(false);
            return vi;
        }
    }

XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

    <LinearLayout android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="3dip"
        android:layout_alignParentLeft="true"
        android:background="@drawable/image_bg"
        android:layout_marginRight="5dip">
 <!--
        <ImageView
            android:id="@+id/list_image"
            android:contentDescription="@string/bookimage"
            android:layout_width="50dip"
            android:layout_height="50dip"/>
 -->
    </LinearLayout>


    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/thumbnail"
        android:layout_toRightOf="@+id/thumbnail"
        android:focusableInTouchMode="false"
        android:clickable="false"
        android:focusable="false"
        android:textColor="#040404"
        android:typeface="sans"
        android:textSize="18sp"
        android:textStyle="bold"/>


    <TextView
        android:id="@+id/artist"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:focusableInTouchMode="false"
        android:clickable="false"
        android:focusable="false"
        android:textColor="#343434"
        android:textSize="13sp"
        android:layout_marginTop="1dip"
        android:layout_toRightOf="@+id/thumbnail" />


    <TextView
        android:id="@+id/duration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/title"
        android:gravity="right"
        android:focusableInTouchMode="false"
        android:clickable="false"
        android:focusable="false"
        android:layout_marginRight="5dip"
        android:textSize="12sp"
        android:textColor="#10bcc9"
        android:textStyle="bold"/>

     <CheckBox
        android:id="@+id/check"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:focusable="false"
        android:layout_marginRight="10dp" />
</RelativeLayout>

Upvotes: 0

Views: 4285

Answers (1)

vikki
vikki

Reputation: 2814

Basically, you can have a hashset that contains only the selected items. The code would look like this

public class MylibmanList extends BaseAdapter {
    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private static LayoutInflater inflater=null;

    HashSet<String> selectedBooks = new HashSet<String>();

    //This listener will be used on all your checkboxes, there's no need to 
    //create a listener for every checkbox.
    CompoundButton.OnCheckedChangeListener checkChangedListener = new CompoundButton.OnCheckedChangeListener{
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                String bookDuration = (String) buttonView.getTag();
                if(isChecked){
                    selectedBooks.add(bookDuration);
                }else{
                    selectedBooks.remove(bookDuration);
                }
            }
    }


    public MylibmanList(Activity a, ArrayList<HashMap<String, String>> d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    static class ViewHolder {
        TextView title;
        TextView artist;
        TextView duration;
        CheckBox check;
    }


    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView==null){
            convertView = inflater.inflate(R.layout.listrow_row, null);

            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.artist = (TextView) convertView.findViewById(R.id.artist);
            holder.duration = (TextView) convertView.findViewById(R.id.duration);
            holder.check = (CheckBox) convertView.findViewById(R.id.check);


            holder.check.setOnCheckedChangeListener(checkChangedListener);

            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }


        HashMap<String, String> book = new HashMap<String, String>();
        book = (HashMap<String, String>) getItem(position);

        holder.check.setTag(book.get(ShowList.LIST_KEY_ID));

        holder.title.setText(book.get(ShowList.LIST_KEY_NAME));
        holder.artist.setText(book.get(ShowList.LIST_KEY_WRITER));
        holder.duration.setText(book.get(ShowList.LIST_KEY_ID));

        boolean bookSelected = false;
        if(selectedBooks.contains(book.get(ShowList.LIST_KEY_ID))){
            bookSelected = true;
        }

        holder.check.setChecked(bookSelected);

        return convertView;
    }

I've changed your getView abit. The viewHolder will now be created only once for each view (as it should). Also, if its not too much of a hustle, you should create a class for your book. Something like

Class Book{
    String title;
    String artist;
    Long duration;
}

Upvotes: 1

Related Questions