1. Download our Official Android App: Forums for Android!

Apps How can I use my variables from my custom adapter?

Discussion in 'Android Development' started by cdubs, Apr 13, 2016.

  1. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    I am using a list view and creating a custom adapter. I am trying to get information every time the button is clicked. The button being declared is connected with each item in the list view. How can I use that button variable so that I get the actual button being used and not just the first button of the list.

    Here is the adapter method:

    Code (Text):
    1.  
    2. class PostsAdapter extends ArrayAdapter<Posts>{
    3.  
    4.     //used to create views from xml
    5.     private LayoutInflater layoutInflater;
    6.  
    7.     public PostsAdapter(Context context, int textViewResourceId, List<Posts> posts) {
    8.         super(context, textViewResourceId, posts);
    9.         layoutInflater = LayoutInflater.from(context);
    10.     }
    11.  
    12.     //add to xml from dataset
    13.     @Override
    14.     public View getView(int position, View convertView, ViewGroup parent) {
    15.         View view = layoutInflater.inflate(R.layout.activity_posts, null);
    16.         Posts posts = getItem(position);
    17.  
    18.         TextView content = (TextView) view.findViewById(R.id.content);
    19.         TextView user = (TextView) view.findViewById(R.id.user);
    20.         TextView topic = (TextView) view.findViewById(R.id.topic);
    21.         TextView date = (TextView) view.findViewById(R.id.date);
    22.         TextView likes = (TextView) view.findViewById(R.id.likeCount);
    23.         TextView id = (TextView) view.findViewById(R.id.hiddenID);
    24.         Button like = (Button) view.findViewById(R.id.btnLike);
    25.  
    26.         content.setText(posts.getContent());
    27.         user.setText(posts.getUser());
    28.         topic.setText(posts.getTopic());
    29.         date.setText(posts.getDate());
    30.         likes.setText(posts.getLikes());
    31.         id.setText(posts.getId());
    32.  
    33.         like.setOnClickListener(DisplayPosts.this);
    34.  
    35.         return view;
    36.     }
    37.  
    38.  
    39. }
    40.  
    41.  
    In my other method I have to redeclare my button variable and this just gets the first button in the list, not the one being clicked on:

    Code (Text):
    1.  
    2. private void createLike(){
    3.     Button like = (Button) findViewById(R.id.btnLike);
    4.     TextView id = (TextView) findViewById(R.id.hiddenID);
    5.     TextView user = (TextView) findViewById(R.id.user);
    6.  
    7.     final String hid = id.getText().toString().trim();
    8.     final String puser = user.getText().toString().trim();
    9.  
    10.     if(like.getText().toString().equalsIgnoreCase("like")){
    11.         like.setText("UnLike");
    12.         ...
    13.  


     

    Advertisement

  2. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    In what class is your createLike() method declared, and which code calls it?
     
    cdubs likes this.
  3. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Thank you so much for the reply. The createLike method is inside my main class DisplayPosts.java. class PostsAdapter extends ArrayAdapter<Posts>{... is also in this class. I have an onclick calling the method:
    Code (Text):
    1. case R.id.btnLike:
    2.     createLike();
    3.  
    Here is the entire class if it helps:
    https://github.com/codyweis/iDea/bl...n/java/apps/luck3y/com/idea/DisplayPosts.java
     
  4. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    You're setting up the button onClick listener in the wrong place.
    So your basic problem as it stands is that your code is finding only the first Button that matches the id, within the Activity's View. This attaches your onClick listener to the first Button in the list only.

    If you want to have a ListView where each row contains a Button (with listener), then the onClick must be attached in the Adapter class. So here, the 'view' variable refers to the View of the row in your ListView

    Code (Text):
    1.  
    2. ...
    3. //add to xml from dataset
    4.     @Override
    5.     public View getView(int position, View convertView, ViewGroup parent) {
    6.       ...
    7.       Button like = (Button) view.findViewById(R.id.btnLike);
    8.       ...
    9.  
    This code finds the instance of the 'like' Button which corresponds to an individual row. You would attach the onClick listener to this Button.


    As an aside: Another major problem with your ListView adapter is that you're not handling View reuse. This whole article is interesting, but in particular you should read this section

    http://www.vogella.com/tutorials/AndroidListView/article.html#adapterperformance
     
    cdubs likes this.
  5. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Awesome, I knew why it was doing it but didn't know how to fix it. I have tried to put the onclick in the view class but I am getting errors. Is there a special way to do the onclick in this class?
     
    #5 cdubs, Apr 14, 2016
    Last edited: Apr 14, 2016
    LV426 likes this.
  6. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    The onClick listener goes in the PostsAdapter class
     
    cdubs likes this.
  7. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    I can only reuse the button instance 'like' if I am inside the getView method, and I get errors if I am to create an onclick there. Sorry if I am misunderstanding your intentions. Thank you for the help.
     
  8. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    So in getView() use

    Code (Text):
    1.  
    2. like.setOnClickListener(this)
    3.  
    and your PostsAdapter class must implement onClickListener
     
    cdubs likes this.
  9. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Awesome! So I got the 'like' button changing text on each one that I click.

    Code (Text):
    1.  
    2. class PostsAdapter extends ArrayAdapter<Posts> implements View.OnClickListener {
    3.  
    4.         //used to create views from xml
    5.         private LayoutInflater layoutInflater;
    6.         Button like;
    7.         TextView likes;
    8.         TextView hiddenId;
    9.  
    10.         public PostsAdapter(Context context, int textViewResourceId, List<Posts> posts) {
    11.             super(context, textViewResourceId, posts);
    12.             layoutInflater = LayoutInflater.from(context);
    13.         }
    14.  
    15.         //add to xml from dataset
    16.         @Override
    17.         public View getView(int position, View convertView, ViewGroup parent) {
    18.             View view = layoutInflater.inflate(R.layout.activity_posts, null);
    19.             Posts posts = getItem(position);
    20.  
    21.             TextView content = (TextView) view.findViewById(R.id.content);
    22.             TextView user = (TextView) view.findViewById(R.id.user);
    23.             TextView topic = (TextView) view.findViewById(R.id.topic);
    24.             TextView date = (TextView) view.findViewById(R.id.date);
    25.             likes = (TextView) view.findViewById(R.id.likeCount);
    26.             hiddenId = (TextView) view.findViewById(R.id.hiddenID);
    27.  
    28.             like = (Button) view.findViewById(R.id.btnLike);
    29.  
    30.             content.setText(posts.getContent());
    31.             user.setText(posts.getUser());
    32.             topic.setText(posts.getTopic());
    33.             date.setText(posts.getDate());
    34.             likes.setText(posts.getLikes());
    35.             hiddenId.setText(posts.getId());
    36.  
    37.             like.setOnClickListener(this);
    38.  
    39.             return view;
    40.         }
    41.  
    42.  
    43.         @Override
    44.         public void onClick(View v) {
    45.             like = (Button) v;
    46.  
    47.             createLike(like, hiddenId, likes);
    48.         }
    49.     }
    50.  
    Now I am trying to pass in the hiddenID and likes so I can access those in the createLike method. However it is not getting the correct hiddenid from the post. It seems to be getting a random one, sometimes the same id when I click like.
     
  10. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    That's not going to work. You can't use class variables like this to store the list row Views

    Code (Text):
    1.  
    2.         Button like;
    3.         TextView likes;
    4.         TextView hiddenId;
    5.  
    Let me try to explain why. You don't control when getView() is called. It's called by the system, when it needs to render a row of your ListView. This method just inflates and returns the correct View, for the given position.
    (And I really would look at how ListView recycling works, if your ListView contains a lot of items.)

    Anyway, each time getView() is called, your code is assigning the above class variables. Each time it will overwrite these variables with what is in the current row to be rendered.

    In parallel with all that, your onClick() method is being called asynchronously, whenever you click a button on a row. So when this code accesses class variables 'hiddenId' and 'likes', these variables will almost certainly hold values which are for a different row. Hence you get the wrong values for the row you just clicked.

    What you need to use is a technique called 'view tagging'. This allows you to associate some supplementary data structure with the View. You could tag the Button view with a 'Holder' class. The Holder class contains your hiddenId. In the Button's onClick method, you simply retrieve the tag data structure from the Button view using getTag();

    Hope I explained this reasonably clearly. As you can see ListViews are quite complex things to deal with!

    Here's an outline of what you will need for your Button View tagging. In the following code 'holder' is an instance of the ViewHolder class:

    Code (Text):
    1.  
    2.  
    3. static class ViewHolder {
    4.    protected TextView hiddenId;
    5.    protected TextView likes;
    6. }
    7.  
    8. like.setTag(holder);
    9.  
     
    #10 LV426, Apr 14, 2016
    Last edited: Apr 14, 2016
    cdubs likes this.
  11. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Okay I think I am on the right track. I have been working hard on this and I really appreciate all your responses. Here is what I have come up with:

    Code (Text):
    1.  
    2. class PostsAdapter extends ArrayAdapter<Posts> implements View.OnClickListener {
    3.     //used to create views from xml
    4.     private LayoutInflater layoutInflater;
    5.  
    6.     public PostsAdapter(Context context, int textViewResourceId, List<Posts> posts) {
    7.         super(context, textViewResourceId, posts);
    8.         layoutInflater = LayoutInflater.from(context);
    9.     }
    10.     //add to xml from dataset
    11.     @Override
    12.     // view convertview = recycled view
    13.     public View getView(int position, View convertView, ViewGroup parent) {
    14.         View view = convertView;
    15.         Holder holder = null;
    16.         Posts posts = getItem(position);
    17.  
    18.         //checks if recycled view is null, thewn creates new view, if not null, use same view
    19.         if(view == null){
    20.             view = layoutInflater.inflate(R.layout.activity_posts, null);
    21.  
    22.             Button like = (Button) view.findViewById(R.id.btnLike);
    23.             TextView content = (TextView) view.findViewById(R.id.content);
    24.             TextView user = (TextView) view.findViewById(R.id.user);
    25.             TextView topic = (TextView) view.findViewById(R.id.topic);
    26.             TextView date = (TextView) view.findViewById(R.id.date);
    27.             TextView likes = (TextView) view.findViewById(R.id.likeCount);
    28.             TextView hiddenId = (TextView) view.findViewById(R.id.hiddenID);
    29.  
    30.             holder = new Holder(content, user, topic, date, likes, hiddenId, like);
    31.  
    32.             view.setTag(holder);
    33.         }
    34.         else{
    35.             holder = (Holder) view.getTag();
    36.         }
    37.         holder.content.setText(posts.getContent());
    38.         holder.user.setText(posts.getUser());
    39.         holder.topic.setText(posts.getTopic());
    40.         holder.date.setText(posts.getDate());
    41.         holder.likes.setText(posts.getLikes());
    42.         holder.hiddenId.setText(posts.getId());
    43.  
    44.         holder.like.setOnClickListener(this);
    45.  
    46.         return view;
    47.     }
    48.  
    49.     -----@Override
    50.   ----- public void onClick(View v) {
    51.         -----like = (Button) v;
    52.         -----Toast.makeText(DisplayPosts.this, "Button: " + like.getText(),
    53.         -----Toast.LENGTH_LONG).show();
    54.         -----createLike(like);
    55.     -----}
    56. -----}
    57.  
    58. static class Holder{
    59.     public TextView content;
    60.     public TextView user;
    61.     public TextView topic;
    62.     public TextView date;
    63.     public TextView likes;
    64.     public TextView hiddenId;
    65.     public Button like;
    66.  
    67.     public Holder(TextView content, TextView user, TextView topic, TextView date, TextView likes, TextView hiddenId, Button like) {
    68.         this.content = content;
    69.         this.user = user;
    70.         this.topic = topic;
    71.         this.date = date;
    72.         this.likes = likes;
    73.         this.hiddenId = hiddenId;
    74.         this.like = like;
    75.     }
    76. }
    77.  
    I put dashes next to the part that I am having trouble with. How do I use the 'like' button variable in the onclick without declaring the class variable 'Button like;' . I hope I am on the right track. Thanks again for your help.
     
  12. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    You've called setTag on the wrong View object. You should set it on the like Button.

    Then in your onClick method, you don't need to access a class 'like' variable. You use the parameter given to this method 'v' - which is actually the same object which you used in your getView method

    So if you use something like the following, it should work

    Code (Text):
    1.  
    2. @Override
    3. public void onClick(View v) {
    4.   Button like = (Button) v;
    5.   Holder holder = (Holder) v.getTag();
    6.   // holder.hiddenId now accessible
    7.   ...
    8. }
    9.  
     
  13. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Again, thank you for your help. I am learning a lot going through all these steps. I know you have done more than what I have asked but I really appreciate the help. Here are the problems I am still encountering.
    1) There still seems to be problems with liking one button, and it changing the text on another.
    2) When I hit like button, it updates the like, when I scroll down out of view, and scroll back up, the like number is reset to the original number.
    3) I needed to keep the view.setTag in order for the app to run. I added like.settag under it.

    Here is updated code:
    Code (Text):
    1.  
    2. ...
    3. if(view == null){
    4.             view = layoutInflater.inflate(R.layout.activity_posts, null);
    5.  
    6.             Button like = (Button) view.findViewById(R.id.btnLike);
    7.             TextView content = (TextView) view.findViewById(R.id.content);
    8.             TextView user = (TextView) view.findViewById(R.id.user);
    9.             TextView topic = (TextView) view.findViewById(R.id.topic);
    10.             TextView date = (TextView) view.findViewById(R.id.date);
    11.             TextView likes = (TextView) view.findViewById(R.id.likeCount);
    12.             TextView hiddenId = (TextView) view.findViewById(R.id.hiddenID);
    13.  
    14.             holder = new Holder(content, user, topic, date, likes, hiddenId, like);
    15.  
    16.             view.setTag(holder);
    17.             like.setTag(holder);
    18.         }
    19.         else{
    20.             holder = (Holder) view.getTag();
    21.         }
    22.         holder.content.setText(posts.getContent());
    23.         holder.user.setText(posts.getUser());
    24.         holder.topic.setText(posts.getTopic());
    25.         holder.date.setText(posts.getDate());
    26.         holder.likes.setText(posts.getLikes());
    27.         holder.hiddenId.setText(posts.getId());
    28.  
    29.         holder.like.setOnClickListener(this);
    30.  
    31.         return view;
    32.     }
    33.  
    34.     @Override
    35.     public void onClick(View v) {
    36.         Button like = (Button) v;
    37.         Holder holder = (Holder) v.getTag();
    38.         Toast.makeText(DisplayPosts.this, "Button: " + like.getText(), Toast.LENGTH_LONG).show();
    39.  
    40.         createLike(like, holder.hiddenId, holder.likes);
    41.     }
    42. }
    43.  
    44. static class Holder{
    45.     public TextView content;
    46.     public TextView user;
    47.     public TextView topic;
    48.     public TextView date;
    49.     public TextView likes;
    50.     public TextView hiddenId;
    51.     public Button like;
    52.  
    53.     public Holder(TextView content, TextView user, TextView topic, TextView date, TextView likes, TextView hiddenId, Button like) {
    54.         this.content = content;
    55.         this.user = user;
    56.         this.topic = topic;
    57.         this.date = date;
    58.         this.likes = likes;
    59.         this.hiddenId = hiddenId;
    60.         this.like = like;
    61.     }
    62. }
    63.  
    Here is createLike():

    Code (Text):
    1.  
    2. private void createLike(final Button like, final TextView hiddenid, final TextView likes){
    3.     final String hid = hiddenid.getText().toString().trim();
    4.  
    5.     if(like.getText().toString().equalsIgnoreCase("like")){
    6.         like.setText("UnLike");
    7.         StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.SERVER_ADDRESS + "LikePost.php",
    8.                 new Response.Listener<String>() {
    9.                     @Override
    10.                     public void onResponse(String response) {
    11.  
    12.                         JSONObject jsonObject = null;
    13.                         try {
    14.                             //json string to jsonobject
    15.                             jsonObject = new JSONObject(response);
    16.                             //get json sstring created in php and store to JSON Array
    17.                             result2 = jsonObject.getJSONArray(Config.json_array_likes);
    18.                             //get username from json array
    19.                             likes.setText(getLikeCount(result2));
    20.                         } catch (JSONException e) {
    21.                             e.printStackTrace();
    22.                         }
    23.                     }
    24.                 },
    25.                 new Response.ErrorListener() {
    26.                     @Override
    27.                     public void onErrorResponse(VolleyError error) {
    28.                     }
    29.                 }){
    30.             @Override
    31.             protected Map<String, String> getParams() throws AuthFailureError {
    32.                 Map<String,String> hashMap = new HashMap<>();
    33.                 //maps specified string key, to specified string value
    34.                 hashMap.put(Config.hid, hid);
    35.                 return hashMap;
    36.             }
    37.         };
    38.         //add string request to queue
    39.         RequestQueue requestQueue = Volley.newRequestQueue(this);
    40.         requestQueue.add(stringRequest);
    41.     }
    42.     else{
    43.         like.setText("Like");
    44.     }
    45. }
    46. private String getLikeCount(JSONArray jsonArray){
    47.     String lc = null;
    48.     for(int i = 0; i < jsonArray.length(); i++) {
    49.         try {
    50.             JSONObject json = jsonArray.getJSONObject(i);
    51.             likeCount.add(json.getString(Config.getLike));
    52.             lc = likeCount.get(0);
    53.         } catch (JSONException e) {
    54.         }
    55.     }
    56.     return lc;
    57. }
    58.  
     
  14. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    Hard to say what's going wrong just through static code analysis. I'd have to get in there and debug, trying to figure out what exactly is getting saved into that Holder class.
    But you do seem like a smart guy, I'm sure you will get to the bottom of it.
     
    #14 LV426, Apr 15, 2016
    Last edited: Apr 15, 2016
    cdubs likes this.
  15. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    I really appreciate all your help so far. I have figured out problem 2 and problem 3 that I had. However problem 1 still exists. There still seems to be problems with liking one button, and it changing the text on another. Do you know what is causing this?

    Here is the updated code:

    Code (Text):
    1.  
    2. public class PostsAdapter extends ArrayAdapter<Posts>  {
    3.     //used to create views from xml
    4.     Context context;
    5.     int textViewResourceId;
    6.     ArrayList<Posts> mPosts = new ArrayList<Posts>();
    7.  
    8.     public PostsAdapter(Context context, int textViewResourceId, ArrayList<Posts> posts) {
    9.         super(context, textViewResourceId, posts);
    10.         this.textViewResourceId = textViewResourceId;
    11.         this.context = context;
    12.         this.mPosts = posts;
    13.     }
    14.  
    15.     // view convertview = recycled view
    16.     @Override
    17.     public View getView(final int position, View convertView, ViewGroup parent) {
    18.         View view = convertView;
    19.         final Holder holder;
    20.         //checks if recycled view is null, thewn creates new view, if not null, use same view
    21.         if(view == null){
    22.             LayoutInflater inflater = ((Activity) context).getLayoutInflater();
    23.             view = inflater.inflate(textViewResourceId, parent, false);
    24.  
    25.             Button like = (Button) view.findViewById(R.id.btnLike);
    26.             TextView content = (TextView) view.findViewById(R.id.content);
    27.             TextView user = (TextView) view.findViewById(R.id.user);
    28.             TextView topic = (TextView) view.findViewById(R.id.topic);
    29.             TextView date = (TextView) view.findViewById(R.id.date);
    30.             TextView likes = (TextView) view.findViewById(R.id.likeCount);
    31.             TextView hiddenId = (TextView) view.findViewById(R.id.hiddenID);
    32.             holder = new Holder(content, user, topic, date, likes, hiddenId, like);
    33.  
    34.             view.setTag(holder);
    35.         }
    36.         else{
    37.             holder = (Holder) view.getTag();
    38.         }
    39.  
    40.         Posts posts = mPosts.get(position);
    41.         holder.content.setText(posts.getContent());
    42.         holder.user.setText(posts.getUser());
    43.         holder.topic.setText(posts.getTopic());
    44.         holder.date.setText(posts.getDate());
    45.         holder.likes.setText(posts.getLikes());
    46.         holder.hiddenId.setText(posts.getId());
    47.  
    48.         holder.like.setOnClickListener(new View.OnClickListener() {
    49.             @Override
    50.             public void onClick(View v) {
    51.                 createLike(position, holder.like, holder.hiddenId, holder.likes);//Added one more parameter "position"
    52.             }
    53.         });
    54.  
    55.         return view;
    56.     }
    57.  
    58.     private void createLike(final int position, final Button like, final TextView hiddenid, final TextView likes){
    59.         final String hid = hiddenid.getText().toString().trim();
    60.  
    61.         if(like.getText().toString().equalsIgnoreCase("like")){
    62.  
    63.             like.setText("UnLike");
    64.             StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.SERVER_ADDRESS + "LikePost.php",
    65.                     new Response.Listener<String>() {
    66.                         @Override
    67.                         public void onResponse(String response) {
    68.  
    69.                             JSONObject jsonObject = null;
    70.                             try {
    71.                                 //counter
    72.                                 n+=1;
    73.  
    74.                                 //json string to jsonobject
    75.                                 jsonObject = new JSONObject(response);
    76.                                 //get json sstring created in php and store to JSON Array
    77.                                 result2 = jsonObject.getJSONArray(Config.json_array_likes);
    78.                                 //get username from json array
    79.                                 String likestring = getLikeCount(result2);
    80.                                 String likenum = mPosts.get(position).getLikes(likestring);
    81.                                 likes.setText(likenum);
    82.                                 mPosts.get(position).setLikes(likenum);
    83.  
    84.                             } catch (JSONException e) {
    85.                                 e.printStackTrace();
    86.                             }
    87.                         }
    88.                     },
    89.                     new Response.ErrorListener() {
    90.                         @Override
    91.                         public void onErrorResponse(VolleyError error) {
    92.                         }
    93.                     }){
    94.                 @Override
    95.                 protected Map<String, String> getParams() throws AuthFailureError {
    96.  
    97.                     // corresponding values.
    98.                     Map<String,String> hashMap = new HashMap<>();
    99.                     //maps specified string key, to specified string value
    100.                     hashMap.put(Config.hid, hid);
    101.                     return hashMap;
    102.                 }
    103.             };
    104.  
    105.             //add string request to queue
    106.             RequestQueue requestQueue = Volley.newRequestQueue(DisplayPosts.this);
    107.             requestQueue.add(stringRequest);
    108.         }
    109.         else{
    110.             like.setText("Like");
    111.             //mPosts.get(position);
    112.  
    113.         }
    114.     }
    115.     private String getLikeCount(JSONArray jsonArray){
    116.         System.out.println("JSON: " + jsonArray);
    117.         String lc = null;
    118.         for(int i = 0; i < jsonArray.length(); i++) {
    119.             try {
    120.                 JSONObject json = jsonArray.getJSONObject(i);
    121.                 likeCount.add(json.getString(Config.getLike));
    122.                 System.out.println("i: " + i);
    123.                 lc = likeCount.get(n - 1);
    124.             } catch (JSONException e) {
    125.             }
    126.         }
    127.         System.out.println("LC: " + lc);
    128.         return lc;
    129.     }
    130.  
    131.      class Holder{
    132.         public TextView content;
    133.         public TextView user;
    134.         public TextView topic;
    135.         public TextView date;
    136.         public TextView likes;
    137.         public TextView hiddenId;
    138.         public Button like;
    139.  
    140.         public Holder(TextView content, TextView user, TextView topic, TextView date, TextView likes, TextView hiddenId, Button like) {
    141.             this.content = content;
    142.             this.user = user;
    143.             this.topic = topic;
    144.             this.date = date;
    145.             this.likes = likes;
    146.             this.hiddenId = hiddenId;
    147.             this.like = like;
    148.         }
    149.     }
    150. }
    151.  
    Thank you!
     
  16. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    Does this happen when you scroll the list up and down, or when you haven't scrolled at all?
     
  17. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    Well, I think it's when I dont scroll at all. But I cant be sure because I have to scroll down to see it. I just know when I click 'like' it changes to unlike, and when I scroll down there will be another one with the text unlike. It seems to be the 5th one under it is also changed. Which is interesting because it can fit a max of 5 on the screen at once.
     
  18. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    It's probably a Listview recycling problem. Make sure you understand how this works. Look at tutorials on how to implement Listview recycling properly.
     
    cdubs likes this.
  19. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    The crucial thing is that if your onClick method is setting the text on a different button, then the holder.like Button is not the same as the one you just clicked. Right? So you need to figure out why this is happening.
     
  20. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    I still can't figure out my problem. Any more help would be appreciated.
     
    #20 cdubs, Apr 24, 2016
    Last edited: Apr 24, 2016
  21. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,883
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,883
    11,531
    1,988
    Male
    Software developer
    South West of England
    It's because you don't update the like Button which is contained in your holder class.

    When you scroll down one item, the system calls getView() with parameter 'convertView' set to what was the first item in your list (it's no longer visible on the screen, so can be recycled)

    Your code then detects that view !=null, so goes into the block

    Code (Text):
    1.  
    2. else{
    3.             holder = (Holder) view.getTag();
    4.         }
    5.  
    But the holder still contains the like Button from the previous item 1, which has the text 'unlike'

    The following code should update the like Button contained in the holder class

    Code (Text):
    1.  
    2.        Posts posts = mPosts.get(position);
    3.         holder.content.setText(posts.getContent());
    4.         holder.user.setText(posts.getUser());
    5.         holder.topic.setText(posts.getTopic());
    6.         holder.date.setText(posts.getDate());
    7.         holder.likes.setText(posts.getLikes());
    8.         holder.hiddenId.setText(posts.getId());
    9.  
    10.  
     
  22. cdubs

    cdubs Newbie
    Thread Starter
    Rank:
    None
    Points:
    16
    Posts:
    13
    Joined:
    Feb 25, 2016

    Feb 25, 2016
    13
    1
    16
    Male
    So do I just hard code the text in right there for the like button? What do I do to update there? All the other holders just enter text from the posts class. Do I add button text to the post class?
     

Share This Page

Loading...