I'm trying to make a navigation drawer switch which switches between a normal theme and a dark theme of an app, however I can't get the switch to work.
I already have a working switch on mainactivity but I can't get it to work in the navigation drawer.
This is the code to switch between light/dark mode.
#Override
protected void onCreate(Bundle savedInstanceState) {
if(AppCompatDelegate.getDefaultNightMode()==AppCompatDelegate.MODE_NIGHT_YES) {
setTheme(R.style.HROTheme);
}
else setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
modeswitch=(Switch)findViewById(R.id.switch2);
if (AppCompatDelegate.getDefaultNightMode()==AppCompatDelegate.MODE_NIGHT_YES) {
modeswitch.setChecked(true);
}
modeswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
recreate();
}
else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
recreate();
}
}
});
You can try to add an item in values/attrs like this: <attr name="bottomback" format="color" />
Then define "bottomback" in styles for your both dark and light styles like this:
<item name="bottomback">#000</item>
That must be different in both styles.
now you can set the backgroundTint of drawer as this: android:backgroundTint="?attr/bottomback"
Related
I have set Light and Dark mode in my app and its working.
But I also want to add an option to let the app follow the mode set by the system. So user can choose among three options.
I tried to do it, but was unsuccessful. I want to add Radio Buttons to switch to Light, Dark, Follow System Mode.
Here's what I have tried
public class setting extends AppCompatActivity {
private Switch darkMode;
Button autoButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
setTheme(R.style.darktheme);
}
else {
setTheme(R.style.AppTheme);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Settings");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setTitleTextAppearance(this, R.style.Font);
darkMode = (Switch) findViewById(R.id.darkModeSwitch);
autoButton = (Button) findViewById(R.id.autoButton);
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
darkMode.setChecked(true);
}
darkMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
getDelegate().applyDayNight();
recreate();
//restartApp();
}
else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
recreate();
// restartApp();
}
}
});
}
}
There’s an option that does this: AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM.
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
how to get back hamburg icon when set back icon?
hen I am implementing change toggle icon when fragment on activity ,its set to back icon but need when its back the fragment then set it to again hamburg icon for open drawer of the activity,
this is my code
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
toolbar.setNavigationIcon(R.drawable.ic_action_navigation_arrow_back);
//drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
///drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
toolbar.setNavigationIcon(R.drawable.icon1);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
//drawerFragment.mDrawerToggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.openDrawer(GravityCompat.START);
}
});
}
}
});
If you are using fragment to show content and have the single toolbar inside host activity, you could manage your toolbar.
#Override
public void onResume() {
super.onResume();
ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
actionBar.setTitle("First Fragment");
actionBar.setIcon(R.drawable.back_icon);
}
Do not forget to call
setSupportActionBar(toolbar)
I am a beginner Android developer and I have been struggling the issue that I can't see the toolbar in any activity that inherits Base Activity. According to other resource, to use the same toolbar in the different activities. I have to implement it in Base Activity and inherit it where I need to use it. Could anyone help me figure out the problem?
styles.xml
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
<style name="AppTheme" parent="AppBaseTheme">
</style>
</resources>
quiz.menu.xml inside of menu folder
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/contact"
android:icon="#drawable/ic_contacts_black_24dp"
android:title="Contact"
app:showAsAction="ifRoom" />
<item android:id="#+id/language"
android:title="Language"
app:showAsAction="never" />
<item android:id="#+id/speech"
android:title="Speech"
app:showAsAction="never">
<munu>
<item android:id="#+id/subitem1"
android:title="Sub Item 1"/>
<item android:id="#+id/subitem2"
android:title="Sub Item 2"/>
</munu>
</item>
</menu>
BaseActivity
public class BaseActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.quiz_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.contact:
Toast.makeText(this, "Contact is selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.language:
Toast.makeText(this, "Language is selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.speech:
Toast.makeText(this, "Speech is selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.subitem1:
Toast.makeText(this, "Language is selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.subitem2:
Toast.makeText(this, "Speech is selected", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
WelcomeActivity (inherits base Activity)
public class WelcomeActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
final Button databaseButton = findViewById(R.id.database);
databaseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
Intent databaseIntent = new Intent(WelcomeActivity.this, Questionnaire.class);
startActivity(databaseIntent);
}
});
}
Questionnaire
public class Questionnaire extends BaseActivity {
public Spinner languageSpinner;
public int languageId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_questionnaire);
...
}
}
The answer is actually simple. You firstly set contentview in OnCreate() method of the BaseActivity class, then you change the view to another xml file in OnCreate() methods of the child classes.
What I suggest is that you do not implement OnCreate() method in BaseActivity class but implement SetContentView() method in BaseActivity.
In short, delete onCreate() method from BaseActivity() and add setContentView() method in the below.
#Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
P.S - Your quiz_menu.xml file does not look like a menu file. :)
P.P.S - Let me know if it works, or if you have troubles. :)
This is my Starting Activity. It is working fine programmatically.
The only problem which I'm facing is that the OverFlow-Menu comes is dark theme when called by the Hardware Menu key.
I've provided all the essential lines of code in this sample.
public class StartingActivity extends AppCompatActivity implements LoginActivity_Tab.loginActivityTab_interface {
private static final String LOGIN_URL = "http://rollhack.96.lt/login.php";
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starting);
includeWidgets();
}
private void includeWidgets() {
///// Tab Layout /////
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
///// ToolBar /////
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("Note Pad");
}
///// This method is called for Exiting the App /////
public void exitApp() {
final AlertDialog.Builder exit = new AlertDialog.Builder(StartingActivity.this);
exit.setTitle("Exit Application")
.setMessage("Are you sure you want to Exit the application?")
.setCancelable(true)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
StartingActivity.this.finishAffinity();
}
})
.setNegativeButton(android.R.string.no, null);
exit.create().show();
}
///// This method is called to assign the Key Events /////
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
exitApp();
return true;
}
return super.onKeyUp(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_starting_activity, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
return Boolean.parseBoolean(null);
case (R.id.menu_about):
return Boolean.parseBoolean(null);
case (R.id.menu_exit):
exitApp();
return true;
}
return super.onOptionsItemSelected(item);
}
This is how it looks when it is called by the overflow menu icon of the ActionBar
This is how my App OverFlow-Menu looks when Hardware Menu key is pressed
Overflow menu by Icon
You can change the color of the overflow menu background by adding a new style in style.xml.
<style name="OverflowMenu"
parent="#android:style/Theme.Holo">
<item name="android:popupMenuStyle">#style/MyOverflowMenu</item>
<item name="android:itemTextAppearance">#style/TextAppearance</item>
</style>
<style name="MyOverflowMenu"
parent="#android:style/Widget.Holo.ListPopupWindow">
<item name="android:popupBackground">#color/your_color</item>
</style>
<style name="TextAppearance">
<item name="android:textColor">#color/your_color</item>
</style>
Overflow Menu by Hardware Key
To change the color of Overflow menu called by Hardware key, add another style.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="actionBarPopupTheme">#style/OverflowMenuHardware</item>
</style>
<style name="OverflowMenuHardware" parent="ThemeOverlay.AppCompat.Dark">
<item name="android:textColorSecondary">#color/your_color</item>
<item name="android:colorBackground">#color/your_color</item>
</style>
Implement either one of these to change the color of Overflow menu of either the one called by icon(former code) or by hardware key(latter code).
I am trying to implement a navigation drawer in a BaseActivity, that shows different options depending on the activity that is currently showing. For that, I developed a BaseActivity, that implements the navigation drawer, and decides what to show, depending on the activity that is currently showing. The purpose of this, is to make all other activities that need to use the navigation drawer, expand the BaseActivity.
The following code, shows no errors, but the navigation drawer shows itself completely empty, and does not show when I click the 'home' button, neither the 'menu' button, a functionality that I implemented with the 'onKeyDown' method. It just shows, when I use the following gesture: move the finger from the left to the right in the left side of the screen.
When I do the same in each class I need, instead of using a BaseActivity, everything works perfeclty fine.
I have been trying this for days now and I still do not understand why, the content of the navigation drawer is still not showing. I would appreciate some help please. Thanks in advance.
Here, the core classes of the problem:
BaseActivity.java
public abstract class BaseActivity extends ActionBarActivity
{
public DrawerLayout drawerLayout = null;
public ActionBarDrawerToggle drawerToggle = null;
public Activity currentActivity = null;
public ArrayList<Item> navDrawerItems = new ArrayList<Item>();
public ItemListAdapter adapter = null;
public ListView drawerList = null;
int id = 0;
protected void onCreate(Bundle savedInstanceState, int resLayoutID)
{
super.onCreate(savedInstanceState);
setContentView(resLayoutID);
currentActivity = this;
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(currentActivity,
drawerLayout,
R.drawable.ic_drawer,
R.string.open_menu,
R.string.close_menu)
{
public void onDrawerClosed(View view)
{
Log.e("", "Close drawer");
getSupportActionBar().setTitle(getTitle());
ActivityCompat.invalidateOptionsMenu(currentActivity);
}
public void onDrawerOpened(View drawerView)
{
Log.e("", "Open drawer");
getSupportActionBar().setTitle(getTitle());
ActivityCompat.invalidateOptionsMenu(currentActivity);
}
};
drawerLayout.setDrawerListener(drawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// Populate navigation drawer depending on the activity
// that is currently showing.
if (this.getClass().getSimpleName().equals("Z"))
setUpNavigationForZActivity();
}
private void setUpNavigationForZActivity()
{
Log.e("", "In setUpNavigationForZActivity");
// Prepare list items.
id = R.string.title_activity_A;
navDrawerItems.add(new NavigationDrawerItem(getString(id), Utils.activityIcon().get(id)));
id = R.string.title_activity_B;
navDrawerItems.add(new NavigationDrawerItem(getString(id), Utils.activityIcon().get(id)));
// Populate view.
drawerList = (ListView) findViewById(R.id.left_menu);
adapter = new ItemListAdapter(currentActivity, navDrawerItems;
drawerList.setAdapter(adapter);
drawerList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
{
Intent intent = null;
switch(position)
{
case 0:
intent = new Intent(currentActivity, A.class);
startActivity(intent)
break;
case 1:
intent = new Intent(currentActivity, B.class);
startActivity(intent)
break;
default:
}
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (drawerToggle.onOptionsItemSelected(item))
return true;
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent e)
{
Log.e("", "onKeyDown");
if (keyCode == KeyEvent.KEYCODE_MENU)
{
if(!drawerLayout.isDrawerOpen(Gravity.LEFT))
drawerLayout.openDrawer(Gravity.LEFT);
else
drawerLayout.closeDrawer(Gravity.LEFT);
}
return super.onKeyDown(keyCode, e);
}
}
Z.java
public class Z extends BaseActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState, R.layout.Z);
setContentView(R.layout.Z);
//Other things to do...
}
}
Z.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Main content view -->
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true" >
// Other layout and views configurations...
</ScrollView>
<!-- Navigation drawer -->
<ListView
android:id="#+id/left_menu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/gray_7_5"
android:choiceMode="singleChoice" />
</android.support.v4.widget.DrawerLayout>
I do not exactly know why you would want to implement it that way but if you still want to do it this way i would suggest making your navdrawer use a listview with an adapter to draw items from an array and then have your base activity have a getData() call that you can override in your derived activities that will supply the data that the Adapter so that the listview will then draw the appropriate items in the navdrawer. You will then have to implement the onItemClick event for each listview per activity.