rookieDeveloper
rookieDeveloper

Reputation: 2468

ListView repeating the data on load more

I am using on scroll to load more data and show them in list view but my ListView first shows already loaded data then adds the newly added data to ListView

I have used for reference this and many others but unable to solve the issue

Here is my activity class

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_all);
        ButterKnife.bind(this);

        Users = Users.getCurrentUser(this);

        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        UIUtility.setStatusColor(this);

        Intent intent = getIntent();
        try {
            entityData = new JSONArray(intent.getStringExtra(EXTRA_DATA));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        viewAllCategory = intent.getIntExtra(EXTRA_CATEGORY, 0);
        viewAllEntityType = intent.getIntExtra(EXTRA_TYPE, 0);
        latitude = intent.getDoubleExtra(EXTRA_LATITUDE, 0);
        longitude = intent.getDoubleExtra(EXTRA_LONGITUDE, 0);

        setTitle(TITLES[viewAllCategory]);

        if (viewAllEntityType == Constants.SMBEntityType.TYPE_USER) {
            List<Users> users = Utility.convertJsonArrayToUsers(entityData);
            adapterUser = new ViewAllUserAdapter(this, users);
            lvEntity.setAdapter(adapterUser);
        }   else {
            List<Book> books = Utility.convertJsonArrayToBook(entityData);
            adapterBook = new ViewAllBookAdapter(this, books);
            lvEntity.setAdapter(adapterBook);
        }   
        lvEntity.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (!stopLoadingMore) {
                    if (totalItemCount == firstVisibleItem + visibleItemCount && !isLoading) {  
                        isLoading = true;
                        showLoading();
                        loadMoreData();
                    }
                }
            }
        });
    }

    private void loadMoreData() {
        String loadMoreUrl = buildLoadMoreUrl();
        ShareMyBookHttpClient client = new ShareMyBookHttpClient();
        client.get(loadMoreUrl, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                hideLoading();
                if (responseBody != null) {
                    start = start+20;
                    try {
                        JSONObject jo = new JSONObject(new String(responseBody));
                        if (!jo.getBoolean(Constants.JsonKeys.ERROR)) {
                            JSONArray data = jo.getJSONArray(Constants.JsonKeys.DATA);
                            if (data.length() == 0) {
                                stopLoadingMore = true;
                                return;
                            }
                            if (data.length() < 20) {
                                stopLoadingMore = true;
                            }
                            for (int i = 0; i < data.length(); i++) {
                                entityData.put(data.getJSONObject(i));
                            }
                            if (viewAllEntityType == Constants.SMBEntityType.TYPE_USER) {
                                List<Users> users = Utility.convertJsonArrayToUsers(entityData);
                                adapterUser.mergeArray(users);
                            } else {
                                List<Book> books = Utility.convertJsonArrayToBook(entityData);
                                adapterBook.mergeArray(books);
                            }
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                hideLoading();
            }
        });
    }

    private String buildLoadMoreUrl() {
        switch (viewAllCategory) {
            default:
            case ViewAllCategory.CATEGORY_USER:
                return Constants.createUrlToGetViewAllUsers(Users.getId(), latitude, longitude, Users.getAuthToken(), start, LIMIT);

            case ViewAllCategory.CATEGORY_MY_BOOKS:
                return Constants.createUrlToGetViewAllMyBooks(Users.getId(), Users.getAuthToken(), start, LIMIT);
        }
    }

    private void showLoading() {
        sbLoading = Snackbar.make(coolMain, R.string.view_all_loading, Snackbar.LENGTH_INDEFINITE);
        sbLoading.show();
    }

    private void hideLoading() {
        isLoading = false;
        if (sbLoading != null) {
            sbLoading.dismiss();
        }
    }

and following is my AdapterClasss

public class ViewAllUserAdapter extends BaseAdapter {

    private List<Users> users;
    private Context context;

    public ViewAllUserAdapter(Context context, List<Users> usersData) {
        this.context = context;
        users = usersData;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row=convertView;
        UserVH holder=null;
        if(row==null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            row= inflater.inflate(R.layout.list_item_view_all_user, parent, false);
            holder = new UserVH(row, position);

            Users user = users.get(position);
            UIUtility.setUserProfileUsingPicasso(context, user.getProfileImageUrlSmall(), holder.ivUserImage);

            holder.tvName.setText(user.getName());
            if (user.getDistance() == -1) {
                holder.tvDistance.setText("");
            } else {
                holder.tvDistance.setText(context.getString(R.string.distance_notation, user.getDistance()));
            }
            row.setTag(holder);
        }
        else {
            holder=(UserVH)row.getTag();Users user = users.get(position);
            UIUtility.setUserProfileUsingPicasso(context, user.getProfileImageUrlSmall(), holder.ivUserImage);

            holder.tvName.setText(user.getName());
            if (user.getDistance() == -1) {
                holder.tvDistance.setText("");
            } else {
                holder.tvDistance.setText(context.getString(R.string.distance_notation, user.getDistance()));
            }

        }

        return row;
    }

    @Override
    public int getCount() {
        return users == null ? 0 : users.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

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

    public void mergeArray(List<Users> additionalUsers) {
        Log.e("users", String.valueOf(additionalUsers.size()));
        if (additionalUsers != null) {
            for (int i = 0; i < additionalUsers.size(); i++) {
                if(!(users.contains(additionalUsers.get(i)))) {
                    users.add(additionalUsers.get(i));
                }
            }
        }
        notifyDataSetChanged();
    }

    public class UserVH extends View {
        @Bind(R.id.item_vau_iv_user_image)
        ImageView ivUserImage;
        @Bind(R.id.item_vau_tv_name)
        TextView tvName;
        @Bind(R.id.item_vau_tv_distance)
        TextView tvDistance;

        private int position;

        public UserVH(View view, final int position) {
            super(context);
            this.position = position;
            ButterKnife.bind(this, view);
            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    UIUtility.openUserDetailActivity(context, users.get(position));
                }
            });
        }
    }
}

Upvotes: 2

Views: 419

Answers (2)

Jai
Jai

Reputation: 1984

As you already referred this link, Exactly the same issue is happening with you, You should have correct implementation for holder class in getView method.

Update your getView() method as per below :

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row=convertView;
        UserVH holder=null;
        if(row==null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            row= inflater.inflate(R.layout.list_item_view_all_user, parent, false);
            holder = new UserVH(row, position);

            row.setTag(holder);
        }
        else {
            holder=(UserVH)row.getTag();

        }



        Users user = users.get(position);
        UIUtility.setUserProfileUsingPicasso(context, user.getProfileImageUrlSmall(), holder.ivUserImage);

            holder.tvName.setText(user.getName());
            if (user.getDistance() == -1) {
                holder.tvDistance.setText("");
            } else {
                holder.tvDistance.setText(context.getString(R.string.distance_notation, user.getDistance()));
            }

        return row;
    }

And update your getItemId and getItem methods as per below :

@Override
public Object getItem(int position) {
    return users.get(position);
}

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

EDIT : clear the list additional users before adding the new objects

public void mergeArray(List<Users> additionalUsers) {
    Log.e("users", String.valueOf(additionalUsers.size()));
    if (additionalUsers != null) {
        // Following line to be added          
        additonalusers.clear();
        for (int i = 0; i < additionalUsers.size(); i++) {
            if(!(users.contains(additionalUsers.get(i)))) {
                users.add(additionalUsers.get(i));
            }
        }
    }
    notifyDataSetChanged();
}

Upvotes: 1

karan
karan

Reputation: 8853

Your implementation of following methods is incorrect.

@Override
public Object getItem(int position) {
    return null;
}

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

Change them as below

@Override
public Object getItem(int position) {
    return users.get(position);
}

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

Upvotes: 1

Related Questions