Android Studio Java:如何从RecyclerView控制主Activity布局显隐
解决RecyclerView点击按钮显示Activity中布局的空指针问题
问题根源
你在ButtonRecyclerAdapter中手动创建MainMenu实例并调用show_confirmationLayout()的方式完全错误:
MainMenu mainMenu = new MainMenu(); mainMenu.show_confirmationLayout();
Activity的实例由Android系统负责创建和生命周期管理,手动new出来的实例不会执行onCreate()方法,也就不会初始化newGameConfirmationLayout变量,调用方法时自然会触发空指针异常。而直接在Activity内部调用show_confirmationLayout()能正常运行,是因为此时Activity实例已被系统初始化,newGameConfirmationLayout已经通过findViewById()完成绑定。
解决方案:接口回调(推荐,低耦合)
通过定义接口实现Adapter与Activity的解耦,让Activity响应Adapter中的按钮点击事件。
1. 在ButtonRecyclerAdapter中定义点击回调接口
public class ButtonRecyclerAdapter extends RecyclerView.Adapter<ButtonRecyclerAdapter.buttonHolder>{ private ArrayList<String> buttonNames; private OnButtonClickListener listener; // 定义回调接口 public interface OnButtonClickListener { void onNewGameClicked(); } // 修改构造方法,传入接口实例 public ButtonRecyclerAdapter(ArrayList<String> loginButtonNames, OnButtonClickListener listener) { this.buttonNames = loginButtonNames; this.listener = listener; } @NonNull @Override public buttonHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.button_block,parent,false); return new buttonHolder(view); } @Override public void onBindViewHolder(@NonNull buttonHolder holder, int position) { holder.button.setText(buttonNames.get(position)); holder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String buttonName = holder.button.getText().toString(); switch (buttonName){ case "NEW GAME": // 触发回调 listener.onNewGameClicked(); break; // 其他按钮的处理逻辑 } } }); } @Override public int getItemCount() { return buttonNames.size(); } public class buttonHolder extends RecyclerView.ViewHolder{ private Button button; public buttonHolder(@NonNull View itemView) { super(itemView); button = itemView.findViewById(R.id.buttonblock); } } }
2. 在MainMenu中实现回调并初始化Adapter
public class MainMenu extends AppCompatActivity { // ... 原有代码省略 ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_menu); // ... 原有初始化代码省略 ... // 初始化Adapter时传入回调 adapter = new ButtonRecyclerAdapter(buttonNames, new ButtonRecyclerAdapter.OnButtonClickListener() { @Override public void onNewGameClicked() { show_confirmationLayout(); } }); buttonRecyclerView.setAdapter(adapter); // ... 原有按钮点击逻辑省略 ... } // ... 原有方法省略 ... }
简化方案:强转Context(不推荐,高耦合)
如果只是快速测试,也可以直接将传入的Context强转为MainMenu实例,但这种方式会让Adapter与MainMenu紧密耦合,无法复用在其他Activity中:
// 在ButtonRecyclerAdapter的点击事件中修改 case "NEW GAME": if (context instanceof MainMenu) { ((MainMenu) context).show_confirmationLayout(); } break;
内容的提问来源于stack exchange,提问作者Nacho Novoa Mayo
相关产品推荐
相关产品推荐

