Search code examples
androidlistviewhashmapcustom-adapter

Using hashMaps in custom adapters for listView


The following is the code that I am currently using for a listView:

private class Asyncprojectlist extends AsyncTask<Void, Void, Void>{
        JSONArray JSar;
        JSONObject JSob;
        String project_title, project_sector;
        @Override
        protected void onPreExecute() {
            progressDialog =  new ProgressDialog(Allprojects.this);
            progressDialog.setCancelable(false);
            progressDialog.setMessage("Loading...");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setProgress(0);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            UserFunctions user = new UserFunctions();
            JSob = user.allprojects();
            try {
                JSar = JSob.getJSONArray("data");

            } catch (JSONException e1) {
                e1.printStackTrace();
            }
            for(int i=0; i<JSar.length(); i++){
                try {
                    JSONObject newobj = JSar.getJSONObject(i);
                    project_title = newobj.getString("title");
                    project_sector = newobj.getString("sector");

                    HashMap<String, String> single = new HashMap<String, String>();
                    single.put("title", project_title);
                    single.put("sector", project_sector);

                    all_list.add(single);

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
//          Log.i("json object", JSar.toString());
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            ListAdapter adapter = new SimpleAdapter(getApplicationContext(), all_list, R.layout.projectlist_frame, 
                    new String[]{"title","sector"}, new int[]{R.id.projecttitle, R.id.projectsector});
            setListAdapter(adapter);
            progressDialog.dismiss();
            list = getListView();
            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View viewClicked,
                        int position, long id) {

                    Intent toindividual = new Intent(Allprojects.this, Individual_project.class);
                    try {
                        toindividual.putExtra("nid", JSar.getJSONObject(position).getString("id"));
                        startActivity(toindividual);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });

}

Here the an api is being called upon to fetch data and the all_list is an ArrayList<HashMap<>> where it is used by the SimpleAdapter to assign values such as projectTitle and projectStatus on the listView layout. Everything here works perfectly. But I am having a hard time implementing the checkBox listener which is in the listView's layout. I believe that a custom adapter is needed. In my attempt to build a custom adapter I could not come up with a working code. Please help in implementing a custom adapter so that the listView can have the checkBox's CheckChangeListener implemented.


Solution

  • you can create a custome adapter for it. In this adapter you have to set CheckChangeListener on checkbox in getView method.

    public class MyBaseAdapter extends BaseAdapter {
    
        private Context mContext;
        private LayoutInflater mInflater;
    
        public MyBaseAdapter(Context context) {
    
            this.mContext = context;
            mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
    
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.row_layout, null);
    
                holder.txtName = (TextView) convertView.findViewById(R.id.textView1);
                holder.chkTick = (CheckBox) convertView.findViewById(R.id.checkBox1);
    
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
    
            final int pos = position;
            holder.txtName.setText("ABC");
            holder.chkTick.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if(isChecked) {
                        Toast.makeText(mContext, "Checked", Toast.LENGTH_SHORT).show(); 
                    }
                }
            });
    
            return convertView;
        }
    }
    

    You may also check this link1,link2 for more details

    You can use hashMap for custome adapter and set value in UI as follow

    public class HashMapAdapter extends BaseAdapter {
    
        private HashMap<String, String> mData = new HashMap<String, String>();
        private String[] mKeys;
        public HashMapAdapter(HashMap<String, String> data){
            mData  = data;
            mKeys = mData.keySet().toArray(new String[data.size()]);
        }
    
        @Override
        public int getCount() {
            return mData.size();
        }
    
        @Override
        public Object getItem(int position) {
            return mData.get(mKeys[position]);
        }
    
        @Override
        public long getItemId(int arg0) {
            return arg0;
        }
    
        @Override
        public View getView(int pos, View convertView, ViewGroup parent) {
            String key = mKeys[pos];
            String Value = getItem(pos).toString();
    
            //do your view stuff here
    
            return convertView;
        }
    }