Theme of app doesn't change dynamically - java

I am trying to change the theme or color of the app when the user selects an option from an AlertDialog. I made the same technique for changing the size of font, and it's works fine. I don't what is the mistake I made for changing the color.
strings.xml:
<resources>
<string-array name="font_sizes">
<item>14</item>
<item>16</item>
<item>18</item>
<item>20</item>
<item>22</item>
</string-array>
<string-array name="app_colors">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
</resources>
styles.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="BlackTheme">
<item name="colorPrimary">#FF000000</item>
<item name="colorPrimaryDark">#FF000000</item>
<item name="colorAccent">#FF000000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF000000</item>
</style>
<style name="BlueTheme">
<item name="colorPrimary">#FF0000FF</item>
<item name="colorPrimaryDark">#FF0000FF</item>
<item name="colorAccent">#FF0000FF</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF0000FF</item>
</style>
<style name="GreenTheme">
<item name="colorPrimary">#008000</item>
<item name="colorPrimaryDark">#008000</item>
<item name="colorAccent">#008000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#008000</item>
</style>
<style name="MagentaTheme">
<item name="colorPrimary">#D500F9</item>
<item name="colorPrimaryDark">#D500F9</item>
<item name="colorAccent">#D500F9</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#D500F9</item>
</style>
</resources>
PreferencesActivity.java:
package sa.edu.qu.coc.cocapps.prefs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.LinearLayout;
import sa.edu.qu.coc.cocapps.R;
public class PreferencesActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar toolbar = null;
public static final String PREFS_KEY = "preferences";
private static int item = 0, color = 0;
private LinearLayout fontSize;
private LinearLayout appColor;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preferences);
prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
initViews();
setSupportActionBar(toolbar);
fontSize.setOnClickListener(this);
appColor.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initViews() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
fontSize = (LinearLayout) findViewById(R.id.fontSize);
appColor = (LinearLayout) findViewById(R.id.appColor);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fontSize:
AlertDialog.Builder changeFontSizeDialog = new AlertDialog.Builder(this)
.setTitle("Select Size")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.font_sizes, item, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("fontSize", i);
editor.commit();
item = i;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeFontSizeDialog.show();
break;
case R.id.appColor:
AlertDialog.Builder changeAppColorDialog = new AlertDialog.Builder(this)
.setTitle("Select color")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.app_colors, color, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
editor = prefs.edit();
editor.putInt("appColor", which);
editor.commit();
color = which;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// DO not do anything.
}
});
changeAppColorDialog.show();
break;
}
}
#Override
protected void onStart() {
super.onStart();
switch(prefs.getInt("appColor", 0))
{
case 0:
this.setTheme(R.style.AppTheme);
return;
case 1:
this.setTheme(R.style.BlackTheme);
return;
case 2:
this.setTheme(R.style.BlueTheme);
return;
case 3:
this.setTheme(R.style.GreenTheme);
return;
case 4:
this.setTheme(R.style.MagentaTheme);
return;
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}

Because themes don't change like that. A theme has to be set before inflating the views. Afterwards, the views will not be refreshed to a new theme. However if you were to create a new View it would pick up the new theme.

Create a base Activity for your app and override onCreate to set the theme. Derive all your other activities from this base Activity.
You can also check this particular tutorial (if you are doing activity theme):
http://mrbool.com/how-to-change-the-layout-theme-of-an-android-application/25837

I solved it. The following code is the whole solution.
strings.xml:
<resources>
<string-array name="font_sizes">
<item>14</item>
<item>16</item>
<item>18</item>
<item>20</item>
<item>22</item>
</string-array>
<string-array name="app_colors">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
</resources>
styles.xml: (Also, do not forget to add the same custom styles to styles.xml (v21)):
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="BlackTheme">
<item name="colorPrimary">#FF000000</item>
<item name="colorPrimaryDark">#FF000000</item>
<item name="colorAccent">#FF000000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF000000</item>
</style>
<style name="BlueTheme">
<item name="colorPrimary">#FF0000FF</item>
<item name="colorPrimaryDark">#FF0000FF</item>
<item name="colorAccent">#FF0000FF</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF0000FF</item>
</style>
<style name="GreenTheme">
<item name="colorPrimary">#008000</item>
<item name="colorPrimaryDark">#008000</item>
<item name="colorAccent">#008000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#008000</item>
</style>
<style name="MagentaTheme">
<item name="colorPrimary">#D500F9</item>
<item name="colorPrimaryDark">#D500F9</item>
<item name="colorAccent">#D500F9</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#D500F9</item>
</style>
</resources>
PreferencesActivity.java:
package sa.edu.qu.coc.cocapps.prefs;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.LinearLayout;
import sa.edu.qu.coc.cocapps.R;
public class PreferencesActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar toolbar = null;
private LinearLayout fontSize, appColor;
public static final String PREFS_KEY = "preferences";
private static int item = 0, color = 0;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private Activity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
switch(prefs.getInt("appColor", 0)) {
case 0:
activity.setTheme(R.style.AppTheme);
break;
case 1:
activity.setTheme(R.style.BlackTheme);
break;
case 2:
activity.setTheme(R.style.BlueTheme);
break;
case 3:
activity.setTheme(R.style.GreenTheme);
break;
case 4:
activity.setTheme(R.style.MagentaTheme);
break;
}
setContentView(R.layout.activity_preferences);
initViews();
setSupportActionBar(toolbar);
fontSize.setOnClickListener(this);
appColor.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initViews() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
fontSize = (LinearLayout) findViewById(R.id.fontSize);
appColor = (LinearLayout) findViewById(R.id.appColor);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fontSize:
AlertDialog.Builder changeFontSizeDialog = new AlertDialog.Builder(this)
.setTitle("Select Size")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.font_sizes, item, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("fontSize", i);
editor.commit();
item = i;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeFontSizeDialog.show();
break;
case R.id.appColor:
AlertDialog.Builder changeAppColorDialog = new AlertDialog.Builder(this)
.setTitle("Select Color")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.app_colors, color, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("appColor", i);
editor.commit();
color = i;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeAppColorDialog.show();
break;
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}

Related

Menu won't show up. I don't know why

I'm just following another tutorial but the result is different. When I'm trying to run my apk, menu icon won't show up on primary layout (activity_main.xml) Anyone knows what I missed?
menu_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- NEW NOTE -->
<item
android:id="#+id/action_create"
android:enabled="true"
android:icon="#android:drawable/ic_menu_add"
android:orderInCategory="0"
android:title="create"
android:visible="true"
app:showAsAction="always" />
<!-- SETTINGS -->
<item
android:id="#+id/action_settings"
android:enabled="true"
android:icon="#android:drawable/ic_menu_manage"
android:orderInCategory="10"
android:title="settings"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>
MainNote.java:
package com.example.lenovo.home;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import android.view.View.OnClickListener;
public class MainNote extends AppCompatActivity {
private ListView mListNotes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_note);
mListNotes = (ListView) findViewById(R.id.main_listview);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_activity, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create: //run NoteActivity in new note mode
startActivity(new Intent(this, NoteActivity.class));
break;
case R.id.action_settings:
//TODO show settings activity
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
super.onResume();
//load saved notes into the listview
//first, reset the listview
mListNotes.setAdapter(null);
ArrayList<Note> notes = Utilities.getAllSavedNotes(getApplicationContext());
//sort notes from new to old
Collections.sort(notes, new Comparator<Note>() {
#Override
public int compare(Note lhs, Note rhs) {
if (lhs.getDateTime() > rhs.getDateTime()) {
return -1;
} else {
return 1;
}
}
});
if (notes != null && notes.size() > 0) { //check if we have any notes!
final NoteAdapter na = new NoteAdapter(this, R.layout.view_note_item, notes);
mListNotes.setAdapter(na);
//set click listener for items in the list, by clicking each item the note should be loaded into NoteActivity
mListNotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//run the NoteActivity in view/edit mode
String fileName = ((Note) mListNotes.getItemAtPosition(position)).getDateTime()
+ Utilities.FILE_EXTENSION;
Intent viewNoteIntent = new Intent(getApplicationContext(), NoteActivity.class);
viewNoteIntent.putExtra(Utilities.EXTRAS_NOTE_FILENAME, fileName);
startActivity(viewNoteIntent);
}
});
} else { //remind user that we have no notes!
Toast.makeText(getApplicationContext(), "you have no saved notes!\ncreate some new notes :)"
, Toast.LENGTH_SHORT).show();
}
}
}
And, the last is my activity_main_note.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.lenovo.home.MainNote">
<ListView
android:id="#+id/main_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</LinearLayout>
UPDATE
This is my styles code
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
This is my theme code for application.
I have just run your code and it works fine.
I am running it with the following theme in styles.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
</resources>
In manifest I have android:theme="#style/AppTheme" in the application tag.
And my Activity extends AppCompatActivity
Also check you have put the menu xml in res/menu folder.
The only thing I see but it is regarding the item being selected is that the return statement is wrong, but it doesn't have to do with the icons not appearing.
In onOptionsItemSelected(MenuItem item) you should return true if you handle the request or false if not.
Change it like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean rtn = false;
switch (item.getItemId()) {
case R.id.action_create: //run NoteActivity in new note mode
startActivity(new Intent(this, NoteActivity.class));
rtn = true;
break;
case R.id.action_settings:
//TODO show settings activity
rtn = true;
break;
default:
rtn = super.onOptionsItemSelected(item);
}
return rtn;
}
See this question: Should "android: onOptionsItemSelected" return true or false
EDIT I
I see in your styles.xml you are extending Theme.AppCompat.Light.NoActionBar, which doesn't have an ActionBar.
In this case you can switch to a theme with an ActionBar as I am using or otherwise you need to add your own action bar to the layout using a Toolbar.

"Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set WindowActionBar to false in your theme to use a toolbar instead"

I get the error "Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set WindowActionBar to false in your theme to use a toolbar instead" whenever I try to run my app in the emulator on Android Studio and it crashes upon startup. I understand that this question has been asked before, but when I remove the extends AppCompatActivity as I am told to do in other posts it then gives me an error for the setSupportActionBar(toolbar) line a bit further down in the code.
As far as I understand this is an error with Android Studio getting confused about the native toolbar and the toolbar that I'm trying to implement. Perhaps I'm misunderstanding the crux of the problem? Why is it giving me an error for setSupportActionBar(toolbar) once I get rid of the extends statement?
The main activity is using the "AppTheme"
Thanks.
MainActivity Code for reference:
package com.treehouse.android.movies;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;
//extends AppCompatActivity
public class MainActivity extends AppCompatActivity
{
static public ArrayList<Movie> moviesList;
static public ArrayList<String> images;
public String mostPopular="http://api.themoviedb.org/3/movie/popular?api_key=";
public String highRated="http://api.themoviedb.org/3/movie/top_rated?api_key=";
//Make both GridAdapter and GridView non-Static?
static public GridAdapter gridAdapter;
static public GridView gridView;
public static boolean connectionEnabled;
public Context currentContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
String result="";
moviesList=new ArrayList<>();
images=new ArrayList<>();
currentContext=getApplicationContext();
if (isNetworkAvailable()!= false) {
connectionEnabled=true;
getJsonData(0);
new GetMovies(currentContext);
gridView =(GridView) findViewById(R.id.moviesGridView);
gridAdapter =new GridAdapter(MainActivity.this,moviesList,images);
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent movieIntent=new Intent(getApplicationContext(),DetailsActivity.class);
Log.i("Default position ", String.valueOf(position));
movieIntent.putExtra("position",position);
startActivity(movieIntent);
}
});
}
else{
Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
connectionEnabled=false;
}
}
public boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
//get json file
//0 for most popular
//1 for highest-rated
public void getJsonData(int searchBy){
GetMovies downloadTask=new GetMovies(currentContext);
try {
if (searchBy == 0 ){
downloadTask.execute(mostPopular);
}
else if(searchBy == 1){
downloadTask.execute(highRated);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.mostpopular_button) {
if (isNetworkAvailable()!= false) {
new GetMovies(currentContext).execute(mostPopular);
gridAdapter.notifyDataSetChanged();
}
else{
Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
}
}
else if (id== R.id.highrated_button){
if (isNetworkAvailable()!= false) {
new GetMovies(currentContext).execute(highRated);
gridAdapter.notifyDataSetChanged();
}
else{
Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
}
}
return super.onOptionsItemSelected(item);
}
}
Styles Code for reference:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
Manifest Code for reference:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.treehouse.android.movies" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true" >
<!-- android:theme="#style/AppTheme" part of application -->
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN"
android:theme="#style/AppTheme"
/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
change your style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
replace to this :
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionBar">true</item>
<item name="windowNoTitle">true</item>
</style>
Since your Activity's theme is set to AppTheme, it comes with an "action bar" by default. When you then call setSupportActionBar(toolbar), your app crashes because you've already got an actionbar (from your theme).
Simply change your Activity's theme to AppTheme.NoActionBar in your manifest.

Change style programmatically for api less than 23

I want to change the button's style using setTextAppearance but, throw "depreciated".how to use setTextAppearance correctly?
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="button_custom" parent="Theme.AppCompat.Light">
<item name="colorControlHighlight">#FFF59D</item>
<item name="colorButtonNormal">#FFF59D</item>
</style>
</resources>
And the activity
public class MainActivity extends AppCompatActivity {
Button btn;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button);
context = this;
btn.setTextAppearance(context,R.style.button_custom);
}
public void setTextAppearance(Context context, int resId) {
if (Build.VERSION.SDK_INT < 23) {
super.setTextAppearance(context, resId);
}
else { super.setTextAppearance(resId);
}
}
}
You can try making your button of AppCompatButton type and use
btn.setTextAppearance(resid)
It will also helps you avoid the Build.VERSION.SDK_INT branching
You can follow this documentation https://developer.android.com/reference/android/support/v7/widget/AppCompatButton.html#setTextAppearance(android.content.Context, int)
User AppCompatButton
<android.support.v7.widget.AppCompatButton
android:id="#+id/some_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Changing theme causes double action bar glitch

So in my app I created a way for the user to set the theme as dark or light. I implemented it into each activity, but now if the theme is dark, the activity has 2 action bars. If I leave it as the light theme, only one action bar is show. This does not make any sense to me. All help is much appreciated. Thanks.
Here is the pic of the activity:
Here is the code for the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
settings = getSharedPreferences(PREFS_NAME, 0);
checkDark(settings.getBoolean("darkMode", false));
super.onCreate(savedInstanceState);
managerHelper = new ManagerDatabaseAdapter(this);
setContentView(R.layout.activity_main);
adapter = new RVAdapter(this, getData());
RV = (RecyclerView) findViewById(R.id.mainV);
layoutManager = new LinearLayoutManager(this);
RV.setLayoutManager(layoutManager);
RV.setAdapter(adapter);
adapter.setClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// getMenuInflater().inflate(R.menu.menu_main, li)
return true;
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && exitD) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Confirm exit")
.setPositiveButton("EXIT", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.action_settings:
Intent intent = new Intent(this, SettingsActivity.class);
intent.putExtra(EXTRA_MESSAGE, true);
startActivity(intent);
overridePendingTransition(R.anim.abc_popup_enter, R.anim.abc_fade_out);
return true;
case R.id.action_surveyList:
Intent survey = new Intent(this, GetSurvey.class);
survey.putExtra(EXTRA_MESSAGE, true);
startActivity(survey);
overridePendingTransition(R.anim.abc_popup_enter, R.anim.abc_fade_out);
return true;
}
return super.onOptionsItemSelected(item);
}
private void checkDark(boolean isChecked) {
if (isChecked)
setTheme(R.style.Dark);
else
setTheme(R.style.AppTheme);
}
}
Here is the styles.xml:
<resources>>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#E53935</item>
<item name="colorPrimaryDark">#C62828</item>
<item name="android:navigationBarColor">#E53935</item>
<item name="android:colorAccent">#1565C0</item>
<item name="android:colorForeground">#color/foreground_material_light</item>
<item name="android:colorBackground">#color/background_material_light</item>
<!-- Other attributes -->
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#E53935</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/primary_dark_material_light</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
</style>
<style name="Dark" parent="#android:style/Theme.Material" >
<item name="android:colorForeground">#color/foreground_material_dark</item>
<item name="android:colorPrimary">#color/primary_material_dark</item>
<item name="android:colorPrimaryDark">#color/primary_dark_material_dark</item>
<item name="android:colorAccent">#color/accent_material_dark</item>
<item name="android:navigationBarColor">#color/primary_material_dark</item>
</style>
<style name="AppTheme.NoActionBar.Dark" parent="#style/AppTheme.NoActionBar" >
<item name="colorPrimary">#E53935</item>
<item name="colorPrimaryDark">#C62828</item>
<item name="android:navigationBarColor">#E53935</item>
<item name="android:colorAccent">#1565C0</item>
<item name="android:colorBackground">#color/background_material_dark</item>
<item name="android:textColorPrimary">#android:color/primary_text_dark</item>
<item name="android:textColorPrimaryInverse">#android:color/primary_text_light</item>
<item name="android:textColorSecondary">#android:color/secondary_text_dark</item>
<item name="android:textColorSecondaryInverse">#android:color/secondary_text_light</item>
<item name="android:statusBarColor">#color/primary_dark_material_dark</item>
</style>
</resources>
Not sure if this is the cause of the problem, but just something to note. Your AppTheme's parent is from AppCompat but your dark theme is using the built-in material theme.
Change the parent style to Theme.Material.NoActionBar:
Your custom style:
<style name="Dark" parent="#android:style/Theme.Material.NoActionBar" >
...
</style>

Change Custom Android Theme Dynamically

I have a few customer theme's in my style.xml file. I want to change the theme upon clicking a button in an alertDialog.
When I try to change the theme, I get an error that the class can't be inflated. I verified that the minimum API is at least 21 which from other posts has to be done.
Here is my code:
style.xml
<resources>
<!-- Base application theme. -->
<style name="Theme.easter" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/easter_color_1</item>
<item name="color_2">#color/easter_color_2</item>
<item name="color_3">#color/easter_color_3</item>
<item name="color_4">#color/easter_color_4</item>
<item name="color_5">#color/easter_color_5</item>
</style>
<style name="soft" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/soft_color_1</item>
<item name="color_2">#color/soft_color_2</item>
<item name="color_3">#color/soft_color_3</item>
<item name="color_4">#color/soft_color_4</item>
<item name="color_5">#color/soft_color_5</item>
</style>
<style name="Theme.girl" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/girl_color_1</item>
<item name="color_2">#color/girl_color_2</item>
<item name="color_3">#color/girl_color_3</item>
<item name="color_4">#color/girl_color_4</item>
<item name="color_5">#color/girl_color_5</item>
</style>
<style name="Theme.summer" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/summer_color_1</item>
<item name="color_2">#color/summer_color_2</item>
<item name="color_3">#color/summer_color_3</item>
<item name="color_4">#color/summer_color_4</item>
<item name="color_5">#color/summer_color_5</item>
</style>
<style name="Theme.warm" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/warm_color_1</item>
<item name="color_2">#color/warm_color_2</item>
<item name="color_3">#color/warm_color_3</item>
<item name="color_4">#color/warm_color_4</item>
<item name="color_5">#color/warm_color_5</item>
</style>
</resources>
I am trying to dynamically change the theme using the following code:
#Override public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.EASTER);
break;
case 1:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.SOFT);
break;
case 2:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.GIRL);
break;
case 3:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.SUMMER);
break;
case 4:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.WARM);
break;
}
}
themeUtils.class
package sourceCode;
import android.app.Activity;
import android.content.Intent;
import com.projects.fbgrecojr.vamoose.R;
/**
* Created by fbgrecojr on 8/26/15.
*/
public class themeUtils {
private static int cTheme;
public final static int EASTER = 0;
public final static int SOFT = 1;
public final static int GIRL = 2;
public final static int SUMMER = 3;
public final static int WARM = 4;
public static void changeToTheme(Activity activity, int theme) {
cTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (cTheme) {
default:
case EASTER:
activity.setTheme(R.style.Theme_easter);
break;
case SOFT:
activity.setTheme(R.style.soft);
break;
case GIRL:
activity.setTheme(R.style.Theme_girl);
break;
case SUMMER:
activity.setTheme(R.style.Theme_summer);
break;
case WARM:
activity.setTheme(R.style.Theme_warm);
break;
}
}
}
finally, in my onCreate() method in the activity that I want to change the theme I have this code:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeUtils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_admin_settings);
....
}
How can I fix this??

Categories