Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seekbar changes value by itself in RecyclerView

Problem: I have many seekbars (managed by RecyclerView.Adapter), when I scroll view, and specific seekbar is not shown anymore, progress in this seekbar sets by itself to 0 (I can see this in OnSeekBarChangeListner). I wonder why.

Expected behavior: When user not changing value by sliding seekbar, progress shouldn't change.

My workaround for now is to check if seekbar is shown, and only than save value.

onBindViewHolder

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int positi
    final DMXChannel currentChannel = channels.get(position);

   ... // Not relevant
else if (holder instanceof ViewHolderSlider) {
        ((ViewHolderSlider) holder).container.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (listner != null)
                    listner.onLongItemClicked(currentChannel.getIndex(), v);
                return true;
            }
        });
        final ViewHolderSlider holderSlider=((ViewHolderSlider) holder);
                ((ViewHolderSlider) holder).tvPosition.setText("" + (currentChannel.getIndex() + 1));
        int value =currentChannel.getValue();
        holderSlider.slider.setProgress(value);
        ((ViewHolderSlider) holder).tvValue.setText("" + currentChannel.getValue());
        ((ViewHolderSlider) holder).slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                holderSlider.tvValue.setText("" + progress);
                if(position!=RecyclerView.NO_POSITION) {
                    if(seekBar.isShown())
                    currentChannel.setValue(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}

My ViewHolder for seekbars

public static class ViewHolderSlider extends RecyclerView.ViewHolder {
    public TextView tvPosition;
    public TextView tvValue;
    public CardView container;
    public VerticalSeekBar slider;
    public ViewHolderSlider(View v) {
        super(v);
        slider= (VerticalSeekBar)v.findViewById(R.id.slider);
        Drawable thumb = MyApp.getContext().getResources().getDrawable(R.drawable.ic_add_white_24dp);
        slider.setThumb(thumb);
        thumb.mutate().setAlpha(0);
        container= (CardView)v.findViewById(R.id.rootView);
        tvPosition= (TextView) v.findViewById(R.id.tv_channel_number);
        tvValue = (TextView) v.findViewById(R.id.tv_value);
    }
}
like image 622
Wiktor Wardzichowski Avatar asked Oct 19 '22 01:10

Wiktor Wardzichowski


1 Answers

you must check that changes are made by user or not . you can do this with "fromUser" variable like this:

((ViewHolderSlider) holder).slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        holderSlider.tvValue.setText("" + progress);
        if(position!=RecyclerView.NO_POSITION) {
            if(seekBar.isShown() && fromUser)
                currentChannel.setValue(progress);
        }
    }
like image 77
saeed shahini Avatar answered Oct 23 '22 10:10

saeed shahini