Android ListView With Toggle Button Web Service

[亡魂溺海] 提交于 2020-01-02 07:51:10

问题


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);

        }

    }

回答1:


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



来源:https://stackoverflow.com/questions/8236603/android-listview-with-toggle-button-web-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!