onBackPressed(); 不起作用,除非我在代码中调用 super.onBackPressed(); 两次

huangapple go评论83阅读模式
英文:

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 -&gt; {
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(&quot;PREFS&quot;, MODE_PRIVATE).edit();
editor.putString(&quot;profileid&quot;, 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&lt;String&gt; mEvent;
private List&lt;Post&gt; 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(&quot;PREFS&quot;, Context.MODE_PRIVATE);
mPostId = sharedPreferences.getString(&quot;postid&quot;, &quot;none&quot;);
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new GridLayoutManager(getContext(), 3);
recyclerView.setLayoutManager(linearLayoutManager);
mPostList = new ArrayList&lt;&gt;();
mEventsImagesAdapter = new EventsImagesAdapter(getContext(), mPostList);
recyclerView.setAdapter(mEventsImagesAdapter);
((DrawerLocker) getActivity()).setDrawerLocked(true);
mSwipeRefreshLayout = view.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -&gt; {
mSwipeRefreshLayout.setRefreshing(true);
mySaves();
});
setBackArrow();
return view;
}
@Override
public void onDestroy() {
((DrawerLocker) getActivity()).setDrawerLocked(false);
super.onDestroy();
}
private void mySaves() {
mEvent = new ArrayList&lt;&gt;();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference(&quot;Attending Event&quot;);
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(&quot;READSAVES&quot;, String.valueOf(mEvent));
readSaves();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readSaves() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference(&quot;Posts&quot;);
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(&quot;SAVES&quot;, 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 -&gt; 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 .

huangapple
  • 本文由 发表于 2020年8月4日 17:52:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/63244331.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定