Search code examples
javaandroidarraylistandroid-volleyandroid-sharedpreferences

How can I make sharedpreferences in Custom Adapter get the latest values of my ArrayList?


I use Volley in the onCreate of my Activity which gets a string on my server, then I convert this string to an arraylist,checkedContactsAsArrayList, and I pass it over to my custom adapter using sharedpreferences, which does stuff with the arraylist in the listview.

But the custom adapter keeps getting the previous arraylist in sharedpreferences, not the one I've just got from the server. The Volley call is too late or something - I can see in logcat the latest values are put after they are got, if you know what I mean.

For example:

VolleyCall 1 putString: 1,2,3
VolleyCall 2 putString: 4,5,6
VolleyCall 3 putString: 7,8,9

Custom Adapter 1 getString: gets values of the last time app was used
Custom Adapter 2 getString: 1,2,3
Custom Adapter 3 getString: 4,5,6

Any idea how to fix this? I could try doing the Volley call in the getView of my custom adapter but I've read on Stackoverflow that's bad practice.

Here are the relvant parts of my code - I've slimmed it down a bit, as there's a lot of stuff in there irrelevant to this issue.

Here's the code of my activity, ViewContact:

public class ViewContact extends AppCompatActivity implements android.widget.CompoundButton.OnCheckedChangeListener  {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(activity_view_contact);


        //selectPhoneContacts is an empty array list that will hold our SelectPhoneContact info
        selectPhoneContacts = new ArrayList<SelectPhoneContact>();


        listView = (ListView) findViewById(R.id.listviewPhoneContacts);


        StringRequest stringRequest = new StringRequest(Request.Method.POST, ViewContact_URL,
                new Response.Listener<String>() {

                    @Override
                    public void onResponse(String response) {

                        //toast the response of ViewContact.php, which has been converted to a
                        //JSON object by the Php file with JSON encode
                        Toast.makeText(ViewContact.this, "OnResponse is" + response, Toast.LENGTH_LONG).show();
                        System.out.println("ViewContact: And the response is " + response);


                        try {

                            //checkedContacts is a String
                            String checkedContacts = responseObject.getString("checkedcontacts");

                            //convert the checkedContacts string to an arraylist

                            checkedContactsAsArrayList = new ArrayList<String>(Arrays.asList(checkedcontacts.split(",")));
                            System.out.println("ViewContact: checkedContactsAsArrayList is " + checkedContactsAsArrayList);


                            //we want to bring the checkedContactsAsArrayList array list to our SelectPhoneContactAdapter.
                            // It looks like Shared Preferences
                            //only works easily with strings so best way to bring the array list in Shared Preferences is with
                            //Gson.
                            //Here, we PUT the arraylist into the sharedPreferences

                    SharedPreferences sharedPreferencescheckedContactsAsArrayList = PreferenceManager.getDefaultSharedPreferences(getApplication());
                    SharedPreferences.Editor editorcheckedContactsAsArrayList = sharedPreferencescheckedContactsAsArrayList.edit();
                    Gson gsoncheckedContactsAsArrayList = new Gson();
                    String jsoncheckedContactsAsArrayList = gsoncheckedContactsAsArrayList.toJson(checkedContactsAsArrayList);
                    editorcheckedContactsAsArrayList.putString("checkedContactsAsArrayList", jsoncheckedContactsAsArrayList);
                    editorcheckedContactsAsArrayList.commit();
                    System.out.println("ViewContact: jsoncheckedContactsAsArrayList is " + jsoncheckedContactsAsArrayList);


                        } catch (JSONException e) {
                            e.printStackTrace();
                            Toast.makeText(getApplicationContext(),
                                    "Error: " + e.getMessage(),
                                    Toast.LENGTH_LONG).show();
                        }



                    }

                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(ViewContact.this, error.toString(), Toast.LENGTH_LONG).show();

                    }

                }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                //we are posting review_id into our ViewContact.php file, which
                //we get when a row is clicked in populistolistview
                //to get matching details
                params.put("review_id", review_id);
                return params;

            }

        };
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);



    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        //checkBoxforContact.setChecked(true);


    }


    //******for the phone contacts in the listview

    // Load data in background
    class LoadContact extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... voids) {

            //we want to delete the old selectContacts from the listview when the Activity loads
            //because it may need to be updated and we want the user to see the updated listview,
            //like if the user adds new names and numbers to their phone contacts.
            selectPhoneContacts.clear();


                SelectPhoneContact selectContact = new SelectPhoneContact();


                selectContact.setName(phoneNameofContact);


            }


            return null;


        }


        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);




            adapter = new SelectPhoneContactAdapter(selectPhoneContacts, ViewContact.this,0);



            listView.setAdapter(adapter);


            adapter.notifyDataSetChanged();


        }
    }


    @Override
    protected void onResume() {

        super.onResume();

        // getPrefs();

        ViewContact.LoadContact loadContact = new ViewContact.LoadContact();


        loadContact.execute();

        Toast.makeText(ViewContact.this, "resuming!", Toast.LENGTH_SHORT).show();


    }

}

And my custom adapter, SelectPhoneContactAdapter :

public class SelectPhoneContactAdapter extends BaseAdapter {

//define a list made out of SelectPhoneContacts and call it theContactsList
public List<SelectPhoneContact> theContactsList;
//define an array list made out of SelectContacts and call it arraylist
private ArrayList<SelectPhoneContact> arraylist;
Context _c;
ArrayList<String> MatchingContactsAsArrayList;
ArrayList<String> checkedContactsAsArrayList;
ArrayList <String> allNamesofContacts;
String contactToCheck;
//we will run through different logic in this custom adapter based on the activity that is passed to it
private int whichactivity;

String phoneNumberofContact;
String[] phoneNumberofContactStringArray;
String ContactsString;

Intent intent;


public SelectPhoneContactAdapter(final List<SelectPhoneContact> selectPhoneContacts, Context context, int activity) {
    theContactsList = selectPhoneContacts;
    _c = context;
    this.arraylist = new ArrayList<SelectPhoneContact>();
    this.arraylist.addAll(theContactsList);
    whichactivity = activity;


    //we are fetching the array list checkedContactsAsArrayList, created in ViewContact.
    //with this we will put a tick in the checkboxes of contacts the review is being shared with

    SharedPreferences sharedPreferencescheckedContactsAsArrayList = PreferenceManager.getDefaultSharedPreferences(_c);
    Gson gsoncheckedContactsAsArrayList = new Gson();
    String jsoncheckedContactsAsArrayList = sharedPreferencescheckedContactsAsArrayList.getString("checkedContactsAsArrayList", "");
    Type type2 = new TypeToken<ArrayList<String>>() {
    }.getType();
    checkedContactsAsArrayList = gsoncheckedContactsAsArrayList.fromJson(jsoncheckedContactsAsArrayList, type2);
    System.out.println("SelectPhoneContactAdapter checkedContactsAsArrayList :" + checkedContactsAsArrayList);

                                 }
}



@Override
public int getCount() {
    return arraylist.size();
}

@Override
public Object getItem(int i) {
    return arraylist.get(i);
}

@Override
public long getItemId(int i) {
    return i;
}



static class ViewHolder {
    //In each cell in the listview show the items you want to have
    //Having a ViewHolder caches our ids, instead of having to call and load each one again and again
    TextView title, phone;
    CheckBox check;
    Button invite;
}


@Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {


    //this is the SelectPhoneContact object; consists of textboxes, buttons, checkbox
    final SelectPhoneContact data = (SelectPhoneContact) arraylist.get(i);

    ViewHolder holder = null;

    if (convertView == null) {

        //if there is nothing there (if it's null) inflate the view with the layout
        LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = li.inflate(R.layout.phone_inflate_listview, null);

        holder = new ViewHolder();
        //So, for example, title is cast to the name id, in phone_inflate_listview,
        //phone is cast to the id called no etc
        holder.title = (TextView) convertView.findViewById(R.id.name);
        holder.phone = (TextView) convertView.findViewById(R.id.no);
        holder.invite = (Button)  convertView.findViewById(R.id.btnInvite);
        holder.check = (CheckBox) convertView.findViewById(R.id.checkBoxContact);


        convertView.setTag(holder);

    } else {

        holder = (ViewHolder) convertView.getTag();

    }


    //in the listview for contacts, set the name
    holder.title.setText(data.getName());

    //in the listview for contacts, set the number
    holder.phone.setText(data.getPhone());




    holder.check.setTag(data);

    return convertView;

    }

}

Solution

  • Call this: loadContact.execute(); After you call .commit();

    ViewContact.LoadContact loadContact = new ViewContact.LoadContact();
    loadContact.execute();