我从头开始构建了一个可定制的导航抽屉(没有利用Android Studio提供的默认抽屉)。在我的天气应用程序的导航栏菜单https://i.stack.imgur.com/SIjdx.jpg,中,每当我选择菜单上的一个选项(比如设置),它就会显示选项的内容,以及底部的导航视图和我的活动工具栏内容,其中包括导航汉堡图标、编辑文本和搜索按钮(托管我的3个片段的活动),这会破坏应用程序,使其看起来非常难看,即https://i.stack.imgur.com/gxj5n.jpg(从那个截图来看,如果实施良好,整个内容应该是空的)。其他栏菜单选项的情况也是如此。我想要的只是一个空白的工作空间,我希望该应用程序只显示导航栏的内容,没有其余的。例子;https://i.stack.imgur.com/3Jtga.png,请告诉我该怎么做?
导航菜单的视图由以下代码控制(第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”表示我当前正在使用我的活动上的fragment的容器视图来显示导航菜单内容,我知道这些内容肯定是错误的,那么我应该在replace中使用什么呢?我缺乏丰富的经验,因为这是我第一次开发应用程序,我花了3个小时孜孜不倦地独自尝试解决这个问题,结果证明失败了。
这是我的活动代码:
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
}
}
}
如果您需要任何其他代码来调查问题,请告诉我。我只是试图避免发布太多
编辑:
我的旧底部导航图:
<?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>
我想我很好地理解了你的问题(如果我没有错的话)。问题是你现在得到的行为是正常的情况。您正在使用相同的主机活动来托管导航抽屉
和底部导航
片段,因此当您尝试从同一主机导航到另一个片段时,主机的直接子视图BottomNavBar
正在显示。我认为您可以通过几种不同但非常简单的逻辑方式解决这个问题。
您正在使用导航体系结构组件,因此 navController
是应该控制片段事务的组件,您正在使用 BottomNavigationView
执行此操作。
但是在navDrawer
中,您正在通过支持FragmentManager
进行交易,这应该通过navController
来完成,因为两者都以不同的方式处理导航。
每当我在菜单上选择一个选项时(比如设置),它会在底部的导航视图中显示选项的内容
这是因为BottomNavView是活动的一部分,您需要将其移动到片段中;这需要更改应用程序的导航设计;要做到这一点,请更改应用程序导航,如下所示:
主导航:
<navigation
..... >
<fragment
android:name="......HomeFragment"/>
<fragment
android:name="......SettingFragment"/>
<fragment
android:name="......AdsUpgradeFragment"/>
<fragment
android:name="......PrivacyPolicyFragment"/>
</navigation>
< code>HomeFragment是应该保存< code > BottomNaviagtionView 而不是activity的片段;当您导航到SettingFragment时,navConroller将替换navHostFragment中的整个片段,因此< code > BottomNaviagtionView 不会显示。
我的活动的工具栏内容,包括导航汉堡包图标,编辑文本和搜索按钮(托管我的3个片段的活动),这会破坏应用程序并使其看起来非常丑陋
与底部导航视图
不同,您不能使用用作supportActionBar的工具栏,因为要更改其外观,需要多次设置supportActionBar
;将复制它;因此,您必须接受单个工具栏;但是,您可以隐藏/显示包含搜索按钮的布局
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);
}
});
是的,当点击返回时,他们会退出应用程序
要随时退出应用程序,请在任何片段中按下底部后退按钮,请使用onBackPressedDispatcher()
在这些片段
中(在您的情况下设置碎片,PrivacyPolicyFragment,
并确保< code>appBarConfiguration不引用这些片段,以便显示向上按钮而不是汉堡。
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();
}
});
另外,请确保您设置的抽屉布局
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);
并且要使主页片段默认隐藏在 navDrawer 中:
navView.getMenu().findItem(R.id.nav_home).setVisible(false); // adjust R.id.nav_home to yours
我目前只有一个导航图。firstFraank代表今天、第二小时和第三天,我正在使用的是其他天气选项卡,但您建议的是导航栏菜单,我应该用我的替换您的还是为您的建议创建一个新选项卡?
您应该使用两个navGraph,第一个是我建议的主导航;第二个是您已经使用的BottomNavigationView
导航;这是因为我们将BottomNavigationView
从活动布局转移到main/home片段布局;它'建议BottomNavigationView
应该有一个单独的navGraph;
因此,您现在需要两个< code > FragmentContainerView ;第一个在活动布局中,它引用了本答案中提供的导航图,第二个在home片段布局中,它引用了< code > BottomNavigationView 的原始导航图。
样本:
出于某种原因,我使用引导主题的导航栏没有显示为块。我正在使用我的index.html页面的轮播模板,并希望在我的其余页面上使用相同的主题,只是没有轮播。然而,当我拿出旋转木马时,我的第二个div坐在我的导航栏下。 下面是我导航栏的代码: 还有一个指向我的小提琴的链接,我的CSS位于引导CSS之上: https://jsfiddle.net/czz2Lm1n/
在angular中,我试图确保我所在的页面在navbar上被高亮显示--我想这可能是我正在使用的自举nav的原生版本,但它似乎不起作用。 导航 有没有一个css脚本或我可以使用的东西来实现这一点?
如何在Jellybean模拟器上启用系统导航栏(包括HOME/BACK/MENU)? 在谷歌上搜索这个,有人说可以通过更改属性来完成,但是我找不到在哪里设置这个常数。有人能帮我吗?
ap.showOptionButton() 显示导航栏右侧按钮。 代码示例 <script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js"></script> <button class="btn btn-default">显示 optionButton</button
ap.showNavigationBarLoading() 显示导航栏加载图标。 代码示例 <script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js"></script> <button class="btn btn-default">showNavigationB
我一直在Stack上寻找一些关于这个的指导,但是没有一个问题被问到这么深,答案也没有更新到最新的Swift版本,甚至没有更新到最新的Swift版本。 这是我所拥有的: 带有两个栏项目的导航控制器: 我的目标是:使导航根视图控制器的导航栏透明(但按钮和标题仍然可见),而不是子导航——没有奇怪的细微差别,比如之前的彩色闪光,或切断导航栏(参见gif) 我尝试过的事情: 在<代码>视图将出现(u动画:B