I am developing an android application. I want to add night mode and day mode in app. I want to make it visible in app's actionbar.
Currently my style.xml file is
<style name="Theme.FullScreen" parent="#android:style/Theme.Black.NoTitleBar.Fullscreen"></style>
<style name="PreferencesTheme" parent="android:Theme.Light">
<item name="android:background">#FFEAEAEA</item>
</style>
<style name="PreferencesTheme" parent="android:Theme.Light">
<item name="android:windowBackground">#drawable/ic_icon_settings</item>
</style>
I solved this problem by using this in my xml file :
<style name="ActionBar" parent="#android:style/Widget.Holo.ActionBar" />
<style name="ActionBar.Light" parent="#style/ActionBar">
<item name="android:background">#color/actionbar_background_light</item>
</style>
<style name="ActionBar.Dark" parent="#style/ActionBar">
<item name="android:background">#color/actionbar_background_dark</item>
</style>
<style name="AppTheme.Light" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/ActionBar.Light</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="listDragShadowBackground">#android:color/background_light</item>
<item name="menuIconCamera">#drawable/ic_menu_camera_holo_light</item>
<item name="menuIconToggle">#drawable/ic_menu_toggle_holo_light</item>
<item name="menuIconShare">#drawable/ic_menu_share_holo_light</item>
</style>
<style name="AppTheme.Dark" parent="#android:style/Theme.Holo">
<item name="android:actionBarStyle">#style/ActionBar.Dark</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="listDragShadowBackground">#android:color/background_dark</item>
<item name="menuIconCamera">#drawable/ic_menu_camera_holo_dark</item>
<item name="menuIconToggle">#drawable/ic_menu_toggle_holo_dark</item>
<item name="menuIconShare">#drawable/ic_menu_share_holo_dark</item>
</style>
MENUS TO SWITCH BETWEEN THE MODES
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.toggleTheme:
if (mThemeId == R.style.AppTheme_Dark) {
mThemeId = R.style.AppTheme_Light;
} else {
mThemeId = R.style.AppTheme_Dark;
}
this.recreate();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The Global Variable necessary for switching between the modes:
private int mThemeId = -1;
And for saving the last selected mode, in the onCreate():
if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
mThemeId = savedInstanceState.getInt("theme");
this.setTheme(mThemeId);
}
Related
I want to make my Contextual Action Bar show a close icon other than the back arrow, but I'm not succeeding.
To do this, I have changed the actionModeCloseDrawable property in my styles.xml file: <item name="actionModeCloseDrawable">#drawable/ic_baseline_close_24</item>, but it is not working, as you can see in the image below:
This is my code at styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
<!-- Customize your theme here. -->
<item name="fontFamily">#font/roboto_regular</item>
<item name="actionBarTheme">#style/ThemeOverlay.Material3.Dark.ActionBar</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeStyle">#style/Widget.App.ActionMode</item>
<item name="actionModeCloseDrawable">#drawable/ic_baseline_close_24</item>
<item name="colorSurface">#color/design_default_color_surface</item>
<item name="materialCalendarStyle">#style/Widget.MaterialComponents.MaterialCalendar</item>
<item name="materialCalendarFullscreenTheme">#style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen</item>
<item name="materialCalendarTheme">#style/ThemeOverlay.MaterialComponents.MaterialCalendar</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.Material3.Light" />
<style name="CustomTextAppearance" parent="TextAppearance.Material3.BodyMedium">
<item name="android:textColor">#color/colorBreviario</item>
</style>
<style name="Widget.App.ActionMode" parent="Widget.AppCompat.ActionMode">
<item name="titleTextStyle">?attr/textAppearanceHeadline6</item>
<item name="subtitleTextStyle">?attr/textAppearanceSubtitle1</item>
<item name="background">#color/material_grey_900</item>
<item name="actionModeCloseDrawable">#drawable/ic_baseline_close_24</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="toolbarStyle">#style/Widget.MaterialComponents.Toolbar.PrimarySurface</item>
<item name="materialCalendarStyle">#style/Widget.MaterialComponents.MaterialCalendar</item>
<item name="materialCalendarFullscreenTheme">#style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen</item>
<item name="materialCalendarTheme">#style/ThemeOverlay.MaterialComponents.MaterialCalendar</item>
</style>
</resources>
How it's not working?
If I try this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item_voz) {
if (mActionMode == null) {
//mActionMode = getActivity().startActionMode(mActionModeCallback);
mActionMode = ((AppCompatActivity)getActivity()).startSupportActionMode((androidx.appcompat.view.ActionMode.Callback) mActionModeCallback);
}
getActivity().invalidateOptionsMenu();
return true;
}
I'm having this error:
java.lang.ClassCastException:
org.mi.app.ui.fragments.HomiliasFragment$1 cannot be cast to
androidx.appcompat.view.ActionMode$Callback
at org.mi.app.ui.fragments.HomiliasFragment.onOptionsItemSelected(HomiliasFragment.java:127)
at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3154)
at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:2937)
at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3158)
at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:2937)
at androidx.fragment.app.FragmentController.dispatchOptionsItemSelected(FragmentController.java:427)
at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:334)
at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:264)
at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
at androidx.appcompat.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:66)
at androidx.appcompat.widget.Toolbar$1.onMenuItemClick(Toolbar.java:221)
at androidx.appcompat.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:781)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
This is my callback:
private final ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// ...
}
// ...
}
How about using a Toolbar? androidx.appcompat.widget.Toolbar has this method:
public void setNavigationIcon(#DrawableRes int resId)
Maybe activity.actionBar.setHomeAsUpIndicator(R.id.back)
How to change the App theme dynamically in android. I have an app with many users, when users log in, as per requirements I have to change the app theme dynamically.
Try this
styles.xml
<style name="lightTheme">
<item name="android:textViewStyle">#style/LightStyledTextView</item>
<item name="android:windowAnimationStyle">#null</item>
<item name="actionOverflowMenuStyle">#style/LightStyledOptionsMenu</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="darkTheme">
<item name="android:textViewStyle">#style/DarkStyledTextView</item>
<item name="android:windowAnimationStyle">#null</item>
<item name="actionOverflowMenuStyle">#style/DarkStyledOptionsMenu</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="LightStyledTextView" parent="Widget.AppCompat.TextView.SpinnerItem">
<item name="android:textColor">#color/black</item>
</style>
<style name="DarkStyledTextView" parent="Widget.AppCompat.TextView.SpinnerItem">
<item name="android:textColor">#color/white</item>
</style>
<!-- Menu Styles-->
<style name="LightStyledOptionsMenu" parent="ThemeOverlay.AppCompat.Light">
<item name="overlapAnchor">false</item>
<item name="android:popupBackground">#color/white</item>
<item name="android:textColor">#color/blue_grey</item>
</style>
<style name="DarkStyledOptionsMenu" parent="ThemeOverlay.AppCompat.Dark">
<item name="overlapAnchor">false</item>
<item name="android:popupBackground">#color/blue_grey</item>
<item name="android:textColor">#color/white</item>
</style>
create this in BaseActivity and call in onCreate method
public void updateTheme()
{
if (Utility.getTheme(getApplicationContext()))
{
setTheme(R.style.darkTheme);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
else
{
setTheme(R.style.lightTheme);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
}
Utility.java
public static void setTheme(Context context, boolean theme)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(context.getString(R.string.prefs_theme_key), theme).apply();
}
public static Boolean getTheme(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.prefs_theme_key), false);
}
and in any Activity use any component to change theme, in this case Switch
Switch darkModeSwitch = findViewById(R.id.darkModeSwitch);
darkModeSwitch.setChecked(Utility.getTheme(this));
darkModeSwitch.setOnCheckedChangeListener((compoundButton, checked) ->
{
Utility.setTheme(getApplicationContext(), checked);
});
I have an AppCompatActivity which contains android.app.Fragment. In fragment I have a button on the toolbar which fires the method showDialog():
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_add_ingredient) {
showDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
private void showDialog() {
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// 2. Chain together various setter methods to set the dialog
// characteristics
builder.setTitle(R.string.dialog_ingredient_add_title);
builder.setView(mActivityMain.getLayoutInflater().inflate(
R.layout.dialog_shopping_ingredient_add, null));
builder.setPositiveButton(R.string.dialog_ingredient_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
builder.setNegativeButton(R.string.dialog_ingredient_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
// 3. Get the AlertDialog from create()
dialog = builder.create();
dialog.show();
}
As it can be seen from the code, a android.support.v7.app.AlertDialog appears.
Picture 1. AlertDialog shown.
Then I select some text.
Picture 2. Text selected.
And somehow text selection tool shows only half of it and is unclickable.
My styles.xml file is below.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base" />
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<!-- colorPrimary is used, for instance, for the default ActionBar (but not Toolbar) background. We specify the same color for the toolbar background in toolbar.xml.. -->
<item name="colorPrimary">#color/color_primary</item>
<!-- colorPrimaryDark is used for the status bar (with the battery, clock, etc). -->
<item name="colorPrimaryDark">#color/color_primary_dark</item>
<!-- colorAccent is used as the default value for colorControlActivated which is used to tint widgets. -->
<item name="colorAccent">#color/color_accent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="android:itemTextAppearance">#style/MenuTextApearance</item>
<item name="colorControlNormal">#000000</item>
<item name="colorControlActivated">#color/color_highlight_text</item>
<item name="colorControlHighlight">#color/color_highlight_text</item>
<item name="actionMenuTextColor">#android:color/white</item>
<item name="android:actionMenuTextColor">#android:color/white</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:textColorHighlight">#color/color_highlight_text</item>
<item name="actionModeBackground">#drawable/myapp_action_mode_background</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/white</item>
</style>
<style name="MenuTextApearance" parent="#android:style/TextAppearance.Widget.IconMenu.Item">
<item name="android:textColor">#000000</item>
</style>
<style name="ActionBarThemeOverlay" parent="">
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="colorControlNormal">#FFFFFF</item>
<item name="colorControlHighlight">#00000000</item>
</style>
<style name="HeaderBar">
<item name="android:background">?colorPrimary</item>
</style>
<style name="HeaderBarTransparent">
<item name="android:background">#color/color_primary_transparent</item>
</style>
<style name="ActionBarPopupThemeOverlay" parent="ThemeOverlay.AppCompat.Light">
<item name="android:background">#00000000</item>
<item name="android:textColor">#FFFFFF</item>
</style>
Question:
How can I make the text selection tool fully visible and clickable?
MainActivity.java
I've implemented MultiChoiceModeListener in this class and below is the code:
on listView:
listView.setMultiChoiceModeListener(MainActivity.this);
listView.setChoiceMode(listView.CHOICE_MODE_MULTIPLE_MODAL);
#Override
public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) {
switch (arg1.getItemId()) {
case R.id.save:
// Close CAB
arg0.finish();
return true;
case R.id.saveto:
// Close CAB
arg0.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode arg0, Menu arg1) {
arg0.getMenuInflater().inflate(R.menu.save_menu, arg1);
return true;
}
#Override
public void onDestroyActionMode(ActionMode arg0) {
listadaptor.removeSelection();
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode arg0, int arg1, long arg2,
boolean arg3) {
final int checkedCount = listView.getCheckedItemCount();
arg0.setTitle(checkedCount + " "+getResources().getString(R.string.selected));
listadaptor.toggleSelection(arg1);
}
style.xml
<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/White</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBar">false</item>
<item name="actionModeStyle">#style/LStyled.ActionMode</item>
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppTheme.Base">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<style name="LStyled.ActionMode" parent="#style/Widget.AppCompat.ActionMode">
<item name="background">#color/colorPrimary</item>
</style>
<style name="ActionBarThemeOverlay" parent="Theme.AppCompat.Light">
<item name="android:textColorPrimary">#fff</item>
<item name="colorControlNormal">#fff</item>
<item name="colorControlHighlight">#3fff</item>
</style>
<style name="HeaderBar">
<item name="android:background">#009688</item>
<item name="android:textStyle">bold</item>
</style>
<style name="ActionBarPopupThemeOverlay" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#000</item>
</style>
below is my screenshots:
you can see both screenshots, in second screenshot, actionmode background is white and text color is also white.. i want to change it to first screenshots color which is in top.
You can change the ActionMode background through attribute actionModeStyle:
<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
....
....
<item name="actionModeStyle">#style/LStyled.ActionMode</item>
</style>
<style name="LStyled.ActionMode" parent="#style/Widget.AppCompat.ActionMode">
<item name="background">#color/color_action_mode_bg</item>
</style>
You will of course need to define a color named color_action_mode_bg:
<color name="color_action_mode_bg">#009688</color>
There are other things you can change as well. Example:
<item name="titleTextStyle">...</item>
<item name="subtitleTextStyle">...</item>
<item name="height">...</item>
To change text color of SAVE and SAVETO, add the following to AppTheme.Base:
<item name="actionMenuTextColor">#color/color_action_mode_text</item>
use actionModeBackground in your AppTheme.Base style.
<item name="actionModeBackground">#color/colorPrimary </item> (or)
<item name="android:actionModeBackground">#color/colorPrimary </item>
To change the Title Color of contextual action bar this was the only method that worked for me:
Write this in your activity's theme
<item name="actionModeStyle">#style/ContextualActionModeTheme</item>
Define the styles
<style name="ContextualActionModeTheme" parent="#style/Widget.AppCompat.ActionMode">
<item name="titleTextStyle">#style/titleColor</item>
</style>
<style name="titleColor" parent="TextAppearance.AppCompat.Widget.ActionMode.Title">
<item name="android:textColor">#color/your_color_here</item>
</style>
The title color of your contextual action bar would be changed.
I know it's possible to have it so if I have a setting I can change between Holo.Light and Holo, however, I cannot seem to find out how. All help is appreciated!
I think that you can do it by using the setTheme() method. Just make sure that you call it before you use setContentView, or it won't work.
For example:
if(userChoice ==1){
setTheme(android.R.style.Theme_Holo_Light);
else if(userChoice == 2){
setTheme(android.R.style.Theme_Holo);
}
A list of themes can be found here
As per a comment on the answer posted, if you need to toggle between the default Holo Themes, use this:
if (mThemeId == R.style.AppTheme.Dark) {
mThemeId = android.R.style.Theme_Holo_Light;
} else {
mThemeId = android.R.style.Theme_Holo;
}
this.recreate();
To use your own custom defined themes from your Styles.XML file. For example, something like this:
<style name="ActionBar" parent="#android:style/Widget.Holo.ActionBar" />
<style name="ActionBar.Light" parent="#style/ActionBar">
<item name="android:background">#color/actionbar_background_light</item>
</style>
<style name="ActionBar.Dark" parent="#style/ActionBar">
<item name="android:background">#color/actionbar_background_dark</item>
</style>
<style name="AppTheme.Light" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/ActionBar.Light</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="listDragShadowBackground">#android:color/background_light</item>
<item name="menuIconCamera">#drawable/ic_menu_camera_holo_light</item>
<item name="menuIconToggle">#drawable/ic_menu_toggle_holo_light</item>
<item name="menuIconShare">#drawable/ic_menu_share_holo_light</item>
</style>
<style name="AppTheme.Dark" parent="#android:style/Theme.Holo">
<item name="android:actionBarStyle">#style/ActionBar.Dark</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="listDragShadowBackground">#android:color/background_dark</item>
<item name="menuIconCamera">#drawable/ic_menu_camera_holo_dark</item>
<item name="menuIconToggle">#drawable/ic_menu_toggle_holo_dark</item>
<item name="menuIconShare">#drawable/ic_menu_share_holo_dark</item>
</style>
Define this as a Global Variable in your Activity:
private int mThemeId = -1;
And set your onCreate() method like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
if (savedInstanceState.getInt("theme", -1) != -1) {
mThemeId = savedInstanceState.getInt("theme");
this.setTheme(mThemeId);
}
mTitlesHidden = savedInstanceState.getBoolean("titlesHidden");
}
setContentView(R.layout.main);
}
And the code to toggle between the two themes:
if (mThemeId == R.style.AppTheme.Dark) {
mThemeId = R.style.AppTheme.Light;
} else {
mThemeId = R.style.AppTheme.Dark;
}
this.recreate();
Note: The theme has to be set before your call to setContentView()