Search code examples
javaandroidlistviewandroid-listviewbaseadapter

Android Listview in Baseadapter how can I save changes to the list


I have been reading different posts on here about baseadapters and trying to learn so that I can fix my issue but I haven't been able to resolve it. On my BaseAdapter I have a String called post that is used in a column in the listview. If the post is longer than 13 characters then it is shortened automatically when the user Clicks on the shortened post then it displays it's full length,however the issue is that once you scroll down the listview and come back up to that same post it's still shortened even though the user clicked before to show the full post. I think this is an issue of the Listview or Baseadapter recycling or cache mechanism is there anyway I can fix this? This image will clear things up .. This post is more than 13 characters so it shows the shortened version

enter image description here

if a user wants to read it in full then they will click on the Read More which will then show all of the content which looks like this

enter image description here

and when the user scrolls down or up that same long post will return to this without the user clicking it again, which I want to avoid

enter image description here

I know that the Listview recycles but how can I update it? This is my code below

public class LocalFeed_CustomView extends BaseAdapter {

 JSONObject names;
    Context ctx;
    Activity m;
    // More is the default value
    String result="More";

    @Override
    public int getCount() {
        try {
            JSONArray jaLocalstreams = names.getJSONArray("localstreams");
            return jaLocalstreams.length();
        } catch (Exception e) {
            Toast.makeText(ctx, "Error: Please try again", Toast.LENGTH_LONG).show();
            return names.length();
        }


    }


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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row=convertView;
        MyViewHolder holder=null;
        try {
            if (row == null) {

                LayoutInflater li = (LayoutInflater) m.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = li.inflate(R.layout.customadapter, null);
                holder = new MyViewHolder(row);
                row.setTag(holder);


            } else {
                holder = (MyViewHolder) row.getTag();
            }


           final MyViewHolder finalHolder1=holder;
        // Json data has been read
            JSONArray jaLocalstreams = names.getJSONArray("localstreams");
            final JSONObject jsonObject = jaLocalstreams.getJSONObject(position);
            // if post length is more than 14 then shorten it
            if (jsonObject.getString("post").length() > 14) {
                holder.post.setText(jsonObject.getString("post").substring(0, 13) + "...Read More");
                holder.post.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        try {
                              // if Result is More then show full post
                            if (result.equals("More")) {
                                finalHolder1.post.setText(jsonObject.getString("post") + "... Read Less");
                                result = "Less";
                            }
                            else
                            {
                                //Result is Less so shorten it again
                                finalHolder1.post.setText(jsonObject.getString("post").substring(0, 13) + "... Read More");
                            result = "More";
                        }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });

        } else{
                // This Post is already less than 14 characters so no Onclick here
            holder.post.setText(jsonObject.getString("post"));
        }

            return row;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return row;


    }






    class MyViewHolder{
        TextView post;
        MyViewHolder(View v)
        {

           post = (TextView)v.findViewById(R.id.post);

        }

    }

}

Solution

  • The adapter represents the model of the list at any given moment in time.

    What this means to you is that if a user clicks a TextView to expand it with the idea that the view is going to stay expanded, then that expanded TextView is state information that will have to be captured in the adapter.

    Adapters should always be thought of in two phases:

    • Event (like onClick()) will update state in the adapter and call notifyDataSetChanged().
    • getView() uses the current state to create the view.

    So let's say in the adapter constructor we create an array of flags

        boolean expanded[] = new boolean[size];
    

    where size is the length of your list.

    Then you can do this:

                // use the current state to create the view
                String text;
                if (expanded[position]) {
                    text = jsonObject.getString("post") + "... Read Less";
                } else {
                    text = jsonObject.getString("post").substring(0, 13) + "...Read More";
                }
                holder.post.setText(text);
                holder.post.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // update the current state and request list refresh
                        expanded[position] = ! expanded[position];    // toggle
                        notifyDataSetChanged();
                    }
                });
    

    This code doesn't do exactly what yours does, I just wanted to give you the basic idea.