英文:
onBackPressed(); doesn't work unless I call super.onBackPressed(); twice in code
问题
我遇到了onBackPressed();
方法的问题。我需要根据用户在调用onBackPressed();
时所在的Fragment
来更改BottomNavView
的图标。目前,我的代码无法实现这一点。我尝试了多种不同的方法来实现此代码,但都没有成功。所以我得到的两个最大的结果是,如果我两次调用super.onBackPressed();
,BNV图标
会更改,但是我的一个Fragment
中的图像会重复出现,我不知道为什么...
所以如果我取消其中一个onBackPressed();
,那么BNV图标就不会随onBackPressed();
而更改。
我在想也许我应该将onBackPressed();
中的instanceOf
更改为多态性
...我看到有人这样做而不是使用instanceOf
...我不知道这是否会解决我的问题。有人可以告诉我他们的看法吗?
也许我可以实现一个onBackPressedListener或fragmentListener
来使这段代码工作吗?
最奇怪的是,图像仅在我的一个Fragment
中重复出现...其他所有都没问题。
MainActivity
private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = menuItem -> {
switch (menuItem.getItemId()) {
case R.id.nav_home:
mSelectedFragment = new TabLayoutFragment();
break;
case R.id.nav_notifications:
seenNotification();
mSelectedFragment = new NotificationsFragment();
break;
case R.id.nav_profile:
SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", mFirebaseUser.getUid());
editor.apply();
mSelectedFragment = new ProfileFragment();
break;
case R.id.nav_save:
mSelectedFragment = new AttendingEventFragment();
break;
}
if (mSelectedFragment != null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, mSelectedFragment, null).addToBackStack(null).commit();
}
return true;
};
@Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof TabLayoutFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_home);
} else if (fragment instanceof AttendingEventFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_save);
} else if (fragment instanceof NotificationsFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_notifications);
} else if (fragment instanceof ProfileFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_profile);
}
super.onBackPressed();
}
EventFragment 这是唯一出现图像重复的地方...
public class AttendingEventFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private List<String> mEvent;
private List<Post> mPostList;
private String mPostId;
private EventsImagesAdapter mEventsImagesAdapter;
private FirebaseUser mFirebaseUser;
private TextView mNoEvents;
private ImageView mBackArrow;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_attending_event, container, false);
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mNoEvents = view.findViewById(R.id.no_events);
mBackArrow = view.findViewById(R.id.arrow_back);
SharedPreferences sharedPreferences = getContext().getSharedPreferences("PREFS", Context.MODE_PRIVATE);
mPostId = sharedPreferences.getString("postid", "none");
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new GridLayoutManager(getContext(), 3);
recyclerView.setLayoutManager(linearLayoutManager);
mPostList = new ArrayList<>();
mEventsImagesAdapter = new EventsImagesAdapter(getContext(), mPostList);
recyclerView.setAdapter(mEventsImagesAdapter);
((DrawerLocker) getActivity()).setDrawerLocked(true);
mSwipeRefreshLayout = view.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -> {
mSwipeRefreshLayout.setRefreshing(true);
mySaves();
});
setBackArrow();
return view;
}
@Override
public void onDestroy() {
((DrawerLocker) getActivity()).setDrawerLocked(false);
super.onDestroy();
}
private void mySaves() {
mEvent = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Attending Event");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
if (snapshot.hasChild(mFirebaseUser.getUid()))
mEvent.add(snapshot.getKey());
}
Log.d("READSAVES", String.valueOf(mEvent));
readSaves();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readSaves() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
for (String id : mEvent) {
if (post != null)
if (post.getPostid().equals(id)) {
mPostList.add(post);
}
}
}
Log.d("SAVES", mPostList.toString());
if (mPostList.size() == 0) {
mNoEvents.setVisibility(View.VISIBLE);
} else {
mNoEvents.setVisibility(View.GONE);
}
mEventsImagesAdapter.notifyDataSetChanged();
Collections.reverse(mPostList);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
private void setBackArrow() {
mBackArrow.setOnClickListener(v -> getActivity().getSupportFragmentManager().popBackStack());
}
@Override
public void onRefresh() {
mySaves();
}
}
英文:
I am having trouble with the onBackPressed();
method. I need the icons of the BottomNavView
to change depending on what Fragment
the user lands on calling onBackPressed();
. That isn't happening right now with the code that I currently have. I've tried several different ways to implement this code, but nothing has worked. So the two biggest outcomes I am getting is if I call super.onBackPressed();
twice the BNV icons
change, BUT the images in one of my Fragments
come back duplicated and I don't know why...
So if I get rid of one of the onBackPressed();
the BNV icons just straight up don't change with onBackPressed();
I was thinking that maybe I should change the instanceOf in onBackPressed();
to polymorphism
... I have seen that that is something that people have done instead of instanceOf
… I don't know if that will solve my problem. Could someone let me know what they think?
Is there maybe a onBackPressedListener or fragmentListener
that I could implement to make this code work?
The strangest thing is that the images come back doubled for only ONE of my fragments... All the others are okay.
MainActivity
private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = menuItem -> {
switch (menuItem.getItemId()) {
case R.id.nav_home:
mSelectedFragment = new TabLayoutFragment();
break;
case R.id.nav_notifications:
seenNotification();
mSelectedFragment = new NotificationsFragment();
break;
case R.id.nav_profile:
SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", mFirebaseUser.getUid());
editor.apply();
mSelectedFragment = new ProfileFragment();
break;
case R.id.nav_save:
mSelectedFragment = new AttendingEventFragment();
break;
}
if (mSelectedFragment != null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, mSelectedFragment, null).addToBackStack(null).commit();
}
return true;
};
@Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof TabLayoutFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_home);
} else if (fragment instanceof AttendingEventFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_save);
} else if (fragment instanceof NotificationsFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_notifications);
} else if (fragment instanceof ProfileFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_profile);
}
super.onBackPressed();
}
EventFragment THIS IS THE ONE WHERE THE IMAGES ARE COMING BACK DOUBLED. ONLY ONE WHERE IT HAPPENS...
public class AttendingEventFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private List<String> mEvent;
private List<Post> mPostList;
private String mPostId;
private EventsImagesAdapter mEventsImagesAdapter;
private FirebaseUser mFirebaseUser;
private TextView mNoEvents;
private ImageView mBackArrow;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_attending_event, container, false);
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mNoEvents = view.findViewById(R.id.no_events);
mBackArrow = view.findViewById(R.id.arrow_back);
SharedPreferences sharedPreferences = getContext().getSharedPreferences("PREFS", Context.MODE_PRIVATE);
mPostId = sharedPreferences.getString("postid", "none");
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new GridLayoutManager(getContext(), 3);
recyclerView.setLayoutManager(linearLayoutManager);
mPostList = new ArrayList<>();
mEventsImagesAdapter = new EventsImagesAdapter(getContext(), mPostList);
recyclerView.setAdapter(mEventsImagesAdapter);
((DrawerLocker) getActivity()).setDrawerLocked(true);
mSwipeRefreshLayout = view.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -> {
mSwipeRefreshLayout.setRefreshing(true);
mySaves();
});
setBackArrow();
return view;
}
@Override
public void onDestroy() {
((DrawerLocker) getActivity()).setDrawerLocked(false);
super.onDestroy();
}
private void mySaves() {
mEvent = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Attending Event");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
if (snapshot.hasChild(mFirebaseUser.getUid()))
mEvent.add(snapshot.getKey());
}
Log.d("READSAVES", String.valueOf(mEvent));
readSaves();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readSaves() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
for (String id : mEvent) {
if (post != null)
if (post.getPostid().equals(id)) {
mPostList.add(post);
}
}
}
Log.d("SAVES", mPostList.toString());
if (mPostList.size() == 0) {
mNoEvents.setVisibility(View.VISIBLE);
} else {
mNoEvents.setVisibility(View.GONE);
}
mEventsImagesAdapter.notifyDataSetChanged();
Collections.reverse(mPostList);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
private void setBackArrow() {
mBackArrow.setOnClickListener(v -> getActivity().getSupportFragmentManager().popBackStack());
}
@Override
public void onRefresh() {
mySaves();
}
}
答案1
得分: 1
super.onBackPressed()
会调用返回按键的期望行为。而你的代码中调用了两次。你的代码应该如下所示。
@Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
return;
}
super.onBackPressed();
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof TabLayoutFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_home);
} else if (fragment instanceof AttendingEventFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_save);
} else if (fragment instanceof NotificationsFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_notifications);
} else if (fragment instanceof ProfileFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_profile);
}
}
现在如果你通过 `#findFragmentById` 从堆栈中获取正确的片段,它应该可以工作。
英文:
super.onBackPressed()
will call the desired behavior of back press . And you are calling twice in your code. your code should look like below .
@Override
public void onBackPressed () {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
return;
}
super.onBackPressed();
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof TabLayoutFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_home);
} else if (fragment instanceof AttendingEventFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_save);
} else if (fragment instanceof NotificationsFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_notifications);
} else if (fragment instanceof ProfileFragment) {
mBottomNavigationView.setSelectedItemId(R.id.nav_profile);
}
}
Now if you get the correct fragment from stack by #findFragmentById
it should work .
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论