Search code examples
androidlistviewprogressseekbar

How to set Seekbar Progress in Listview with custom rows


Progress of seekbar is not saved after scrolling ListView.

I have a problem with the seekbars in my custom row layouts in my listview. For simplicity, please reffer to below tutorial, to which i added a seekbar in the layout and i changed the "name" field to an int ("number"), controlled by the seekbar progress:

https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView

https://github.com/codepath/android-custom-array-adapter-demo

when changing the first seekbar and cycling the views , down and up, the progress is reset.

am i not saving it correctly here : users.get(PersonPosition).number = progress;?

Thank you in advance

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_list);
        ListView listView = (ListView) findViewById(R.id.lvUsers);
        ArrayList<User> arrayOfUsers = User.getUsers();
        listView.setAdapter(new CustomUsersAdapter(this,
                arrayOfUsers));
    }
}
public class User {
    //declare private data instead of public to ensure the privacy of data field of each class
    public int number;
    public String hometown;

    public User(int number, String hometown) {
        this.number = number;
        this.hometown = hometown;
    }

    //retrieve user's name
    public int getnumber(){
        return number;
    }
    //retrieve user's name
    public void setnumber(int number){
        this.number= number;
    }

    //retrieve users' hometown
    public String getHometown(){
        return hometown;
    }

    public static ArrayList<User> getUsers() {
        ArrayList<User> users = new ArrayList<User>();
        users.add(new User(0, "San 1"));
        users.add(new User(0, "San 2"));
        users.add(new User(0, "San 3"));
        users.add(new User(0, "San 4"));
        users.add(new User(0, "San 5"));
        users.add(new User(0, "San 6"));
        users.add(new User(0, "San 7"));
        users.add(new User(0, "San 8"));
        users.add(new User(0, "San 9"));
        users.add(new User(0, "San 10"));
        users.add(new User(0, "San 11"));
        users.add(new User(0, "San 12"));
        return users;
    }

    public void showItem (String Tag) {
        System.out.println("\n" + Tag +
                "\nNumber: "             + number +
                "\nHometown:"            + hometown
                );
    }
}
public class CustomUsersAdapter extends ArrayAdapter<User> {
    Context context;
    private final ArrayList<User>   users;

    public CustomUsersAdapter(Context context, ArrayList<User> users) {
        super(context, 0, users);
        this.context=context;
        this.users=users;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_user, parent, false);
        }

        final User      user         = getItem(position);
        final TextView  tvName       = (TextView) convertView.findViewById(R.id.tvName);
        TextView        tvHome       = (TextView) convertView.findViewById(R.id.tvHometown);
        SeekBar         seekBar      = convertView.findViewById(R.id.seekBar);

//        user.showItem("#############getView()");


        tvName.setText(String.valueOf(user.getnumber()));
        tvHome.setText(user.getHometown());


        seekBar.setProgress (user.getnumber());

        final int PersonPosition = position;
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                tvName.setText(String.valueOf(progress));
//                user.setName(progress);
//                user.showItem("OnProgressChanged");
                users.get(PersonPosition).number = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        // Return the completed view to render on screen

        return convertView;
    }
}

Solution

  • You will want to update the user when you stop tracking the touch like so:

     seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                tvName.setText(String.valueOf(progress));
    //                user.setName(progress);
    //                user.showItem("OnProgressChanged");
    
            }
    
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
    
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
               users.get(PersonPosition).setNumber(seekBar.getProgress());
            }
        });
    

    You will also want to consider using the view holder pattern.