I make an Android app with the following functions: When opening the app, create a viewpager(VP) and add 3 rooms(3 fragments) to the VP. Each room adds 1 fragment (same deviceFragment) but different TAG and name. Each fragment will have 3 buttons placed in the RecyclerView. I use EventBus to receive click events on each button click.
My problem is that when I open the app for the first time, the app runs perfectly without any errors, but if I rotate the screen, when the app resumes, pressing the button will generate 2 DEVICE_CLICK events. If you rotate the screen again, it will generate 3 events and continue to increase. I want when I rotate the screen, the app will re-initialize and not generate multiple DEVICE_CLICK events.
Please help
public class MainActivity extends AppCompatActivity {
....
vpAdapter = new deviceVPAdapter(this);
vpAdapter.addFragment(new deviceFragment("Living_room", "0"));
vpAdapter.addFragment(new deviceFragment("Working_room", "1"));
vpAdapter.addFragment(new deviceFragment("Bath_room", "2"));
vpDevice.setOffscreenPageLimit(3);
vpDevice.setSaveEnabled(false);
vpDevice.setSaveFromParentEnabled(false);
vpDevice.setAdapter(vpAdapter);
}
//viewPagerAdapter
public class deviceVPAdapter extends FragmentStateAdapter {
private List<Fragment> listFrag;
public deviceVPAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
this.listFrag = new ArrayList<>();
}
@NonNull
@Override
public Fragment createFragment(int position) {
return listFrag.get(position);
}
public void addFragment(Fragment fm){
listFrag.add(fm);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
if(listFrag != null) return listFrag.size();
return 0;
}
@Override
public boolean containsItem(long itemId) {
return super.containsItem(itemId);
}
@Override
public long getItemId(int position) {
return listFrag.get(position).hashCode();
}
}
public class deviceFragment extends Fragment {
public String TAG;
private String pageName;
public deviceFragment(String pName, String pIndex){
TAG = pIndex;
pageName = pName;
}
@Nullable
@Override
public View onCreateView(...){
...
List<deviceInfo> listDevice = new ArrayList();
listDevice.add(new deviceInfo("sw 0");
listDevice.add(new deviceInfo("sw 1");
listDevice.add(new deviceInfo("sw 2");
dAdapter = new deviceAdapter(listDevice);
rcvDevice.setAdapter(dAdapter);
}
....
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvents(variousData data){
switch (data.getEventCode()){
...
case DEVICE_CLICK:
//this section called multi after rotate screen or os kill and resume
break;
}
}
@Override
public void onResume() {
super.onResume();
if(!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
@Override
public void onPause() {
super.onPause();
if(EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this);
}
}
//device adapter (recycler view) on fragment
public class deviceAdapter extends RecyclerView.Adapter<deviceAdapter.deviceViewHolder>{
List<deviceInfo> listDevice;
public deviceAdapter(List<deviceInfo> listDev) {
this.listDevice = listDev;
notifyDataSetChanged();
}
.....
public class deviceViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public deviceViewHolder(@NonNull DeviceItemLayoutBinding dBinding) {
super(dBinding.getRoot());
this.devBinding = dBinding;
devBinding.btnDevice.setOnClickListener(this);
}
@Override
public void onClick(View v) {
EventBus.getDefault().post(new variousData(DEVICE_CLICK, null, getLayoutPosition(), listDevice.get(getLayoutPosition())));
}
}
}
I tried checking in deviceAdapter and it only generates 1 event/click so the problem due deviceFragment. I think case 1: the fragment being created many times, case 2 is due to Eventbus being registered many times (but I checked and found nothing wrong).