如何解决Android:处理抽屉菜单中的开关
我的应用程序中只有一个用户设置,我想通过添加到给定菜单项的开关将其放入导航抽屉。
<item
android:id="@+id/nav_dark"
android:checkable="true"
android:icon="@drawable/round_brightness_4_24"
android:title="@string/menu_dark"
app:actionViewClass="android.widget.Switch" />
该开关确实出现在菜单项的右侧。
我的听众:
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.nav_dark) {
// code to apply dark or light theme
// works as expected
}
else {
// code to handle regular menu items
// it works too
}
return true;
}
我的问题:
- 当我点击
R.id.nav_dark
时,该项目被选中。我希望彩色的覆盖物停留在(或跳回)上一个菜单项,该菜单项的片段实际上显示在抽屉后面。 - 即使我手动使用
item.setChecked(true)
,开关也不会做出相应的反应。我希望启用深色主题时将开关打开,禁用深色主题时将开关关闭。 - 点击开关本身不会将事件传递给菜单项。我希望他们同步工作。
我在其他应用程序中看到了复选框和电子表格的工作方式,尽管其中大多数都在应用程序栏的溢出菜单中。 (我也尝试过使用复选框,但没有区别。)
解决方法
我使用以下线程解决了这个问题:Switch in Navigation drawer item with Design Support Library on Android
在此示例中,专用菜单项在浅色和深色主题之间切换,但是您可以使用它来切换任何设置。
问题解决
- 实施我们自己的
onNavigationItemSelected
侦听器,因为Android Studio创建的默认解决方案阻止使用专用菜单项。 - 实施片段交易和工具栏处理逻辑。
- 实施交换机的
onCheckedChange
侦听器。
我们要做的是捕获菜单项上的点击。如果是常规物品,我们将更改抽屉后面的片段。如果它是开关的专用项,我们将手动切换该开关,从而调用其监听器。
实际的代码(在这种情况下,更改主题)由开关的侦听器处理。如果单击开关本身,则将直接调用侦听器。
activity_main_drawer.xml
菜单文件中的相关代码
<item
android:id="@+id/nav_dark"
android:checkable="true"
android:icon="@drawable/round_brightness_4_24"
android:title="@string/menu_dark"
app:actionViewClass="android.widget.Switch" /> <!-- you can also use a CheckBox -->
MainActivity.java
中的相关代码
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,Switch.OnCheckedChangeListener {
private Toolbar toolbar;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle toggle;
private NavigationView navigationView;
private Switch switchDark;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.toolbar_title));
setSupportActionBar(toolbar);
// We have to handle the fragment changes manually,// because what we do conflicts with the default solution created by Android Studio
drawerLayout = findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.navigation_drawer_open,R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
navigationView = findViewById(R.id.nav_view);
// Check the menu item connected to the default fragment manually
navigationView.getMenu().findItem(R.id.nav_item1).setChecked(true);
navigationView.setNavigationItemSelectedListener(this); // See below!
switchDark = (Switch)navigationView.getMenu().findItem(R.id.nav_dark).getActionView();
// Set the default state of the switch connected to the menu item
switchDark.setChecked(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);
switchDark.setOnCheckedChangeListener(this); // See below!
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Handle the menu item with the switch
if (item.getItemId() == R.id.nav_dark) {
((Switch)item.getActionView()).toggle(); // Call the onCheckedChangeListener of the switch and let it do the work
return false; // Prevent the menu item to get selected (No overlay indicator will appear)
}
// Handle the other menu items
// We have to do this,because we deleted the default solution created by Android Studio
Fragment newFragment = null;
if (item.getItemId() == R.id.nav_item1) {
newFragment = new CustomFragment();
toolbar.setTitle(getResources().getString(R.string.custom_fragment_title));
}
else if (item.getItemId() == R.id.nav_item2) {
newFragment = new OtherFragment();
toolbar.setTitle(getResources().getString(R.string.other_fragment_title));
}
// Start the fragment transition manually
if (newFragment != null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment,newFragment);
transaction.addToBackStack(null);
transaction.commit();
drawerLayout.close();
}
return true; // The selected item will have the overlay indicator
}
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(buttonView.getContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
int themeID;
if (isChecked) {
themeID = AppCompatDelegate.MODE_NIGHT_YES;
}
else {
themeID = AppCompatDelegate.MODE_NIGHT_NO;
}
AppCompatDelegate.setDefaultNightMode(themeID); // Change the theme at runtime
editor.putInt("themeID",themeID); // Save it to be remembered at next launch
editor.apply();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。