GridView adapter duplicating when use EndlessScrollListener

223 views Asked by At

Hi i am having a fragment which loads data in json type from webservice and show that in the gridview(custom).In the first 16 items(Page 1), i have no problem but i when try to load page and add items to adapter some items duplicate :(

my code is:

fragment:

@SuppressLint("ValidFragment")
public class MainTabFragment extends Fragment {

    ProductArrayAdapter adapter;
    LinearLayout baseLoading;

    int lastpage = 1;
    int totalpages = 0;

    boolean loadingMore = false;
    boolean isFirstTime = true;

    RelativeLayout listFooterLoading;
    com.goldenapps.iran14.GridView grdProducts;
    GifDecoderView view;
    ImageButton imgbtnConnectionLost;

    public static final String CATEGORY_VIP = "vip";
    public static final String CATEGORY_EMG = "fori";

    String curentCat = "";

    //Banner data
    LinearLayout lytBanner;
    ImageView imgBanner;

    int bannerId = 0;
    String bannerThumbnail = "";
    String bannerContent = "";
    String bannerUrl = "";
    String bannerBGcolor = "";

    public MainTabFragment() {
        bannerId = 1;
    }

    public MainTabFragment(String _currentCat) {
        this.curentCat = _currentCat;

        if(this.curentCat.equals("")){
            bannerId = 1;
        }else if(this.curentCat.equals(CATEGORY_EMG)){
            bannerId = 2;
        }else if(this.curentCat.equals(CATEGORY_VIP)){
            bannerId = 3;
        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        baseLoading = (LinearLayout) rootView.findViewById(R.id.baseLoading);

        grdProducts = (com.goldenapps.iran14.GridView) rootView.findViewById(R.id.grdProducts);
        grdProducts.setOnScrollListener(new EndlessScrollListener(0));
        grdProducts.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                // TODO Auto-generated method stub

                Product p =  adapter.getList().get(arg2);
                ArrayList<Product> arrp = new ArrayList<Product>();
                arrp.add(p);

                Intent intent = new Intent(getActivity(), OtherActivity.class);

                Bundle b = new Bundle();

                b.putParcelableArrayList("Product", arrp);

                if(!p.getImageviewUrl().equals("")){

                    b.putString("ImageUrl", p.getImageviewUrl());

                }else if(p.getImages().size() > 0){

                    b.putString("ImageUrl", p.getImages().get(0));

                }else{
                    b.putString("ImageUrl", "");
                }

                b.putInt(OtherActivity.FRAGMENT_TYPE, OtherActivity.FRAGMENT_TYPE_PRODUCTVIEW);

                intent.putExtras(b);

                getActivity().startActivity(intent);

            }

        }); 

        LayoutInflater inflinflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View banner = inflinflater.inflate(R.layout.layout_top_banner, null);



//      String[] colors = getActivity().getResources().getStringArray(R.array.iran14_banner_colors);        
//      Random rand = new Random();                 
        LinearLayout lytBanner = (LinearLayout) banner.findViewById(R.id.lytBanner);
//      lytBanner.setBackgroundColor(Color.parseColor(colors[rand.nextInt(colors.length)]));
        imgBanner = (ImageView) banner.findViewById(R.id.imgBanner);

        grdProducts.addHeaderView(banner);

        //Footer loading
        listFooterLoading = (RelativeLayout) rootView.findViewById(R.id.lytLoading);
        listFooterLoading.addView(Globals.getFooterLoading(getActivity()));

        isStarting();

        new LoadBannerDataTask(lytBanner).execute(bannerId);

        return rootView;
    }

    /**
     * Load products task
     * @author Server
     *
     */
    private class LoadContentsAsync extends AsyncTask<Integer, Void, Boolean>{

        //Dialog d;
        String err = "";
        //View loadingView;
        ArrayList<Product> tmpProducts = new ArrayList<Product>();

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

            if(lastpage <= 2){

                baseLoading.setVisibility(View.VISIBLE);                

            }

            loadingMore = true;

        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            // TODO Auto-generated method stub



            JSONObject responseObject = null;


            String jsonText = "";

            if(!curentCat.equals("")){
                jsonText = JsonConnections.getCategoryItemsFromServer(curentCat, params[0], false, getActivity()).trim();
            }else{
                jsonText = JsonConnections.getDataFromServer(params[0],false,getActivity()).trim();
            }

            if(jsonText == null){
                return false;
            }

            if(jsonText.equals("")){
                return false;
            }

            if(!Globals.isJSON(jsonText)){
                return false;
            }


            try{
                jsonText = jsonText.replaceAll("\n", "\\n");
                responseObject = new JSONObject(jsonText);

                if(!responseObject.getString("status").equals("ok")){

                    if(responseObject.has("error")){
                        err =  responseObject.getString("error");
                    }else{
                        err += "موردی یافت نشد";
                    }

                    return false;
                }else{

                    if(responseObject.has("pages")){
                        totalpages = responseObject.getInt("pages");
                    }

                    if(responseObject.has("count")){

                        int c =  responseObject.getInt("count");

                        if(c < 1){

                            err += "موردی یافت نشد";
                            return false;

                        }

                    }

                }

                JSONArray posts = responseObject.getJSONArray("posts");

                for(int i = 0; i < posts.length() ; i++){

                    JSONObject obj = posts.getJSONObject(i);

                    Product p = new Product();

                    p.setId(obj.getInt("id"));
                    p.setTitle((String) obj.get("title"));
                    p.setUrl((String) obj.get("url"));
                    p.setDate(((String) obj.get("date")).split(" ")[0]);
                    p.setTime(((String) obj.get("date")).split(" ")[1]);

                    if(obj.has("thumbnail_images")){

                        JSONObject objImageView = obj.getJSONObject("thumbnail_images");
                        if(objImageView != null){
                            if(objImageView.has("url")){
                                p.setImageviewUrl(objImageView.getString("url"));
                            }
                        }
                    }


                    ArrayList<String> images = new ArrayList<String>();
                    if(obj.has("thumbnail")){
                        if(obj.get("thumbnail") != null){
                            images.add((String) obj.get("thumbnail"));
                        }

                    }

                    //شاخه ها
                    if(obj.has("categories")){
                        JSONArray arrCategories = obj.getJSONArray("categories");



                        if(arrCategories != null){
                            if(arrCategories.length() > 0){

                                for(int j=0; j<arrCategories.length(); j++){

                                    JSONObject objCat = arrCategories.getJSONObject(j);

                                    if(objCat.getString("slug").equals(Product.TAG_VIP)){
                                        p.setType(Product.TYPE_VIP);
                                        break;

                                    }else if(objCat.getString("slug").equals(Product.TAG_FORI)){
                                        p.setType(Product.TYPE_FORI);
                                        break;
                                    }
                                }


                            }
                        }                       
                    }

                    p.setImages(images);

                    Log.i("Product", p.getTitle() + " , type= " + p.getType());

                    tmpProducts.add( p );


                }


                return true;


            }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                err += "خطا در ارتباط با سرور";
            }

            return false;
        }

        protected void onPostExecute(Boolean done){

            loadingMore = false;

            if(lastpage <= 2){
                baseLoading.setVisibility(View.GONE);
            }else{
                listFooterLoading.setVisibility(View.GONE);
            }

            if(done){

                if(isFirstTime){

                    isFirstTime = false;

                    adapter =  new ProductArrayAdapter(getActivity(), tmpProducts, Product.NORMAL, null);

                    grdProducts.setAdapter(adapter);
                }else{

                    for(Product p : tmpProducts){
                        adapter.add(p);
                    }

                }


                adapter.notifyDataSetChanged();
            }else{
                if(err.equals("")){
                    Globals.showMessage(getActivity(), "خطا");
                }else{
                    Globals.showMessage(getActivity(), err);
                }


            }

            if(adapter != null){
                if(adapter.getCount() > 0){
                    new DownloadImageTask(null).execute(new String[]{""});
                }
            }

        }


    }

    /**
     * Load products task
     * @author Server
     *
     */
    private class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {


          public DownloadImageTask(ImageView bmImage) {

          }

          protected Bitmap doInBackground(String... urls) {

              Bitmap mIcon11 = null;

              ArrayList<Product> tmplist = adapter.getList();

              int min = 0;

              if(tmplist.size() > 16){
                  min = tmplist.size()-16; 
              }

              for(int i=min ; i < tmplist.size() ; i++) {

                    if(tmplist.get(i) != null){

                        try{

                            if(tmplist.get(i).getImages().size() <= 0){
                                continue;
                            }

                            if(tmplist.get(i).getImages().get(0).equals("")){
                                continue;
                            }

                            InputStream in = new java.net.URL(tmplist.get(i).getImages().get(0)).openStream();
                            mIcon11 = BitmapFactory.decodeStream(in);

                            if(mIcon11 != null){
                                tmplist.get(i).setMainImage(mIcon11);
                            }

                        }catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        publishProgress(0);
                    }

                }

              return null;
          }

          protected void onPostExecute(Bitmap result) {
//            bmImage.setImageBitmap(result);
          }


        protected void onProgressUpdate(Integer... progress){
            adapter.notifyDataSetChanged();
            super.onProgressUpdate(progress[0]);
        }


    }

    private boolean isStarting(){

        InputStream stream = null; 
        try { 
            stream = getActivity().getAssets().open("loading.gif"); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
        view = new GifDecoderView(getActivity(), stream); 

        baseLoading.removeAllViews();

        baseLoading.addView(view);

        if(lastpage <=1 ){
            baseLoading.setVisibility(View.VISIBLE);
        }else{
            baseLoading.setVisibility(View.GONE);
        }


        if(Globals.isNetworkOnline(getActivity())){

            new LoadContentsAsync().execute(lastpage++);
            return true;

        }else{

            baseLoading.setVisibility(View.GONE);

            imgbtnConnectionLost = new ImageButton(getActivity());
            imgbtnConnectionLost.setImageDrawable(getActivity().getResources().getDrawable(R.drawable.connection_lost_icon));
            imgbtnConnectionLost.setBackgroundColor(Color.TRANSPARENT);

            baseLoading.removeAllViews();

            baseLoading.addView(imgbtnConnectionLost);
            baseLoading.setVisibility(View.VISIBLE);

            imgbtnConnectionLost.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    isStarting();
                }
            });
        }

        return true;

    }

    private class EndlessScrollListener implements OnScrollListener {

        private int visibleThreshold = 5;
        private int previousTotal = 0;
        private boolean loading = true;

        public EndlessScrollListener(int visibleThreshold) {
            this.visibleThreshold = visibleThreshold;
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (loading) {

                if (totalItemCount > previousTotal) {
                    loading = false;
                    previousTotal = totalItemCount;
                }

            }

            if (firstVisibleItem + visibleItemCount == totalItemCount) {

                // last item in grid is on the screen, show footer:
                if(lastpage <= totalpages && totalpages > 0){
                    listFooterLoading.setVisibility(View.VISIBLE);
                }

            } else if (listFooterLoading.getVisibility() != View.GONE) {

                // last item in grid not on the screen, hide footer:
                listFooterLoading.setVisibility(View.GONE);
            }

            if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
                // I load the next page of gigs using a background task,
                // but you can call any function here.

                if(lastpage > totalpages && totalpages > 0){

                    return;

                }

                new LoadContentsAsync().execute(lastpage++);

                loading = true;


            }



        }

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

    }



    /**
     * Load products task
     * @author Server
     *
     */
    private class LoadBannerDataTask extends AsyncTask<Integer, Void, Boolean>{

        LinearLayout lytBanner;

        public LoadBannerDataTask(LinearLayout _lytBanner){
            this.lytBanner = _lytBanner;
        } 

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

        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            // TODO Auto-generated method stub

            JSONObject responseObject = null;


            String jsonText = "";

            jsonText = JsonConnections.getBannerDataFromServer(params[0], getActivity()).trim();

            if(jsonText == null){
                return false;
            }

            if(jsonText.equals("")){
                return false;
            }

            if(!Globals.isJSON(jsonText)){
                return false;
            }

            try{
                jsonText = jsonText.replaceAll("\n", "\\n");
                responseObject = new JSONObject(jsonText);

                JSONArray arrBanner = responseObject.getJSONArray("banners");

                JSONObject bannerObj = arrBanner.getJSONObject(0);



                bannerThumbnail = bannerObj.getString("thumbnail");
                bannerContent = bannerObj.getString("content");
                bannerUrl = bannerObj.getString("url");
                bannerBGcolor = bannerObj.getString("bgcolor");

                return true;


            }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }

            return false;
        }

        protected void onPostExecute(Boolean done){



            loadingMore = false;

            this.lytBanner.setBackgroundColor(Color.parseColor(bannerBGcolor));

            if(bannerThumbnail != null){
                if(!bannerThumbnail.equals("")){
                    new DownloadBannerImageTask().execute(new String[]{bannerThumbnail});
                }
            }

        }

    }

    /**
     * Load products task
     * @author Server
     *
     */
    private class DownloadBannerImageTask extends AsyncTask<String, Integer, Bitmap> {


          protected Bitmap doInBackground(String... urls) {

              Bitmap mIcon11 = null;


              try{

                  InputStream in = new java.net.URL(urls[0]).openStream();
                  mIcon11 = BitmapFactory.decodeStream(in);

              }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
              }



              return mIcon11;
          }

          protected void onPostExecute(Bitmap result) {
              imgBanner.setImageBitmap(result);
          }


    }

}
1

There are 1 answers

1
Haresh Chhelana On

Try to replace this peace of code :

if(isFirstTime){
    isFirstTime = false;
    adapter =  new ProductArrayAdapter(getActivity(), tmpProducts, Product.NORMAL, null);
    grdProducts.setAdapter(adapter);
 }else{
    adapter.notifyDataSetChanged();
 }

You have already add new data to tmpProducts which reference is use to show list item just notify adapter after new data.