Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ListView With Toggle Button Web Service

The problem is,onCheckedChange() methods get called repeatedly and the phone runs out of memory. When I take the calls to the AsyncTask out of the checkedChange method it works fine. Or if I take the setChecked() calls out it works fine as well. But I have to have those methods in there for this portion of the application to make sense. The WebService calls are super short but have to be toggled from the Toggle button.

I would like you to share some of your thoughts and opinions.

private class ItemAdapter extends ArrayAdapter<FavItem> {

        private final ArrayList<FavItem> cats;
        public int count;

        // private Context m;
        public ItemAdapter(Context context, int textViewResourceId,
                ArrayList<FavItem> myItems) {
            super(context, textViewResourceId, myItems);
            this.cats = myItems;
            // this.m = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;

            if (v == null) {
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                // LayoutInflater vi = getLayoutInflater();
                v = vi.inflate(R.layout.favitem, null);
            }
            final FavItem o = cats.get(position);
            if (o != null) {

                TextView title = (TextView) v.findViewById(R.id.textViewNear1);
                TextView sub = (TextView) v.findViewById(R.id.textViewNear2);
                final ToggleButton text = (ToggleButton) v
                        .findViewById(R.id.texttoggle);
                final ToggleButton email = (ToggleButton) v
                        .findViewById(R.id.emailtoggle);
                text.setChecked(o.getFav_sms() == 1 ? true : false);
                email.setChecked(o.getFav_email() == 1 ? true : false);
                title.setText(o.getBusiness_name());
                sub.setText(o.getDeal_name());

                text.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton cText,
                            boolean textCheck) {
                        count++;
                        int uText = text.isChecked() ? 1 : 0;
                        int uEmail = email.isChecked() ? 1 : 2;
                        int id = o.getObject_id();
                        String catURL = "https://example.com/?fn=myfavs&a=add&ot=2&oid="
                                + id + "&f1=" + uText + "&f2=" + uEmail;
                        UpdateFavs u = new UpdateFavs();
                        u.execute(catURL);
                        log("URL" + catURL);

                        log("count: " + count);
                    }
                });
                email.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton cEmail,
                            boolean emailChecked) {
                        int id = o.getObject_id();
                        count++;
                        int uText = text.isChecked() ? 1 : 0;
                        int uEmail = email.isChecked() ? 1 : 2;
                        String catURL = "https://example.com/?fn=myfavs&a=add&ot=2&oid="
                                + id + "&f1=" + uText + "&f2=" + uEmail;
                        UpdateFavs u = new UpdateFavs();
                        u.execute(catURL);
                        log("URL" + catURL);

                        log("count: " + count);
                    }

                });

            }
            return v;
        }

    }

private class UpdateFavs extends AsyncTask<String, Void, String> {
        InputStream is;
        String result;

        @Override
        protected void onPreExecute() {
            pBar.setVisibility(View.VISIBLE);
        }

        @Override
        protected String doInBackground(String... id) {
            try {

                // final String catURL =
                // "https://example.com/?fn=myfavs&a=add&ot=2&oid="
                // + "&f1=" + uText + "&f2=" + uEmail;
                String catURL = id[0];

                DefaultHttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(catURL);
                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                nameValuePairs.add(new BasicNameValuePair("ID",
                        getCookie()));

                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                httpclient.execute(httppost);

            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            pBar.setVisibility(View.GONE);

        }

    }
like image 518
JakeWilson801 Avatar asked Feb 21 '26 13:02

JakeWilson801


1 Answers

First of all let your ItemAdapter class implement OnCheckedChangeListener. In your code, a new listener will be instantiated every time the list is scrolled. Also, since the views have a listener set on them, the listener's onCheckedChanged() method will be called every time you scroll. I suggest trying this :

private class ItemAdapter extends ArrayAdapter<FavItem> implements OnCheckedChangeListener {     
 private final ArrayList<FavItem> cats;        
 public int count;     
 // private Context m;

private Holder holder;

public ItemAdapter(Context context, int textViewResourceId, ArrayList myItems) { super(context, textViewResourceId, myItems); this.cats = myItems; // this.m = context; } @Override public View getView(int position, View convertView, ViewGroup parent) {

          if (convertView == null) { 
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             // LayoutInflater vi = getLayoutInflater(); 
            v = vi.inflate(R.layout.favitem, null);
holder=new Holder();
holder.title= (TextView) v.findViewById(R.id.textViewNear1);
holder.text= (ToggleButton) v.findViewById(R.id.texttoggle);
holder.sub= (TextView) v.findViewById(R.id.textViewNear2); 
holder.email= (ToggleButton) v .findViewById(R.id.emailtoggle);
convertView.setTag(holder)
         }else{
holder=convertView.getTag();
         }
         final FavItem o = cats.get(position);
         if (o != null) {
holder.text.setTag(position);
holder.email.setTag(position);
              //first remove any listener already present
            holder. text..setOnCheckedChangeListener(null);
            holder. email.setOnCheckedChangeListener(null);
//you can now set checked state. we already removed the listener, so it will not trigger the checkd change call
              holder. text.setChecked(o.getFav_sms() == 1 ? true : false);
             holder.email.setChecked(o.getFav_email() == 1 ? true : false);
             holder.title.setText(o.getBusiness_name());
             holder.sub.setText(o.getDeal_name());
//set the listener to the views now. ( so that check events will only be triggerde manually by user and not by scrolling the lsit
holder. text.setOnCheckedChangeListener(this);
 holder.email.setOnCheckedChangeListener(this);
return convertView;
}

class Holder{
     TextView title ,sub ;
     ToggleButton text,email;
  }

@Override
   public void onCheckedChanged(CompoundButton b,boolean emailChecked) { 
int position=(Integer)b.getTag(); //now you know position of button in list.
switch(b.getId(){
    case R.id.texttoggle: //toggle button
       //do whatever you want
       break;
     case R.id.emailtoggle:
        //do whatever you want
        break; 
}

   }

removing listener every time before setting the item checked will do the trick. Do notice the way holder class is used. This reduces the number of times findViewById() is called from getView() method. Hope this helps

like image 64
rDroid Avatar answered Feb 23 '26 01:02

rDroid