How to save the state of a RecyclerView row element?

I have a recyclerview that populates data from an SQL database. Now each line in recyclerview has a search bar, which when moving shows that it is moving in text mode inside the same line. The problem is that when I scroll up or down the recyclerview and then go back to the first modified line, the search drum returns to its default position. How can I make him keep a new position? In normal actions / fragments, I use life cycle methods like "onPause" to save / restore state. Here we have onAttachedToRecyclerView, I think it should solve my problem, but I don’t know exactly how to do it.

EDIT : here is the complete simple application file I am working on to test this issue.

MainActivity.class

public class MainActivity extends AppCompatActivity {
    private List<Score> scoreList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MyAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

    mAdapter = new MyAdapter(scoreList);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(mAdapter);

    prepareScoreData();
}

private void prepareScoreData() {
    Score score = new Score("title", 5);
    scoreList.add(score);

    for(int i= 0; i<1000; i++){
        score = new Score("title", 5);
        scoreList.add(score);
    }

    mAdapter.notifyDataSetChanged();
}
}

Myadapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Score> scoresList;

public class MyViewHolder extends RecyclerView.ViewHolder {
    TextView title, scoreView;
    SeekBar seekbar;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.title);
        scoreView = (TextView) view.findViewById(R.id.score);
        seekbar = (SeekBar) view.findViewById(R.id.seekbar);
    }
}


public MyAdapter(List<Score> scoresList) {
    this.scoresList = scoresList;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item, parent, false);

    return new MyViewHolder(itemView);
}


@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    final Score score = scoresList.get(position);
    holder.title.setText(score.getTitle());

    if (!score.getProgressed()) {
        holder.seekbar.setProgress(0) ;
    } else {
        holder.seekbar.setProgress(score.getSeekbarProgress());
    }

    holder.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            holder.scoreView.setText(String.valueOf(i));
            score.setSeekbarProgress(i);
            score.setProgressed(true);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    });
}

@Override
public int getItemCount() {
    return scoresList.size();
}
}

Grade Class

public class Score {
private String title;
int seekbarProgress;
boolean progressed;

public Score() {
}

public Score(String title,int seekbarProgress) {
    this.title = title;
    this.seekbarProgress = seekbarProgress;
}

public void setProgressed(boolean progressed) {
    this.progressed = progressed;
}



public void setTitle(String title) {
    this.title = title;
}

public void setSeekbarProgress(int seekbarProgress) {
    this.seekbarProgress = seekbarProgress;
}

public String getTitle() {
    return title;
}

public int getSeekbarProgress() {
    return seekbarProgress;
}

public boolean getProgressed() {
    return progressed;
}
}

MainActivity_Layout

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.moaness.tut_recyclerview.MainActivity">

    <!-- A RecyclerView with some commonly used attributes -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    </RelativeLayout>

item.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="60dp"
    android:paddingBottom="60dp"
    android:layout_marginBottom="10dp"
    android:clickable="true"
    android:background="#f2f2f2"
    android:orientation="vertical">

    <TextView
        android:id="@+id/title"
        android:text="title"
        android:textColor="@color/title"
        android:textSize="16dp"
        android:paddingTop="16dp"
        android:textStyle="bold"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/score"
        android:text="score"
        android:layout_below="@+id/title"
        android:textSize="16dp"
        android:paddingBottom="16dp"
        android:textStyle="bold"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/score"
        android:id="@+id/seekbar"
        />

</RelativeLayout>
+4
source share
1 answer

If you use recyclerview, you need to maintain the state of each row, which means that if you check the condition (for example, if) at any stage of the recyclerview element (in the adapter class recycliewiew), you also need to handle another. I can send you a code snippet so that you have a good idea for the recycliewiew adapter.

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
    List<ViewHolder> holders = new ArrayList<ViewHolder>();
    private ArrayList<ContactModel> arrayList = new ArrayList<>();
    private Context context;
    private LayoutInflater inflater;

    public void clearAdapter() {
        arrayList.clear();
        notifyDataSetChanged();
    }

    public ContactsAdapter(Context context, ArrayList<ContactModel> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    public void setList(ArrayList<ContactModel> listSearch) {
        this.arrayList = listSearch;
        notifyItemRangeChanged(0, listSearch.size());
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.custom_row_for_contacts, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        holders.add(viewHolder);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final ContactModel current = this.arrayList.get(position);
        holder.txtDriverName.setText(current.getName());
        holder.txtDriverPhone.setText(current.getPhone());
        if (current.getImgUrl().length() > 0) {
            String urlLicenceThumb = UrlEndPoints.parentUrl + current.getImgUrl();
            Glide.with(context).load(urlLicenceThumb).error(R.mipmap.ic_launcher).into(holder.imgDriver);
        } else {
           Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imgDriver);
        }
    }

    public void delete(int position) {
        arrayList.remove(position);
        notifyItemRemoved(position);
    }

    @Override
    public int getItemCount() {
        return (null != arrayList ? arrayList.size() : 0);
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        private TextView txtDriverName, txtDriverPhone;
        private CircleImageView imgDriver;
        private Button btnInvite;
        private CheckBox chkAdd;

        public ViewHolder(View itemView) {
            super(itemView);
            chkAdd = (CheckBox) itemView.findViewById(R.id.chkAdd);
            imgDriver = (CircleImageView) itemView.findViewById(R.id.imgDriver);
            txtDriverName = (TextView)itemView.findViewById(R.id.txtDriverName);
            txtDriverPhone = (TextView)     itemView.findViewById(R.id.txtDriverPhone);
            btnInvite = (Button) itemView.findViewById(R.id.btnInvite);
        }
    }
}
+10
source

Source: https://habr.com/ru/post/1651137/


All Articles