You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Activity向RecyclerView适配器回传数据并更新对应行

从新Activity向RecyclerView适配器回传对象并更新对应行的实现方案

好的,我来帮你解决这个问题——要实现从新Activity回传对象并更新RecyclerView对应行,咱们可以分几步来做,我会结合你给出的适配器代码框架来讲解,推荐用Android官方现在主推的Activity Result API(毕竟startActivityForResult已经被弃用啦):

1. 准备工作:让Movie类支持Intent传递

首先,你的Movie对象需要能在Activity之间传递,所以得实现Parcelable接口(比Serializable效率更高):

public class Movie implements Parcelable {
    private String title;
    private String year;
    private String genre;

    // 构造函数、getter、setter方法...

    // Parcelable接口实现代码
    protected Movie(Parcel in) {
        title = in.readString();
        year = in.readString();
        genre = in.readString();
    }

    public static final Creator<Movie> CREATOR = new Creator<Movie>() {
        @Override
        public Movie createFromParcel(Parcel in) {
            return new Movie(in);
        }

        @Override
        public Movie[] newArray(int size) {
            return new Movie[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(title);
        dest.writeString(year);
        dest.writeString(genre);
    }
}

2. 在原Activity注册Activity Result Launcher

假设你的RecyclerView所在的原Activity是MoviesActivity,这里需要注册一个ActivityResultLauncher来接收新Activity返回的数据:

public class MoviesActivity extends AppCompatActivity {
    private MoviesAdapter moviesAdapter;
    private ActivityResultLauncher<Intent> updateMovieLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movies);

        // 初始化RecyclerView和适配器(你的原有代码)
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        moviesAdapter = new MoviesAdapter(yourMoviesList);
        recyclerView.setAdapter(moviesAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        // 注册Launcher,用于接收返回数据
        updateMovieLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                    // 获取返回的修改后的Movie对象和对应位置
                    Movie updatedMovie = result.getData().getParcelableExtra("UPDATED_MOVIE");
                    int position = result.getData().getIntExtra("MOVIE_POSITION", -1);

                    if (updatedMovie != null && position != -1) {
                        // 调用适配器的方法更新对应行
                        moviesAdapter.updateMovieAtPosition(position, updatedMovie);
                    }
                }
            }
        );
    }

    // 给适配器提供Launcher的调用能力(或者你也可以把Launcher通过构造函数传给适配器)
    public ActivityResultLauncher<Intent> getUpdateMovieLauncher() {
        return updateMovieLauncher;
    }
}

3. 在适配器的ViewHolder中设置点击事件,启动新Activity

修改你的MoviesAdapter,在MyViewHolder中添加点击事件,传递当前行的位置和Movie对象到新Activity:

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {
    private List<Movie> moviesList;

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

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

        public MyViewHolder(View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.title);
            year = itemView.findViewById(R.id.year);
            genre = itemView.findViewById(R.id.genre);
            linearLayout = itemView.findViewById(R.id.linear_layout); // 假设你的根布局是这个

            // 设置行点击事件
            itemView.setOnClickListener(v -> {
                int position = getAdapterPosition();
                // 确保位置有效,避免RecyclerView回收导致的异常
                if (position != RecyclerView.NO_POSITION) {
                    Movie currentMovie = moviesList.get(position);
                    Intent intent = new Intent(v.getContext(), UpdateMovieActivity.class);
                    // 传递位置和当前Movie对象
                    intent.putExtra("MOVIE_POSITION", position);
                    intent.putExtra("CURRENT_MOVIE", currentMovie);

                    // 调用原Activity的Launcher启动新Activity
                    ((MoviesActivity) v.getContext()).getUpdateMovieLauncher().launch(intent);
                }
            });
        }
    }

    // 添加更新指定位置数据的方法
    public void updateMovieAtPosition(int position, Movie updatedMovie) {
        if (position >= 0 && position < moviesList.size()) {
            moviesList.set(position, updatedMovie);
            // 只更新对应行,比notifyDataSetChanged效率更高
            notifyItemChanged(position);
        }
    }

    // 你的onCreateViewHolder、onBindViewHolder、getItemCount方法...
}

4. 在新Activity中处理数据并返回结果

假设你的新Activity是UpdateMovieActivity,处理完数据后,把修改后的Movie对象和位置返回给原Activity:

public class UpdateMovieActivity extends AppCompatActivity {
    private Movie currentMovie;
    private int position;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_movie);

        // 获取原Activity传递过来的数据
        currentMovie = getIntent().getParcelableExtra("CURRENT_MOVIE");
        position = getIntent().getIntExtra("MOVIE_POSITION", -1);

        // 这里写你的业务逻辑,比如修改Movie的属性...

        // 假设点击保存按钮返回结果
        Button saveBtn = findViewById(R.id.save_btn);
        saveBtn.setOnClickListener(v -> {
            // 构造修改后的Movie对象
            Movie updatedMovie = new Movie(currentMovie.getTitle(), "2024", currentMovie.getGenre()); // 示例修改

            // 准备返回的Intent
            Intent resultIntent = new Intent();
            resultIntent.putExtra("UPDATED_MOVIE", updatedMovie);
            resultIntent.putExtra("MOVIE_POSITION", position);
            // 设置结果码为RESULT_OK,表示成功返回
            setResult(RESULT_OK, resultIntent);
            // 关闭当前Activity
            finish();
        });
    }
}

额外注意点

  • 一定要检查getAdapterPosition()的返回值是否为RecyclerView.NO_POSITION,避免RecyclerView item被回收后点击导致的异常。
  • 用notifyItemChanged(position)而不是notifyDataSetChanged(),前者只会刷新指定行,性能更优。
  • 如果你的项目还在使用旧的startActivityForResult,可以替换为上述的Activity Result API,它是官方推荐的替代方案。

内容的提问来源于stack exchange,提问作者user1382802

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:17:38