I've been researching this forever and can't find a solution. Everything about my custom list view seems to perform correctly. When I click on the holder.feedUpVoteButton
, the text changes +=1
correctly. However, when I scroll down and scroll back up, the text value is reverted to the value it had before it was clicked.
I refuse to use notifyDatasetChanged
because I am not adding anything or removing anything from the list.
public class CustomFeedListViewAdapter extends BaseAdapter{
CustomFeedListViewAdapter customFeedListViewAdapter;
Date createdAt, currentDate; int num;
static HashMap<String, String> oneData = new HashMap<String, String>();
HashMap<String, String> iFeed = new HashMap<>();
private String likesString;
String upVoteClicked, downVoteClicked;
HashMap<String, String> mFeed = new HashMap<>();
List<ParseObject> mObjects;
private ParseObject parseObFeed;
CustomFeedListViewAdapter(Context context, ArrayList<HashMap<String, String>> data) {
super();
this.mContext = context;
GlobalFeedTab.arrayFeedList = data;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return GlobalFeedTab.arrayFeedList.size();
}
@Override
public Object getItem(int i) {
return GlobalFeedTab.arrayFeedList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
likes = new int[GlobalFeedTab.arrayFeedList.size()];
countryNames = new int[GlobalFeedTab.arrayFeedList.size()];
dateNames = new String[GlobalFeedTab.arrayFeedList.size()];
final ViewHolder holder;
if (view == null) {
position = i;
view = inflater.inflate(R.layout.feed_list_row, viewGroup, false);
holder = new ViewHolder();
holder.feedNumOfLikes = (TextView) view.findViewById(R.id.feedNumofLikes);
holder.feedUpVoteButton = (Button) view.findViewById(R.id.feedUpVoteButton);
} else {
position = i;
holder = (ViewHolder) view.getTag();
}
mFeed = GlobalFeedTab.arrayFeedList.get(position);
holder.feedNumOfLikes.setText(mFeed.get("likes"));
likesString = mFeed.get("likes");
likes[position] = Integer.valueOf(likesString);
holder.feedUpVoteButton.setTag(position);
ParseQuery<ParseObject> query2 = new ParseQuery<ParseObject>("FeedItem");
query2.setLimit(250);
query2.addDescendingOrder("createdAt");
query2.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(final List<ParseObject> objects, ParseException e) {
if (e == null) {
for ( final ParseObject object : objects) {
holder.feedUpVoteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = (Integer) v.getTag();
parseObFeed = objects.get(pos);
username = parseObFeed.getString("username");
createdAt = parseObFeed.getDate("createdAt");
likes[pos] += 1;
parseObFeed.put("likes", likes[pos]);
holder.feedNumOfLikes.setText(String.valueOf(parseObFeed.getInt("likes")));
parseObFeed.put(ParseUser.getCurrentUser().getUsername() + "upvoteClicked", true);
parseObFeed.saveInBackground();
}
});
}
});
return view;
}
private class ViewHolder {
ImageView feedProfilePic;
TextView feedUsername;
TextView feedNumOfLikes;
TextView feedFeedItem;
TextView feedDate;
TextView feedNumofReplies;
Button feedUpVoteButton;
Button feedDownVoteButton;
Button feedCommentButton;
ListView feedListView;
}
}
Actually that is the whole theory.When you increment a value.You have to increment that value in the list from where you are fetching the data.Because when you scroll down,the upper rows will be lost.When you scroll back up,list will be loaded again from the list values.So all you have to do is to increment the value in the list too i.e
GlobalFeedTab.arrayFeedList
this link is for further detail,for anyone looking for some more detail When you write this lineYou will also have to increment the value in the arraylist(mFeed) of yours and then write notifyDataSetChanged();
Every single time
getView
is called, you re-makeThis is not saved as you scroll and the row you clicked leaves and re-enters the display. The holder could hold this integer value.
And update it accordingly
However, you need to also update the parse object.
You are modifying the data, though. Calling it will make your adapter data consistent with what is stored in your Parse Server.
Edit
This gets complicated because you are making each "row" have some "nested" list of objects that are associated with it. I suppose you could store that entire list in the holder.
When inside the adapter, you call Parse to get this secondary list for each item in your adapter, but you only need to store that within the holder. Don't do anything else with it when the query2 returns .
Your real issue here is that is unclear what
query2
is even returning. It's some list of data, sure, but are you actually wanting to display a List within a List? Also, each item of the adapter is querying the exact same data from Parse. I think you need a filter... Then, yourposition
variable doesn't correspond betweenGlobalFeedTab.arrayFeedList
and theList<ParseObject>
, because those are different lists.Here's just some comments that I can point out.
I can't remember if saveInBackground has a callback, but that might be something to look into
After continuous trial and error. I finally figured out how to change a textview after it scrolls. My problem was I was getting the wrong
ParseObject
value. My main activity contains aParseQuery
and I was getting thelikes
from aHashmap();
However, for some reason I couldn't pass the value of likes directly so I passed the ParseObject itself. Therefore, needing no query in myBaseAdapter
Class. Then, I implemented these lines of code inGetView();
to answer my original question: