In the Android resources xml to reference the value of an attribute for a theme you use the question-mark (?) instead of at (#). Such as ListViewCustomStyle below:
<ListView
android:id="#+id/MainScreenListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?ListViewCustomStyle"/>
How can I use the value of the ListViewCustomStyle in code? If I try it the normal way i.e.
com.myapp.R.attr.ListViewCustomStyle
Then the code crashes. Is there a special way to access this since it is a reference to an item and not an actual item?
It might just be crashing because you wrote ListRowCustomStyle there, and ListViewCustomStyle in your xml.
The way I do this is to have the tag style="#style/my_button" for example (with no android: preceding it). Then you can define your style in the values/styles.xml file, e.g.
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="my_button" parent="#android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:textColor">#FFFFFFFF</item>
...
</style>
</resources>
You can access the style in code by using the id R.style.my_button
I believe in the xml you wanted to write
style="#style/ListViewCustomStyle"
Anyway, how to use it in code?
Last time I check, it was impossible :(
I did it with a trick:
create a layout file as the example that follows:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/MyCustomStyle"/>
when you want to add an object with your custom style in code, you have to inflate it, using this layout you just created:
:
LayoutInflater inflater = LayoutInflater.from(this); // this = activity or context
Button button = (Button) inflater.inflate(R.layout.myButtonWithMyStyle, null); //use the same layout file as above
button.setText("It works!");
myView.addView(button);
This is considerably slower than creating a Button in code. It may be a problem if you create hundreads of Views at the same time using this method. Less than that I think you can handle it.
Related
I am trying to create a view pragmatically and then add it to my activity. This bit is working fine, however the theme for the view group isn't inherited by my new view
My theme:
<style name="CustomButtonTheme" parent="#style/Widget.AppCompat.Button">
<item name="android:textColor">#FF0000</item>
<item name="android:background">#00FF00</item>
</style>
My layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/buttonArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme="#style/CustomButtonTheme">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This button inherits CustomButtonTheme" />
</LinearLayout>
Java code
AppCompatButton button = new AppCompatButton(getContext());
button.setText("This button does not inherit CustomButtonTheme");
LinearLayout buttonArea = findViewById<LinearLayout>(R.id.buttonArea);
buttonArea.addView(button);
An android:theme attribute in a layout will only have effect during inflation, and only on that particular subtree. It won't be applied to the Activity's overall theme.
All that attribute does, though, is cause the LayoutInflater to wrap its current Context with the specified theme in a ContextThemeWrapper. We could do something similar ourselves, and just to illustrate the basic usage:
ContextThemeWrapper wrapper = new ContextThemeWrapper(getContext(), R.style.CustomButtonTheme);
AppCompatButton button = new AppCompatButton(wrapper);
However, this has already been done for us, basically, when the LayoutInflater created a ContextThemeWrapper internally, for that android:theme attribute. That ContextThemeWrapper is the Context that the LinearLayout will have been created with, so we can simply use its Context to instantiate our AppCompatButton:
AppCompatButton button = new AppCompatButton(buttonArea.getContext());
As the OP points out, this has the added benefit of working in pretty much every similar setup without having to know the exact theme needed.
I am trying to use a custom title to include an image button to the title bar.
I got a lot of help form this post: android: adding button to the title of the app?, but could not get it work for my ListActivity.
In a nutshell, following is what I have:
I hide the titlebar in the AndroidManifest.xml
The specify a relative layout for the custom title (workorder_list_titlebar.xml)
My Activity Class looks like the following:
public class WorkOrderListActivity extends ListActivity {
String[] orders={"WO-12022009", "WO-12302009","WO-02122010", "02152010"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.workorder_list_titlebar);
setContentView(R.layout.workorder_list);
setListAdapter(new ArrayAdapter(this,R.layout.workorder_list, R.id.label,orders));
}
}
When I ran the app, I got AndroidRuntimeException: You cannot combine custom titles with other title features.
Base on the stack trace, the exception was thrown by com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:183), that was triggered by setlistAdapter call.
Does anyone have the same problem with ListActivity?
Also once I manage to get this work, how do I attach listeners to the image button for it to do something?
Thanks in advance.
I had the same issue and I fix it deleting
<item name="android:windowNoTitle">true</item>
from my theme.xml
Make you create custom style in “values” folder. Make sure you code as below.
<style name="CustomTheme" parent="android:Theme">
Don't modify parent parameter.
This did work for me.
Instead of modifying your theme.xml you may also:
create a new XML style file my_theme.xml in values folder like this:
<style name="MyWindowTitleBackground">
<item name="android:background">#444444</item>
</style>
<style name="MyTheme" parent="android:Theme">
<item name="android:windowTitleBackgroundStyle">#style/MyWindowTitleBackground</item>
</style>
You may define other settings as you like in this theme.
Then just use this theme in your manifest within the activity's attributes
android:theme="#style/MyTheme"
Finally set your custom title as always in your activity.java:
final Window window = getWindow();
boolean useTitleFeature = false;
// If the window has a container, then we are not free
// to request window features.
if (window.getContainer() == null) {
useTitleFeature = window
.requestFeature(Window.FEATURE_CUSTOM_TITLE);
}
setContentView(R.layout.screen_main);
if (useTitleFeature) {
window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
R.layout.custom_title);
// Set up the custom title
main_title = (TextView) findViewById(R.id.title_left_text);
main_title.setText(R.string.app_name);
main_title = (TextView) findViewById(R.id.title_right_text);
main_title.setText(R.string.Main_titleInfo);
}
Don't forget to define the custom_title.xml file in your layout folder. For example...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical" >
<TextView
android:id="#+id/title_left_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:ellipsize="end"
android:singleLine="true" />
<TextView
android:id="#+id/title_right_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#fff" />
</RelativeLayout>
I think notenking is right, that this is a problem in activities within tabs. Since some of my activities can either be stand-alone or within a tab, I've found the following helps:
final Window window = getWindow();
boolean useTitleFeature = false;
// If the window has a container, then we are not free
// to request window features.
if(window.getContainer() == null) {
useTitleFeature = window.requestFeature(Window.FEATURE_CUSTOM_TITLE);
}
setContentView(layoutId);
if (useTitleFeature) {
window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
}
May be you find this problem when use it in tab,for there already have a title and you can not add a custom title again.
you should add this custom title in the activity which you get the Tab
I did exactly as Sunny Dasari did but with one small change I put the # before and android in the parent attribute.
So my code looked like this.
<style name="CustomTheme" parent="#android:Theme">
To avoid crashing, you can simply add
android:theme="#style/android:Theme"
to the <Activity> tag in your AndroidManifest.xml:
<activity
android:name="test.TestActivity"
android:label="#string/app_name"
android:theme="#style/android:Theme">
This is because the styles defined in your default theme conflict with FEATURE_CUSTOM_TITLE (such as the attribute android:windowNoTitle). By using another theme, you can avoid such problems.
However, you might further need to define your own theme to change other attributes, such as android:windowTitleSize, background color, text color and font, etc. In this case, you can derive your theme from an existing theme (e.g., Theme.Light) and modify its attributes:
<resources>
<style name="CustomWindowTitleBackground">
<item name="android:background">#323331</item>
</style>
<style name="CustomTheme" parent="#style/android:Theme.Light">
<item name="android:windowNoTitle">false</item>
<item name="android:windowTitleSize">60dip</item>
<item name="android:windowTitleBackgroundStyle">#style/CustomWindowTitleBackground</item>
</style>
</resources>
Try swapping following lines:
setContentView(R.layout.workorder_list);
this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.workorder_list_titlebar);
I have run into this issue as well and it looks like it is an issue with what theme is applied to an activity in the AndroidManifest.xml file. If I use a theme like:
android:theme="#android:style/Theme.Holo
Then it will throw the error
android.util.AndroidRuntimeException: You cannot combine custom titles with other title features
However if I use a different theme like:
android:theme="#android:style/Theme.Black"
then it will not throw the error and subsequently will not crash. However I am trying to use a theme like Theme.Holo. I'm not sure if there is a way around this.
Since, I was trying to compile my program in android 4.0, I was facing the same problem. None of these solutions helped.So, I copied my style contents from values > styles.xml and pasted it in values-v11 styles.xml file and values-v14 styles.xml file. Bingo, the trick worked.
As a beginner most of the answers didn't help me for my case. So here is my answer.
Go to res/values folder in your android project and check for strings.xml (this file may vary in your case, something like themes.xml)
Inside the file under resource tag check whether you have style tags. If you don't find it, add the code below as mentioned below as a child to resources tag
something like below
<resources>
<style name="SomeNameHere">
<item name="android:windowNoTitle">true</item>
</style>
</resources>
if you already have style tag, just add the code below to your style tag
<item name="android:windowNoTitle">true</item>
As I asked in the title, is there any way to do so?
Now, when I put all styles into one file it looks a little crowded, I would like to separate styles.
For example:
res/values/styles_for_main_screen
res/values/styles_for_set_screen
And then in main_screen layout
<TextView
style="#styles_for_main_screen/text_view_custom_style">
</TextView>
This example obviously doesn't work, but it shows what I'd like to achieve.
I read in every tutorial that we need to put our custom styles into styles.xml file, but I wonder if there is a possibility to diversify styles in few xml files?
Every question I read was something like "how to do .... in styles.xml".
I can't find question similar to mine.
Example how it should be done, thanks #Frank N. Stein for the answer:
This how looks my custom xml res/values/styles_for_main_screen
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="custom_back">
<item name="android:background">#E81C1C</item>
<item name="android:text">whatr</item>
</style>
</resources>
and then to retrieve this style I just write:
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
style="#style/custom_back"
/>
so the convention looks like:
style="#(what I want to retrieve)/(name of style)"
from the android developers site
In XML: #[package:]style/style_name
You can call your style files whatever you want (if you respect the naming conventions and you put them all in the values folder/s), as you do with strings and colors.
Therefore, YES! You can have multiple ones, if so you desire.
Obviously, you will NOT specify the path to each file.
Referencing the style/s by using R.style.your_new_style is enough.
Remember that, android scans the files found int the /values directory by reading their content. For styles, every <style name="styleName" > ... </style> will be parser and a style object reference will be created.
Then, as Frank said, Yes. You can use whatever file name to write your custom styles.
During development of Android application, I noticed that I use multiple buttons, that the different between them is the Id, the text and the onclick function.
So I implemented a different XML file holding 1 styled button, and when I want to use a button I just import it into the required layout.
But then I realized I have a new problem: I don't know how to set all the different parameters at each imported button...
Is there a method to perform this and stick to DRY approach?
Well, if you need multiple buttons, you will need to give them different identifiers. You can do this in your import declaration like this:
<include layout="#layout/your_button"
android:id="#+id/loginButton" />
Then, you can reference them by ID like usual:
Button loginButton = (Button) findViewById(R.id.loginButton);
loginButton.setText("Login");
However, I am not sure this is a better approach than just declaring your buttons as needed in XML. If you want to avoid repeating styling, you can define a custom style for your button and apply it in the XML declaration. See the docs on styling for more information.
Below is an example from the docs with an EditText.
In the styles:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CustomText" parent="#style/Text">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#008</item>
</style>
</resources>
In your layout:
<?xml version="1.0" encoding="utf-8"?>
<EditText
style="#style/CustomText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello, World!" />
I am trying to use a custom title to include an image button to the title bar.
I got a lot of help form this post: android: adding button to the title of the app?, but could not get it work for my ListActivity.
In a nutshell, following is what I have:
I hide the titlebar in the AndroidManifest.xml
The specify a relative layout for the custom title (workorder_list_titlebar.xml)
My Activity Class looks like the following:
public class WorkOrderListActivity extends ListActivity {
String[] orders={"WO-12022009", "WO-12302009","WO-02122010", "02152010"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.workorder_list_titlebar);
setContentView(R.layout.workorder_list);
setListAdapter(new ArrayAdapter(this,R.layout.workorder_list, R.id.label,orders));
}
}
When I ran the app, I got AndroidRuntimeException: You cannot combine custom titles with other title features.
Base on the stack trace, the exception was thrown by com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:183), that was triggered by setlistAdapter call.
Does anyone have the same problem with ListActivity?
Also once I manage to get this work, how do I attach listeners to the image button for it to do something?
Thanks in advance.
I had the same issue and I fix it deleting
<item name="android:windowNoTitle">true</item>
from my theme.xml
Make you create custom style in “values” folder. Make sure you code as below.
<style name="CustomTheme" parent="android:Theme">
Don't modify parent parameter.
This did work for me.
Instead of modifying your theme.xml you may also:
create a new XML style file my_theme.xml in values folder like this:
<style name="MyWindowTitleBackground">
<item name="android:background">#444444</item>
</style>
<style name="MyTheme" parent="android:Theme">
<item name="android:windowTitleBackgroundStyle">#style/MyWindowTitleBackground</item>
</style>
You may define other settings as you like in this theme.
Then just use this theme in your manifest within the activity's attributes
android:theme="#style/MyTheme"
Finally set your custom title as always in your activity.java:
final Window window = getWindow();
boolean useTitleFeature = false;
// If the window has a container, then we are not free
// to request window features.
if (window.getContainer() == null) {
useTitleFeature = window
.requestFeature(Window.FEATURE_CUSTOM_TITLE);
}
setContentView(R.layout.screen_main);
if (useTitleFeature) {
window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
R.layout.custom_title);
// Set up the custom title
main_title = (TextView) findViewById(R.id.title_left_text);
main_title.setText(R.string.app_name);
main_title = (TextView) findViewById(R.id.title_right_text);
main_title.setText(R.string.Main_titleInfo);
}
Don't forget to define the custom_title.xml file in your layout folder. For example...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical" >
<TextView
android:id="#+id/title_left_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:ellipsize="end"
android:singleLine="true" />
<TextView
android:id="#+id/title_right_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#fff" />
</RelativeLayout>
I think notenking is right, that this is a problem in activities within tabs. Since some of my activities can either be stand-alone or within a tab, I've found the following helps:
final Window window = getWindow();
boolean useTitleFeature = false;
// If the window has a container, then we are not free
// to request window features.
if(window.getContainer() == null) {
useTitleFeature = window.requestFeature(Window.FEATURE_CUSTOM_TITLE);
}
setContentView(layoutId);
if (useTitleFeature) {
window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
}
May be you find this problem when use it in tab,for there already have a title and you can not add a custom title again.
you should add this custom title in the activity which you get the Tab
I did exactly as Sunny Dasari did but with one small change I put the # before and android in the parent attribute.
So my code looked like this.
<style name="CustomTheme" parent="#android:Theme">
To avoid crashing, you can simply add
android:theme="#style/android:Theme"
to the <Activity> tag in your AndroidManifest.xml:
<activity
android:name="test.TestActivity"
android:label="#string/app_name"
android:theme="#style/android:Theme">
This is because the styles defined in your default theme conflict with FEATURE_CUSTOM_TITLE (such as the attribute android:windowNoTitle). By using another theme, you can avoid such problems.
However, you might further need to define your own theme to change other attributes, such as android:windowTitleSize, background color, text color and font, etc. In this case, you can derive your theme from an existing theme (e.g., Theme.Light) and modify its attributes:
<resources>
<style name="CustomWindowTitleBackground">
<item name="android:background">#323331</item>
</style>
<style name="CustomTheme" parent="#style/android:Theme.Light">
<item name="android:windowNoTitle">false</item>
<item name="android:windowTitleSize">60dip</item>
<item name="android:windowTitleBackgroundStyle">#style/CustomWindowTitleBackground</item>
</style>
</resources>
Try swapping following lines:
setContentView(R.layout.workorder_list);
this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.workorder_list_titlebar);
I have run into this issue as well and it looks like it is an issue with what theme is applied to an activity in the AndroidManifest.xml file. If I use a theme like:
android:theme="#android:style/Theme.Holo
Then it will throw the error
android.util.AndroidRuntimeException: You cannot combine custom titles with other title features
However if I use a different theme like:
android:theme="#android:style/Theme.Black"
then it will not throw the error and subsequently will not crash. However I am trying to use a theme like Theme.Holo. I'm not sure if there is a way around this.
Since, I was trying to compile my program in android 4.0, I was facing the same problem. None of these solutions helped.So, I copied my style contents from values > styles.xml and pasted it in values-v11 styles.xml file and values-v14 styles.xml file. Bingo, the trick worked.
As a beginner most of the answers didn't help me for my case. So here is my answer.
Go to res/values folder in your android project and check for strings.xml (this file may vary in your case, something like themes.xml)
Inside the file under resource tag check whether you have style tags. If you don't find it, add the code below as mentioned below as a child to resources tag
something like below
<resources>
<style name="SomeNameHere">
<item name="android:windowNoTitle">true</item>
</style>
</resources>
if you already have style tag, just add the code below to your style tag
<item name="android:windowNoTitle">true</item>