简体   繁体   中英

Passing data from an activity back to recyclerview adapter

How can I pass data from an Activity back to the RecyclerView adapter. I've clicked one of the row in the recycler view and started a new activity. From the new activity how can I pass an object back to adapter and update the row from where I've started the activity

    public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

    private List<Movie> moviesList;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;
        LinearLayout layout;

        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
            layout = (LinearLayout) view.findViewById(R.id.layout);
        }
    }

    public MoviesAdapter(List<Movie> moviesList) {
        this.moviesList = moviesList;
    }

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

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Movie movie = moviesList.get(position);
        holder.title.setText(movie.getTitle());
        holder.genre.setText(movie.getGenre());
        holder.year.setText(movie.getYear());
        holder.layout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mContext.startActivity(new Intent(mContext, MovieDetailsActivity.class));   
                    }
                });
    }

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

From the new Activity I've created I'll edit the movie details and once clicked OK I need to pass the Movie object back to adapter and update the corresponding row.

Yes it is possible, first of all you need to implement a method to add an element in your adapter, let's say void addItem(Movie movie);

Then, you need to get your data back from your previous activity.

There you have multiple solution. The most obvious one, given the code you've shown us would be to make your Movie class Parcelable . When your movie has been extended to Parcelable I'll just give you this link as I'm not the best person to explain Parcelables to you :/) you will be able to bundle it to your activity .

So, you have your adapter in your first activity (we will call it MainActivity ) and you want to add a Movie from your second activity (let's call it SecondActivity ) What you'll need to do is open your SecondActivity "for result" which mean that you're expecting a result coming from this activity.

Once in your SecondActivity do whatever logic you need to have a new Movie to add and return it to your MainActivity by putting it in your result.

Here is a link about activities and results

Your final code will look like something like this

MainActivity

public static String MOVIE_REQUEST = "movie_request";
@Override
protected void onCreate(Bundle savedInstance){
     ...
        previous logic
     ...

     recyclerView.setAdapter(mAdapter);

     ...
        rest of the logic of your activity
     ...
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MOVIE_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            Movie movie = (Movie)data.getParcelableExtra(SecondActivity.MOVIE_EXTRA);
            mAdapter.addItem(movie);
        }
    }
}

Adapter

public void addItem(Movie movie){
    movieList.add(movie);
    //Your code should be way better than this anwser btw) notifyDatasetChanged isn't the best way to proceed
    notifyDatasetChanged();
}

SecondActivity

public static final String MOVIE_EXTRA = "movie_extra";
private void sendMovie(Movie movie){
    Intent data = new Intent();
    data.putExtra(MOVIE_EXTRA, movie);
    //At this point you're returning your result to your first activity
    setResult(RESULT_OK, data);
}

And you're done, you should have gotten a new movie from your second activity

Regards, Matthieu

Create a boolean in your model name it isSelected , once clicked on that object make it true , and in onBindView method of RecyclerView make a check if object isSelected is true then perform selected action as you want to display.

@Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Movie movie = moviesList.get(position);
        holder.title.setText(movie.getTitle());
        holder.genre.setText(movie.getGenre());
        holder.year.setText(movie.getYear());
        if(movie.isSelected()){
        holder.layout.setBackgroundColor(Color.GRAY);
        }
        holder.layout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        movie.setSelected(true);
                        notifyDatasetChanged();
                        mContext.startActivity(new Intent(mContext, MovieDetailsActivity.class));   
                    }
                });
    }

declare your adapter activity singleTask in manifest and then when you open new activity from adapter on click of item, pass the int position of item in second activity, then in second activity call first activity using intent like this:

 public void callFirst()
{
Intent intent =new Intent(this, FirstAdatperActivity.classs);
// pass position which we was bring from first activity...
intent.putExtra("position", position);
startActivity(intent);
finish();
}

then you will get result in onNewIntent() method you can override in your first activity and get intent data position and refresh adapter

recentAdapter.notifyItemChanged(postion, object);

in other way you can call second activity using this:

Intent intent =new Intent(this, SecondActvity.class);
intent,putExtra("pos",postion);
startActivityForResult(intent, 101);

and from second activity

Intent intent =new Intent(this, SecondActvity.class);
intent,putExtra("pos",postion);
setresult(101);

then you will get response in onActivityResult with position in intent bundle data , so you cal refresh your adapter from there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM