gpt4 book ai didi

java - 如何不间断地显示我的导航栏内容?

转载 作者:行者123 更新时间:2023-12-05 00:00:43 27 4
gpt4 key购买 nike

我从头开始构建了一个可自定义的抽屉导航(没有使用 Android Studio 提供的默认抽屉)。在我的天气应用程序的导航栏菜单中/image/SIjdx.jpg ,每当我在菜单上选择一个选项(比如设置)时,它都会显示该选项的内容以及底部导航 View 和我的 Activity 工具栏内容,其中包括导航汉堡包图标、编辑文本和搜索按钮( Activity 托管我的 3 个 fragment )破坏了应用程序并使其看起来非常丑陋,即 /image/gxj5n.jpg (从该屏幕截图来看,如果实现得当,整个内容应该是空的)。其他栏菜单选项的情况相同。我想要的只是一个空白的空间,我希望应用程序只显示导航栏内容而不显示其余内容。例子; /image/3Jtga.png请问我应该怎么做?

导航菜单的 View 由以下代码控制(第 185 行):

@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;
}

那里的“fragment ”代表我目前正在我的 Activity 中使用 fragment 的容器 View 来显示我知道肯定是错误的导航菜单内容,那么我应该用什么来替换?我缺乏丰富的经验,因为这是我第一次构建应用程序,我自己不知疲倦地花了 3 个小时试图找出被证明是流产的问题。

这是我的 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 navigation 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
}
}
}

如果您需要任何其他代码来调查问题,请告诉我。我只是想避免张贴太多

编辑:

我的旧 bottomtabs 导航图:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_nav"
app:startDestination="@id/firstFragment">

<fragment
android:id="@+id/firstFragment"
android:name="com.viz.lightweatherforecast.FirstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first" />
<fragment
android:id="@+id/secondFragment"
android:name="com.viz.lightpreciseweatherforecast.SecondFragment"
android:label="fragment_second"
tools:layout="@layout/fragment_second" />
<fragment
android:id="@+id/thirdFragment"
android:name="com.viz.lightpreciseweatherforecast.ThirdFragment"
android:label="fragment_third"
tools:layout="@layout/fragment_third" />
</navigation>

我的新导航条形图:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bar_nav"
app:startDestination="@id/firstFragment">

<fragment
android:id="@+id/firstFragment"
android:name="com.viz.lightweatherforecast.FirstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first" />
<fragment
android:id="@+id/settings_id"
android:name="com.viz.lightweatherforecast.Settings"
android:label="@string/settings"
tools:layout="@layout/settings" />
<fragment
android:id="@+id/ads_upgrade_id"
android:name="com.viz.lightweatherforecast.Upgrade"
android:label="@string/upgrade_to_remove_ads"
tools:layout="@layout/upgrade" />
<fragment
android:id="@+id/privacy_policy_id"
android:name="com.viz.lightweatherforecast.Privacy_Policy"
android:label="@string/privacy_policy"
tools:layout="@layout/privacy_policy"/>

</navigation>

最佳答案

您正在使用导航架构组件,因此 navController 是应该控制 fragment 事务的组件,您正在使用 BottomNavigationView 正确地执行此操作。

但在 navDrawer 中,您正在通过 supportFragmentManager 进行交易,这应该通过 navController 进行,因为两者处理导航的方式不同.

whenever I select an option on the menu(say settings), it displays the contents of the option along with the bottom navigation view

那是因为BottomNavView是activity的一部分,需要移动到fragment中;这需要更改应用程序的导航设计;为此,请更改您的应用导航,如下所示:

主导航:

<navigation
..... >

<fragment
android:name="......HomeFragment"/>

<fragment
android:name="......SettingFragment"/>

<fragment
android:name="......AdsUpgradeFragment"/>

<fragment
android:name="......PrivacyPolicyFragment"/>


</navigation>

HomeFragment 是应该包含 BottomNaviagtionView 而不是 Activity 的 fragment ;当您导航到 SettingFragment 时,navConroller 将替换 navHostFragment 中的整个 fragment ,因此 BottomNaviagtionView 将不会显示。

my Activity's Toolbar contents which comprises of the nav hamburgericon, the edittext and the search button(the activity hosting my 3fragments) which spoils the app and makes it look very ugly

BottomNaviagtionView 不同,您不能使用用作 supportActionBar 的 toolBar 来执行此操作,因为多次设置 supportActionBar 以更改其外观;会复制它;所以你必须接受一个工具栏;但是您可以隐藏/显示包含搜索按钮和 EditText 的布局,只要目的地发生变化:

navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
LinearLayout searchBar = findViewById(R.id.searchbar); // change searchbar according to the layout id that holds the search button and the EditText
if (destination.getId() == R.id.nav_home) {
searchBar.setVisibility(View.VISIBLE);

} else {
searchBar.setVisibility(View.GONE);
}

});

and yes they currently exit the app when clicking back

要退出应用程序,在任何 fragment 中按下底部后退按钮时,请使用 onCreateView() 中的 OnBackPressedDispatcher() 这些 fragment (在您的情况下为 SettingFragment、PrivacyPolicyFragment , & AdsUpgradeFragment):

并确保 appBarConfiguration 不引用这些 fragment ,以便可以显示向上按钮而不是汉堡。

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
// Exit the app when back is pressed
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
requireActivity().finishAndRemoveTask();
else requireActivity().finish();
}
});

此外,请确保您在 navController 中设置了 DrawerLayout 及其 navView:

NavigationView navView = findViewById(....);

appBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home) // remove up button from all these fragments >> Keep the up/back button in R.id.settings_id, R.id.settings_id, ads_upgrade_id, privacy_policy_id
.setOpenableLayout(drawer)
.build();

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);

并使 Home fragment 默认隐藏在 navDrawer 中:

navView.getMenu().findItem(R.id.nav_home).setVisible(false); // adjust R.id.nav_home to yours

更新

I currently have a single nav graph. The firstFragment represents thetoday, 2nd - hourly and 3rdI'm using is for my other weather tabs but the one you're suggestingis for the navbar menu, should I replace yours with mine or justcreate a new one for your suggestion?

您应该使用两个 navGraph,第一个用于我建议的主导航;第二个用于您已经使用的 BottomNavigationView 导航;那是因为我们将 BottomNavigationView 从 Activity 布局转移到了 main/home fragment 布局;和 it' recommended the BottomNavigationView should have a separate navGraph ;

因此,您现在需要两个 FragmentContainerView;第一个位于引用此答案中提供的 navGraph 的 Activity 布局中,第二个位于引用 BottomNavigationView 的原始 navGraph 的主 fragment 布局中。

示例:

关于java - 如何不间断地显示我的导航栏内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70544289/

27 4 0