java - 如何正确实现抽屉导航中的顶部后退按钮?

标签 java android navigation-drawer back-button

我目前正在尝试向我的天气应用程序添加抽屉导航,因此我观看了 YouTube 教程并能够按照我想要的方式实现它,直到我意识到 我观看的教程没有涵盖如何实现上/上背部 抽屉导航按钮,事实上,我目前无法返回 打开任何导航选项卡后我的默认 fragment 。我搜了几个 寻找有关如何实现顶部背面的教程的网站和 YouTube 视频 按钮,但尚未看到/无法找到它。我也搜索了这个网站,仍然 在这里还没有找到有类似问题的人。请问有人可以帮忙吗?

这是我的应用程序当前的屏幕截图:/image/SeSjV.png但如果我打开任何导航栏选项(即设置)并单击“返回”,我将无法返回到显示天气的默认 fragment 。它也没有后退按钮。

目前,单击“返回”只会退出应用程序。

这是我尝试过的唯一代码,但它不起作用:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (item.getItemId() == android.R.id.home) {
        int backStackCount = fragmentManager.getBackStackEntryCount();//check currently how many frags loaded
        if (backStackCount > 0) {
            fragmentManager.popBackStack(); //go back to previously loaded fragment
        }   
    }

    return super.onOptionsItemSelected(item);
}

它给出了以下错误:

error: cannot find symbol int backStackCount = fragmentManager.getBackStackEntryCount();//check currently how many frags loaded

这是我的 Activity 代码:

public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    private DrawerLayout drawer;
    // Last update time, click sound, search button, search panel.
    TextView timeField;
    MediaPlayer player;
    ImageView Search;
    EditText textfield;
    // For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
    ConstraintLayout constraintLayout;
    public static int count = 0;
    int[] drawable = new int[]{R.drawable.dubai, R.drawable.norway, R.drawable.eiffel_tower, R.drawable.hong_kong, R.drawable.statue_of_liberty,
            R.drawable.beijing, R.drawable.chicago, R.drawable.colombia, R.drawable.vienna,R.drawable.tokyo};
    Timer _t;

    private WeatherDataViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        // use home activity layout.

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Allow activity to make use of the toolbar

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);

        // Trigger action to open & close nevigation drawer
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
                , R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        timeField = findViewById(R.id.textView9);
        Search = findViewById(R.id.imageView4);
        textfield = findViewById(R.id.textfield);
        //  find the id's of specific variables.

        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
        // host 3 fragments along with bottom navigation.
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();
        NavigationUI.setupWithNavController(bottomNavigationView, navController);

        // Make hourly & daily tab unusable
        bottomNavigationView.setOnNavigationItemSelectedListener(item -> {

            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            }
            return false;
        });

        navController.addOnDestinationChangedListener((controller, destination, arguments) -> navController.popBackStack(destination.getId(), false));

        // For scheduling background image change
        constraintLayout = findViewById(R.id.layout);
        constraintLayout.setBackgroundResource(R.drawable.dubai);
        _t = new Timer();
        _t.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // run on ui thread
                runOnUiThread(() -> {
                    if (count < drawable.length) {

                        constraintLayout.setBackgroundResource(drawable[count]);
                        count = (count + 1) % drawable.length;
                    }
                });
            }
        }, 5000, 5000);

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // make click sound when search button is clicked.
                player = MediaPlayer.create(HomeActivity.this, R.raw.click);
                player.start();

                getWeatherData(textfield.getText().toString().trim());
                // make use of some fragment's data

                Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
                if (currentFragment instanceof FirstFragment) {
                    FirstFragment firstFragment = (FirstFragment) currentFragment;
                    firstFragment.getWeatherData(textfield.getText().toString().trim());
                } else if (currentFragment instanceof SecondFragment) {
                    SecondFragment secondFragment = (SecondFragment) currentFragment;
                    secondFragment.getWeatherData(textfield.getText().toString().trim());
                } else if (currentFragment instanceof ThirdFragment) {
                    ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
                    thirdFragment.getWeatherData(textfield.getText().toString().trim());
                }
            }

            private void getWeatherData(String name) {

                ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

                Call<Example> call = apiInterface.getWeatherData(name);

                call.enqueue(new Callback<Example>() {
                    @Override
                    public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {

                        try {
                            assert response.body() != null;
                            timeField.setVisibility(View.VISIBLE);
                            timeField.setText("First Updated:" + " " + response.body().getDt());
                        } catch (Exception e) {
                            timeField.setVisibility(View.GONE);
                            timeField.setText("First Updated: Unknown");
                            Log.e("TAG", "No City found");
                            Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                        t.printStackTrace();
                    }

                });
            }

        });
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings_id:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
                        new Settings()).commit();
                break;
            case R.id.ads_upgrade_id:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
                        new Upgrade()).commit();
                break;
            case R.id.privacy_policy_id:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
                        new Privacy_Policy()).commit();
                break;
        }
        drawer.closeDrawer(GravityCompat.START);

        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
            // Open/close drawer animation
        }
    }

最佳答案

if (item.getItemId() == android.R.id.home) {
    int backStackCount = fragmentManager.getBackStackEntryCount();//check currently how many frags loaded
    if (backStackCount > 0) {
        fragmentManager.popBackStack(); //go back to previously loaded fragment
    }   
}

Currently, clicking back only exits the app.

使用popBackStack()将弹出后退堆栈,使您的应用程序存在,但您只需返回到默认 fragment 即可。

要解决此问题,您需要更改抽屉式汉堡按钮的行为,以便有时可以使用它来打开抽屉式 navView 布局,而其他时候则可以返回到默认 fragment ;后者是当您想添加顶部后退按钮时。

how I can implement the up/top back button for the nav drawer

这需要访问 setToolbarNavigationClickListener方法使您能够为汉堡点击添加监听器。

在这种情况下,您需要根据需要返回主 fragment ,在 onCreate() 方法中添加:

toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Enable the functionality of opening the side drawer, when the burger icon is clicked
        toggle.setDrawerIndicatorEnabled(true); // Show the burger icon & enable the drawer funcionality
        navController.navigate(R.id.home); // Back to default fragment (replace home with your default fragment id in the navGraph)
    }
});

剩下的部分是当你想转到某个 fragment 时显示后退按钮

并使用toggle.setDrawerIndicatorEnabled()来启用/禁用单击主页/汉堡图标时打开/关闭抽屉的功能

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
    @Override
    public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {

        // Repeat this condition for all the Fragments that you want to show the back button
        if (destination.getId() == R.id.settings_id) { // replace `settings_id` with your fragment id in the navGraph that you want to show the back button
            // Disable the functionality of opening the side drawer, when the burger icon is clicked & show the UP button instead
            toggle.setDrawerIndicatorEnabled(false);

        } 

    }
});

关于java - 如何正确实现抽屉导航中的顶部后退按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70455347/

相关文章:

android获取zip文件中文件的压缩大小

android - 抽屉导航上出现灰色条

flutter - 没有应用栏的抽屉 Flutter

java - 使用 iText 将 HTML 转换为 PDF

java - 结合 Neo4j、Spring Data 和 Neo4j 谓词

android - 将视频设置为背景

java - 客户端上的表同步监听器上的 Realm 对象服务器 (android)

java - 使用 mockito 抛出运行时异常时测试是否抛出自定义异常

java - lucene,如何一起使用 SearcherManager 和 SearcherLifetimeManager

Android 汉堡菜单和返回箭头