How to change app theme dynamically programmatically - android

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

Related

Change Contextual ActionBar close icon in Android

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)

Popup menu style issue

I am developing one app in which I have a list and a popup menu in it. But my app has black background color and text color is white. But my popup menu back color coming is white and text color is white. I have tried all posible ways but its not working. Here is my code.
Style.xml
<attr name="iconColor" format="reference" />
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/back_color</item>
<item name="colorPrimaryDark">#android:color/holo_orange_dark</item>
<item name="android:textColor">#color/White</item>
<item name="android:textSize">12dp</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="iconColor">#android:color/white</item>
<item name="android:popupBackground">#color/back_color</item>
<item name="android:popupMenuStyle">#style/PopupMenu</item>
<item name="colorAccent">#android:color/holo_red_light</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" >
<item name="android:panelBackground">#color/back_color</item>
<item name="android:textColor">#color/black</item>
</style>
<style name="StyledScrollerTextAppearance" parent="#android:style/TextAppearance">
<item name="android:textSize">24sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#android:color/white</item>
</style>
<style name="AppTheme.TextAppearance">
<item name="android:textColor">#color/White</item>
<item name="android:textSize">12dp</item>
</style>
<style name="AppTheme.TextAppearance.Subtitle">
<item name="android:textColor">#color/White</item>
<item name="android:textSize">10dp</item>
</style>
<style name="PopupMenu">
<item name="android:panelBackground">#color/back_color</item>
<item name="android:textColor">#color/White</item>
</style>
<style name="Theme.AppCompat.Light.NoActionBarCustom" parent="Theme.AppCompat.Light.NoActionBar" >
<item name="colorAccent">#android:color/holo_red_dark</item>
</style>
Below is recycler view adapter
#Override
public void onBindViewHolder(ItemHolder itemHolder, int i) {
Song localItem = arraylist.get(i);
itemHolder.title.setText(localItem.title);
itemHolder.artist.setText(localItem.artistName);
setOnPopupMenuListener(itemHolder, i);
}
private void setOnPopupMenuListener(ItemHolder itemHolder, final int position) {
itemHolder.popupMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context wrapper = new ContextThemeWrapper(mContext, R.style.PopupMenu);
final PopupMenu menu = new PopupMenu(wrapper, v);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.popup_play:
break;
case R.id.popup_next:
break;
}
return false;
}
});
menu.inflate(R.menu.popup_song);
menu.show();
}
});
}
Please help me with it.
After reading comments, you need a contextual menu.
Inherit your PopupMenu from Widget.PopupMenu.
<style name="AppTheme.PopupMenu" parent="#android:style/Widget.PopupMenu">
<item name="android:popupBackground">#color/yourcolor</item>
</style>
I would suggest wrap your toolbar in AppBarLayout and in AppBarLayout theme set your menu style.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/app_bar"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
Here are styles.
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Light">
<!-- text color for toolbar and popup menu-->
<item name="android:textColorPrimary">#color/colorAccent</item>
<item name="popupMenuStyle">#style/AppTheme.PopupMenu</item>
<item name="android:popupMenuStyle">#style/AppTheme.PopupMenu</item>
</style>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Dark" />
<style name="AppTheme.PopupMenu" parent="#android:style/Widget.PopupMenu">
<!-- background color of popup menu-->
<item name="android:popupBackground">#color/colorBlack</item>
</style>
Finally, create your popup menu with AppBarLayout context.
AppBarLayout bar= (AppBarLayout) findViewById(R.id.app_bar);
PopupMenu p = new PopupMenu(bar.getContext(), findViewById(item.getItemId()));
For more information, read this answer.

How to add night mode and day mode in android actionbar

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

Why is the text selection tool is half shown and is not clickable

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?

how to Customize the Contextual Action Bar using appCompat in material design

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.

Categories

Resources