Android双Activity中RecyclerView仅显示一条数据的问题排查求助
问题:RecyclerView仅显示一条数据的排查与解决
我要做一个包含两个Activity的简单应用:Activity A(MainActivity)带RecyclerView,Activity B(UploadActivity)负责上传EditText的输入数据。现在RecyclerView创建和数据传递功能正常,但列表只能显示一条数据,求排查错误原因。
相关代码
包含RecyclerView的Activity A(MainActivity)
public class MainActivity extends AppCompatActivity { private ArrayList<MainData> list; private MainAdapter adapter; private RecyclerView recyclerView; private LinearLayoutManager linearLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.rv); linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); list = (ArrayList<MainData>) getIntent().getSerializableExtra("list"); adapter = new MainAdapter(list); recyclerView.setAdapter(adapter); adapter.notifyDataSetChanged(); }
负责上传数据的Activity B(UploadActivity)
public class upload extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_upload); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(upload.this, MainActivity.class); ArrayList<MainData> list = new ArrayList<>(); EditText edit = (EditText) findViewById(R.id.edittext_name); EditText edit_main = (EditText) findViewById(R.id.edittext_main); list.add(new MainData(edit.getText().toString(), edit_main.getText().toString())); intent.putExtra("list",list); startActivity(intent); finish(); } }); }
Adapter代码
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.CustomViewHolder> { private ArrayList<MainData> list; public MainAdapter(ArrayList<MainData> list) { this.list = list; } @NonNull @Override public MainAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false); CustomViewHolder holder = new CustomViewHolder(view); return holder; } @Override public void onBindViewHolder(@NonNull MainAdapter.CustomViewHolder holder, int position) { //holder.iv_profile.setImageResource(list.get(position).getIv_profile()); holder.tv_name.setText(list.get(position).getTv_name()); holder.tv_content.setText(list.get(position).getTv_content()); holder.itemView.setTag(position); } @Override public int getItemCount() { return (null != list ? list.size() : 0); } public void remove(int position) { try { list.remove(position); notifyItemRemoved(position); } catch (IndexOutOfBoundsException ex) { ex.printStackTrace(); } } public class CustomViewHolder extends RecyclerView.ViewHolder { protected ImageView iv_profile; protected TextView tv_name; protected TextView tv_content; public CustomViewHolder(@NonNull View itemView) { super(itemView); this.iv_profile = (ImageView) itemView.findViewById(R.id.iv_profile); this.tv_name = (TextView) itemView.findViewById(R.id.tv_name); this.tv_content = (TextView) itemView.findViewById(R.id.tv_content); } } }
错误原因分析
每次从UploadActivity跳转到MainActivity时,你都新建了一个ArrayList,只添加当前输入的一条数据再传递。这意味着每次跳转都会完全重置数据列表,而不是在原有列表基础上追加新数据。同时,MainActivity每次被启动都会创建新实例,之前的列表数据不会被保留。
解决方案
方案1:用单例存储全局列表(简单快速)
创建单例类统一管理数据列表,让所有Activity共享同一个实例:
public class DataManager { private static DataManager instance; private ArrayList<MainData> dataList; private DataManager() { dataList = new ArrayList<>(); } public static synchronized DataManager getInstance() { if (instance == null) { instance = new DataManager(); } return instance; } public ArrayList<MainData> getDataList() { return dataList; } public void addData(MainData data) { dataList.add(data); } }
修改UploadActivity的点击事件:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EditText edit = (EditText) findViewById(R.id.edittext_name); EditText edit_main = (EditText) findViewById(R.id.edittext_main); // 向全局列表添加新数据 DataManager.getInstance().addData(new MainData(edit.getText().toString(), edit_main.getText().toString())); Intent intent = new Intent(upload.this, MainActivity.class); startActivity(intent); finish(); } });
修改MainActivity的初始化逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.rv); linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); // 获取全局共享的列表实例 list = DataManager.getInstance().getDataList(); adapter = new MainAdapter(list); recyclerView.setAdapter(adapter); }
方案2:用ActivityResultContracts传递数据(符合Android规范)
让MainActivity启动UploadActivity,待UploadActivity返回数据后,MainActivity将新数据追加到原有列表:
1. 修改MainActivity的跳转逻辑
// 在MainActivity中添加跳转至UploadActivity的按钮事件 Button goUploadBtn = findViewById(R.id.btn_go_upload); goUploadBtn.setOnClickListener(v -> { registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { MainData newData = (MainData) result.getData().getSerializableExtra("new_data"); if (newData != null) { list.add(newData); adapter.notifyItemInserted(list.size() - 1); } } }).launch(new Intent(this, upload.class)); });
2. 修改UploadActivity的返回逻辑
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EditText edit = (EditText) findViewById(R.id.edittext_name); EditText edit_main = (EditText) findViewById(R.id.edittext_main); MainData newData = new MainData(edit.getText().toString(), edit_main.getText().toString()); Intent intent = new Intent(); intent.putExtra("new_data", newData); setResult(RESULT_OK, intent); finish(); } });
3. 确保MainActivity的列表初始化正确
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.rv); linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); // 初始化空列表,避免空指针 if (list == null) { list = new ArrayList<>(); } adapter = new MainAdapter(list); recyclerView.setAdapter(adapter); }
额外注意事项
- 必须确保
MainData类实现Serializable接口,否则无法通过Intent传递:
public class MainData implements Serializable { private String tv_name; private String tv_content; public MainData(String tv_name, String tv_content) { this.tv_name = tv_name; this.tv_content = tv_content; } // getter方法 public String getTv_name() { return tv_name; } public String getTv_content() { return tv_content; } }
- 如果需要重启App后保留数据,可使用SharedPreferences或Room数据库实现持久化存储。
内容的提问来源于stack exchange,提问作者Chanyoung
相关产品推荐
相关产品推荐

