1

I have a custom arrayAdapter that fills a listView. When I first load the listActivity, the information that was loaded from a AsyncTask loads correctly without any duplicates.

no duplicates on initial activity load

On that same activity I use the search field in the ActionBar but for some reason when I display the results using the same arrayAdapter the results are always duplicated and even tripled sometimes.

duplicate views

I've double and triple checked the answers on this site and other sites but can't seem to come up with a valid solution. If you don't have a full solution maybe you could possibly nudge me in the right direction. Here is my arrayAdapter:

public class JobsAdapter extends ArrayAdapter<String> {

     public static LayoutInflater inflater = null;
     public ArrayList<HashMap<String, String>> jobList;
     public String jobId;
     public Context context;
     public int layoutResourceId;


    public static class ViewHolder {

        TextView jid;
        TextView jid2;
        TextView jcn;
        TextView jd;
        TextView js;

      }

    public JobsAdapter(Context context, int layoutResourceId){

        super(context, layoutResourceId);
        this.context = context;
    }

    public JobsAdapter(Context context, int layoutResourceId, ArrayList<HashMap<String, String>> jobList){

        super(context, layoutResourceId);
        this.context = context;
        this.jobList = jobList;
    }

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

    public Item getItem(Item position) {
        return position;
    }

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

    @Override
    public boolean hasStableIds() {
        return true;
    }


    public View getView(int position, View convertView, ViewGroup parent) {     
        ViewHolder holder;
        View v = convertView;

        if(v == null)
        {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.list_edit_job_item, parent, false);
            holder = new ViewHolder();
            holder.jid = (TextView) v.findViewById(R.id.jobid);
            holder.jid2 = (TextView) v.findViewById(R.id.jobID);
            holder.jcn = (TextView) v.findViewById(R.id.jobClientName);
            holder.jd = (TextView) v.findViewById(R.id.jobDescription);
            holder.js = (TextView) v.findViewById(R.id.jobStatus);

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

        HashMap<String, String> i = jobList.get(position);

        String sjid = i.get("jobID");
        String sjid2 = i.get("jobID");
        String sjcn = i.get("clientName");
        String sjd = i.get("description");
        String sjs = i.get("status");

        if(holder.jid != null)
            {
                holder.jid.setText(sjid);
            }
        if(holder.jid2 != null)
            {
                holder.jid2.setText(sjid2);
            }
        if(holder.jcn != null)
            {
                holder.jcn.setText(sjcn);
            }
        if(holder.jd != null)
            {
                holder.jd.setText(sjd);
            }
        if(holder.js != null)
            {
                holder.js.setText(sjs);
            }

        return v;


    }

    public void updateList(ArrayList<HashMap<String, String>> newJobList) {
        jobList.addAll(newJobList);
        this.notifyDataSetChanged();
    }

    public void addAllItems(ArrayList<HashMap<String, String>> newJobList) {
        jobList.clear();
        jobList.addAll(newJobList);
        this.notifyDataSetChanged();
    }


    @Override

    public int getViewTypeCount() {                 

        return getCount();
    }

    @Override
    public int getItemViewType(int position) {

        return position;
    }

}

And here is my main activity:

public class DisplayEditJobs extends ListActivity implements OnScrollListener, OnQueryTextListener {


    private static final String TAG_JOB_JOBID = "jobID";
    private static final String TAG_JOB_CLIENTID = "clientID"; 
    private static final String TAG_JOB_CLIENT_NAME = "clientName";
    private static final String TAG_JOB_TITLE = "clientID";
    private static final String TAG_JOB_STATUS = "status";
    private static final String TAG_JOB_DATE_CREATED = "date_created";
    private static final String TAG_JOB_NOTES = "notes";   
    private static final String TAG_JOB_DESCRIPTION = "description";
    private static final String TAG_SUCCESS = "success";   
    private static final String TAG_JOBS = "jobs";

    Aleph0 adapter = new Aleph0();


    private ProgressDialog pDialog;
    public String jobID, userPermissions;
    public EditText notes, description, createdDate;
    public Spinner status, client;
    public Button AddJobButton, pickCreatedDateButton; 

    ArrayList<User> clientList;
    ArrayList<String> technicianIDList;
    List<String> labels;
    ActionBar actionBar;
    ListView lv;
    int success = 0 ;
    int page = 1;
    int currentPage = 1;
    int threshold = 3;

    private SearchView searchView;
    private static final String display_jobs_url = "http://com.tradeport.on.ca/view_all_jobs.php";
    String query = "";

    JSONParser jsonParser = new JSONParser();

    JSONArray user_session = null;
    int pagedefault = 1;
    JSONArray jobs = null;

    Button btnLoadMore;

    TextView pageid;
    int newpageid;
    public JobsAdapter myAdapter;
    ArrayList<HashMap<String, String>> jobsList;




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

        ActionBar actionBar = getActionBar();
        actionBar.setTitle("Choose a Job to Edit");
        actionBar.setDisplayHomeAsUpEnabled(true); 

        jobsList = new ArrayList<HashMap<String, String>>();
        myAdapter = new JobsAdapter(DisplayEditJobs.this, R.layout.list_edit_job_item, jobsList);
        getListView().setOnScrollListener(this); 
        new LoadAllJobs().execute();

        lv = getListView();

        lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

                String jobid = ((TextView) view.findViewById(R.id.jobid)).getText().toString();
                Intent in = new Intent(getApplicationContext(),Jobs.class);
                in.putExtra(TAG_JOB_JOBID, jobid);
                startActivityForResult(in, 100);
            }


        });



    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == 100) {

            Intent intent = getIntent();
            finish();
            startActivity(intent);
        }

    }

    class LoadAllJobs extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(DisplayEditJobs.this);
            pDialog.setMessage("Loading Jobs. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        protected String doInBackground(String... args) {

            SharedPreferences pref = getApplicationContext().getSharedPreferences("USER_SESSION", 0);
            String session_username = pref.getString("username", null);
            String session_key = pref.getString("key", null);



            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("tag", "view_all_jobs"));
            params.add(new BasicNameValuePair("username", session_username));
            params.add(new BasicNameValuePair("key", session_key ));
            params.add(new BasicNameValuePair("page", String.valueOf(page)));

            JSONObject json = jsonParser.makeHttpRequest(display_jobs_url, "POST", params);

            Log.d("All Instruments: ", json.toString());

            try {

                success = json.getInt(TAG_SUCCESS);

                if (success == 1) {

                    jobs = json.getJSONArray(TAG_JOBS);

                    for (int i = 0; i < jobs.length(); i++) {
                        JSONObject c = jobs.getJSONObject(i);

                        String jobid = c.getString(TAG_JOB_JOBID);
                        String clientName = c.getString(TAG_JOB_CLIENT_NAME);
                        String status = c.getString(TAG_JOB_STATUS);
                        String description = c.getString(TAG_JOB_DESCRIPTION);

                        HashMap<String, String> map = new HashMap<String, String>();

                        map.put(TAG_JOB_JOBID, jobid);
                        map.put(TAG_JOB_CLIENT_NAME, "Client : "+clientName);
                        map.put(TAG_JOB_STATUS, status);
                        map.put(TAG_JOB_DESCRIPTION, description);

                        jobsList.add(map);
                    }

                } else {

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

            return null;
        }

        protected void onPostExecute(String file_url) {


            pDialog.dismiss();
            Context context = getBaseContext();
            myAdapter = new JobsAdapter(context, R.layout.list_edit_job_item, jobsList);
            lv.setAdapter(myAdapter); 



        }

    }

    class updateJobs extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        protected String doInBackground(String... args) {

            jobs = null;
            success = 0;
            SharedPreferences pref = getApplicationContext().getSharedPreferences("USER_SESSION", 0);
            String session_username = pref.getString("username", null);
            String session_key = pref.getString("key", null);



            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("tag", "view_all_jobs"));
            params.add(new BasicNameValuePair("username", session_username));
            params.add(new BasicNameValuePair("key", session_key ));
            params.add(new BasicNameValuePair("page", String.valueOf(page)));

            JSONObject json = jsonParser.makeHttpRequest(display_jobs_url, "POST", params);

            Log.d("All Instruments: ", json.toString());

            try {

                if (success == 1) {
                    jobsList.clear();

                    jobs = json.getJSONArray(TAG_JOBS);

                    for (int i = 0; i < jobs.length(); i++) {
                        JSONObject c = jobs.getJSONObject(i);

                        String jobid = c.getString(TAG_JOB_JOBID);
                        String clientName = c.getString(TAG_JOB_CLIENT_NAME);
                        String status = c.getString(TAG_JOB_STATUS);
                        String description = c.getString(TAG_JOB_DESCRIPTION);

                        HashMap<String, String> map = new HashMap<String, String>();

                        map.put(TAG_JOB_JOBID, jobid);
                        map.put(TAG_JOB_CLIENT_NAME, "Client : "+clientName);
                        map.put(TAG_JOB_STATUS, status);
                        map.put(TAG_JOB_DESCRIPTION, description);

                        jobsList.add(map);
                    }

                } else {

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

            return null;
        }



        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) 
        {
            if(success == 1)
                { 
                    myAdapter.updateList(jobsList); 
                }
        }

    }


    class searchUpdateJobs extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();


        }

        /**
         * getting All products from url
         * */
        protected String doInBackground(String... args) {
            jobsList.clear();
            myAdapter.clear();
            jobs = null;
            success = 0;
            SharedPreferences pref = getApplicationContext().getSharedPreferences("USER_SESSION", 0);
            String session_username = pref.getString("username", null);
            String session_key = pref.getString("key", null);


            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("tag", "view_all_jobs"));
            params.add(new BasicNameValuePair("username", session_username));
            params.add(new BasicNameValuePair("key", session_key ));
            params.add(new BasicNameValuePair("keyword", query ));
            params.add(new BasicNameValuePair("page", String.valueOf(page)));

            JSONObject json = jsonParser.makeHttpRequest(display_jobs_url, "POST", params);


            try {

                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {

                    jobs = json.getJSONArray(TAG_JOBS);

                    for (int i = 0; i < jobs.length(); i++) {
                        JSONObject c = jobs.getJSONObject(i);

                        String jobid = c.getString(TAG_JOB_JOBID);
                        String clientName = c.getString(TAG_JOB_CLIENT_NAME);
                        String status = c.getString(TAG_JOB_STATUS);
                        String description = c.getString(TAG_JOB_DESCRIPTION);

                        HashMap<String, String> map = new HashMap<String, String>();

                        map.put(TAG_JOB_JOBID, jobid);
                        map.put(TAG_JOB_CLIENT_NAME, "Client : "+clientName);
                        map.put(TAG_JOB_STATUS, status);
                        map.put(TAG_JOB_DESCRIPTION, description);

                        jobsList.add(map);

                    }


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

            return null;
        }



        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {

            myAdapter.updateList(jobsList);   
        }

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.display_edit_instruments, menu);
        searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();        
        searchView.setOnQueryTextListener(this);
        searchView.setSubmitButtonEnabled(true);

        int id = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);

        TextView textView = (TextView) searchView.findViewById(id);
        textView.setTextColor(Color.WHITE);

        return true;
    }


    @Override
    public void onScroll(AbsListView view, int firstVisible,
            int visibleCount, int totalCount) {


    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

         if ((scrollState == SCROLL_STATE_IDLE) && (query.equals(""))) {
                if (lv.getLastVisiblePosition() >= lv.getCount() - 1 - threshold) {

                    final int index = lv.getFirstVisiblePosition();
                    View v = lv.getChildAt(0);
                    final int top = (v == null) ? 0 : v.getTop();

                    currentPage++;
                    page++;
                    new updateJobs().execute();
                    lv.setSelectionFromTop(index, top);



                }
            }

    }


    class Aleph0 extends BaseAdapter {
        int count = 10; 
        public int getCount() { return count; }
        public Object getItem(int pos) { return pos; }
        public long getItemId(int pos) { return pos; }

        public View getView(int pos, View v, ViewGroup p) {
            if(pos!=count-1)
            {
                TextView view = new TextView(DisplayEditJobs.this);
                view.setText("entry " + pos);
                return view;
            }
            TextView view = new TextView(DisplayEditJobs.this);
            view.setText("Loading.. " + pos);
            return view;

        }
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        if (!TextUtils.isEmpty(newText))
        {
          query = newText.toString();
          new searchUpdateJobs().execute();

         }

        return false;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }


}
Trig3rz
  • 174
  • 11

1 Answers1

1

After doing more digging and testing I found a quick workaround. It's probably not the best solution as I reset the adapter each time the class is called like so

protected void onPostExecute(String file_url) {
        HashSet<HashMap<String, String>> unique = new HashSet<HashMap<String, String>>();
        unique.addAll(jobsList);
        jobsList.clear();
        jobsList.addAll(unique);   

        //this resets the adapter   

        myAdapter = new JobsAdapter(DisplayEditJobs.this, R.layout.list_edit_job_item, jobsList);
        lv.setAdapter(myAdapter); 
    }

I'm sure this is more resource consuming than an actual update method. I'm open to any suggestions if anyone has any ideas.

Trig3rz
  • 174
  • 11