cannot combine custom titles with other title features - android

I am getting this error when calling the setContentView() after
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.maintitlebar);
The code is in the onCreate() for my class which extends ListActivity.
My manifest XML file shows the default AppTheme for the application:
android:theme="#style/AppTheme"
I have updated styles.xml to be:
<resources>
<style name="AppTheme" parent="android:Theme.Light" >
<item name="android:windowNoTitle">true</item>
</style>
</resources>
This seems to be in accordance with the main posts on this error message. I have also cleaned the build, yet I am still getting the above error message. Has anybody any idea what is causing the clash?

I had a similar problem that drove me insane: I have 2 versions of the same app using a shared library project as their common code (over 95% of each app is made of that shared library project): One runs fine, without any problem whatsoever. The other crashes upon start with the same error message & symptoms you describe:
You cannot combine custom titles with other title features
The layout XML files are common as well! So, I couldn't find any explanation for this weird problem.
After much brainstorming between me, myself and I, I discovered that the only difference between the two apps is that the one that runs fine has this in its AndroidManifest.xml:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="7" />
And the one that crashes has this in its AndroidManifest.xml:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="13" />
So, you see, the Android UI is touted as being a 4th-generation UI framework, in which the UI is declarative and independently themed, but at the end of the day it's all the same st: Developing in C (for example) for Microsoft Windows is no more time consuming than developing in Java for the Android because the Android development framework is full of landmines like this in which the compiler won't tell you anything at compile time, and the thrown exception won't tell you either. Instead, you have to rely on **luck finding that little snippet of documentation (that may or may not exist), providing you with a hint as to where to look for the root cause of the problem.
I hope that this information will be helpful to many who experience the same problem.

You should use
<item name="android:windowNoTitle">false</item>
in your custom theme

I have the same problem and here is what it worked for me:
AndroidManifest.xml
< application
...
...
android:theme="#style/CustomTheme" >
Styles.xml
< style name="CustomTheme" parent="android:Theme">
< /style>
MainActivity.java
1) super.onCreate(savedInstanceState);
2) requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
3) setContentView(R.layout.activity_main);
4) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title1);
The order of the codes is important as shown above.
If you have:
1) requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
2) setContentView(R.layout.activity_main);
3) super.onCreate(savedInstanceState);
4) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title1);
You will get this exception:
android.view.InflateException: Binary XML file line #37: Error inflating class fragment

It matters which parent theme you are using:
If I use parent="android:Theme", then android:windowNoTitle="false" works (as per #Vladimir's answer).
However, if I use parent="android:Theme.Holo.Light", then I need to use android:windowActionBar="false" (as per #Jasper's comment). Here's my working xml using the Holo Light theme:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ScheduleTimes" parent="android:Theme.Holo.Light">
<item name="android:windowActionBar">false</item>
</style>
</resources>

Maybe this question up to this time is already solved, but i post this answer for those who are having this error...i had a very similar problem, and changing the manifest file didn't work at all, but what it worked for me was go to the gradle Scripts and go to the build.gradle(Module:app) in this file, i changed the minSdkVersion and the targetSdkVersion with the same in both of them in this case for example 7, and the app runs correctly!

I had the same problem. I downloaded an app named BlueToothChat.
So, I add the following code to the string.mxl file within the value folder:
<resources>
<style name="CustomTheme" parent="#android:Theme">
<item name="android:windowNoTitle">false</item>
</style>
<string name="app_name">Bluetooth Chat</string>
...
and then add: {Theme = "#style/CustomTheme"} to the home page of the activity page (BluetoothChat.cs):
namespace BluetoothChat
{
/// <summary>
/// This is the main Activity that displays the current chat session.
/// </summary>
[Activity (Label = "#string/app_name", MainLauncher = true,
Theme = "#style/CustomTheme", ConfigurationChanges
Android.Content.PM.ConfigChanges.KeyboardHidden |
Android.Content.PM.ConfigChanges.Orientation)]
public class BluetoothChat : Activity
However, I did not test variations of this procedure or define any real CustomTheme attributes.

Related

How can I run a separate layout for Tabs in Android

I created a separate layout for tablets in android studio, but I'm unable to run that particular layout, whenever I try to run it, it default runs the normal layout, which is for mobile
I have to agree with the user Ricardo but having said that, I need some more information. First of all how you load the layout, what is the layout name and where did you place these layouts.
Check this before https://developer.android.com/training/multiscreen/screensizes.html and you have to do something like this.
In your manifest
<resources>
<bool name="isTablet">true</bool>
</resources>
<resources>
<bool name="isTablet">false</bool>
</resources>
In your Mainactivity
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
// do something
} else {
// do something else
}

Disabling Android O auto-fill service for an application

Android O has the feature to support Auto-filling for fields. Is there any way I can disable it for a specific application. That is I want to force my application not to use the auto-fill service.
Is it possible ?
To block autofill for an entire activity, use this in onCreate() of the activity:
getWindow()
.getDecorView()
.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
Is there any better method than this ?
Currently there is no direct way to disable the autofill for an entire application, since the autofill feature is View specific.
You can still try this way and call BaseActivity everywhere.
public class BaseActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
disableAutofill();
}
#TargetApi(Build.VERSION_CODES.O)
private void disableAutofill() {
getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
}
}
You can also force request autofill this way.
public void forceAutofill() {
AutofillManager afm = context.getSystemService(AutofillManager.class);
if (afm != null) {
afm.requestAutofill();
}
}
Note: At the moment autofill feature is only available in API 26 Android Oreo 8.0
Hope this helps!
I believe the accepted answer is incorrect:
So I have my own class which is extends the android.support.v7.widget.AppCompatEditText and all I did is overwrote the following method with the following value:
#Override
public int getAutofillType() {
return AUTOFILL_TYPE_NONE;
}
no other solutions worked, not even android:importantForAutofill="no".
getAutofillType() comes from the View class, so it should work for every other class such as TextInputEditText too!
I ran into this too. It turns out the issue was caused by setting the hint text on the EditText nested inside the TextInputLayout.
I did some digging and found this nugget in the 26.0.0 Beta 2 release notes.
Andorid Support Release Notes June 2017
TextInputLayout must set hints on onProvideAutofillStructure()
That led me to try setting the hint on the TextInputLayout instead of the nested EditText.
This resolved the crashing issue for me.
Example:
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Some Hint Text"
android.support.design:hintAnimationEnabled="true"
android.support.design:hintEnabled="true"
android.support.design:layout_marginTop="16dp">
<android.support.design.widget.TextInputEditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.TextInputLayout>
Seems to be a bug that needs to be fixed : https://issuetracker.google.com/issues/67675432
In the meanwhile a workaround for now is to disable the AutoFill feature for the whole project.
You can add in the values-v26/styles.xml file the following style or you can edit your BaseEditTextStyle if you are using a specific style for your EditText views.
<style name="App_EditTextStyle" parent="#android:style/Widget.EditText">
<item name="android:importantForAutofill">noExcludeDescendants</item>
</style>
and in the values-v26/themes.xml file you can simply add to the default theme that you are using in your app the items editTextStyle and android:editTextStyle like following :
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="android:editTextStyle">#style/App_EditTextStyle</item>
<item name="editTextStyle">#style/App_EditTextStyle</item>
</style>
this way you can apply this changes for all your EditTexts without needing to change your layout files or Activities (and later on you can easily remove it when the bug is fixed).
Is it possible ?
Not that I am aware of. Certainly, nothing is documented.
Is there any better method than this ?
Not that I am aware of.
In your EditText attributes add android:importantForAutofill="no"
This should be a temporary fix and will only apply to api 26+
Create custom EditText style and set android:importantForAutofill to no.
<style name="EditTextStyleWithoutAutoFill" parent="Widget.AppCompat.EditText">
<item name="android:importantForAutofill">no</item>
</style>
Then in your activity theme set this style for editTextStyle.
<item name="android:editTextStyle">#style/EditTextStyleWithoutAutoFill</item>
In my case, our app targets SDK version 21 but newer devices (26+) were still popping up the autocomplete. Pretty big problem if the app runs on devices that are shared between people. Using just android:importantForAutofill="no" did not work for me.
The only solution that I found to work in my case was:
<EditText
android:importantForAutofill="no"
tools:targetApi="o"
android:autofillHints="AUTOFILL_HINT_SMS_OTP" ...
The reason I added android:autofillHints="AUTOFILL_HINT_SMS_OTP" was because if you long-pressed on the EditText it would still bring up autofill. Basically, I told the field's autofill that it is waiting for a text message that will never be sent. Bit of a hack, I know...
Note: you may have to add xmlns:tools="http://schemas.android.com/tools" to your schemas' if it is not there already.
Had the same problem with API 28+ and disable Autofill. For me the only solution was to disable long click for my views.
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:longClickable="false"
android:text="#={model.emailAdress}"/>
With reference to Google issue tracker, it has been fixed.
This is fixed on Android 8.1
If any issue persists, please report at Google issue tracker they will re-open to examine.

Support library VectorDrawable Resources$NotFoundException

I am using Design Support Library version 23.4.0. I have enabled the gradle flag:
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
I am using build tools version 23.0.2, but still, I am getting Resources$NotFoundException on KitKat or lower.
It is occurring when I use android:drawableLeft or imageView.setImageResource(R.drawable.drawable_image).
And yes, I am putting this on every activity where I am using drawables
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Is this a bug of the support library?
It took 3 separate things for me to get this to work using support library 23.4.0:
Add this to build.gradle
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
Add the following to onCreate of your Application class
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
(From the reference of this link - "https://stackoverflow.com/a/45582033/10752962")
In API less then 21,use this line before setContentView();
For all XML views in which you are setting a vector drawable replace
android:src
with
app:srcCompat
and in the code replace this:
imageView.setImageResource(...);
with
imageView.setImageDrawable(...);
To complement some of the answers here: backward-compatible support for VectorDrawables comes with a price and doesn't work in all cases.
In which cases does it work? I've made this diagram to help (valid for Support Library 23.4.0 to at least 25.1.0).
Try using:
imageView.setImageDrawable(VectorDrawableCompat.create(getResources(), drawableRes, null));
You don't have to add AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
this way.
Just inflate your vector drawables using VectorDrawableCompat and you're all set.
We had the same issue. Vector drawables were not visible on Kitkat. I solved this issue by adding AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); to the onCreate method of Activities.
Before that dont forget to add:
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
and call setImageResource for the view that you use the vector drawable. My view is ImageButton. I have Android SDK build tools version 23.0.3
Sorry for being late to the party but this answer may help users who want to enable the flag AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); for all activities.
1. Create a class which extends to Application (android.app.Application)
public class MyApplicationClass extends Application
{
#Override
public void onCreate()
{
super.onCreate();
}
}
2. Head over to Manifest.xml and add the following line to your tag
<application
android:name=".MyApplicationClass"
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">
...
</application>
3. Add the following code above onCreate in MyApplicationClass.java
// This flag should be set to true to enable VectorDrawable support for API < 21
static
{
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Complete code for MyApplicationClass.java
import android.app.Application;
import android.support.v7.app.AppCompatDelegate;
/**
* Created by Gaurav Lonkar on 23-Dec-17.
*/
public class MyApplicationClass extends Application
{
// This flag should be set to true to enable VectorDrawable support for API < 21
static
{
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
#Override
public void onCreate()
{
super.onCreate();
}
}
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
use this in app.gradle
Then use AppCompatDrawableManager to setDrawable and getDrawable. Works for me
Support for vector drawables in places like android:drawableLeft was disabled in support library 23.3. It was announced on Google+:
we’ve decided to remove the functionality which let you use vector
drawables from resources on pre-Lollipop devices due to issues found
in the implementation in version 23.2.0/23.2.1. Using app:srcCompat and setImageResource()
continues to work.
Links to issues:
https://code.google.com/p/android/issues/detail?id=205236
https://code.google.com/p/android/issues/detail?id=204708
However, if you can live with those issues, in 23.4 you can re-enable this functionality using AppCompatDelegate.setCompatVectorFromResourcesEnabled().
If you're curious how this works, the best person to learn from is Chris Banes, who authored this functionality. He explains in detail on his blog.
change
imageView.setImageResource(R.drawable.drawable_image)
to
imageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.drawable_image));
if you want to use vectordrawable in xml, use this:
app:srcCompat="#drawable/drawable_image"
I had a similar problem long ago, it did not work by setting
vectorDrawables.useSupportLibrary = true
only worked when I created the "mipmap" folder, and the code used
imageView.setImageResource (R.mipmap.drawable_image)
It has more Info here
Inflating Drawable's
`VectorDrawable` and `AnimatedVectorDrawable` in this support library can be inflated in this way:
Calling static getDrawable() methods:
//This will only inflate a drawable with <vector> as the root element
VectorDrawable.getDrawable(context, R.drawable.ic_arrow_vector);
//This will only inflate a drawable with <animated-vector> as the root element
AnimatedVectorDrawable.getDrawable(context, R.drawable.ic_arrow_to_menu_animated_vector);
// This will inflate any drawable and will auto-fallback to the lollipop implementation on api 21+ devices
ResourcesCompat.getDrawable(context, R.drawable.any_drawable);
If inflating the Drawable in java code, it is recommended to always use ResourcesCompat.getDrawable() as this handles Lollipop fallback when applicable. This allows the system to cache Drawable ConstantState and hence is more efficient.
The library has the following morph (bi-directional) animations :
Play-Pause morph animation
Play-Stop morph animation
Arrow-Hamburger menu morph animation
As you can see, I produced the above image on my API 16 phone:
import com.wnafee.vector.compat.AnimatedVectorDrawable;
mdrawable = (AnimatedVectorDrawable) AnimatedVectorDrawable.getDrawable(this.getApplicationContext(), R.drawable.consolidated_animated_vector);
Look at the github README for vector-compat here: https://github.com/wnafee/vector-compat
This will fix your problem (down to API 14) if you merge it with your app module's build.gradle dependencies (usually at the end of file):
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//Trying to FIX Binary XML file line #2: invalid drawable tag animated-vector
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
//not needed
// compile 'com.android.support:support-vector-drawable:25.0.0'
compile 'com.wnafee:vector-compat:1.0.5'//*******holy grail *******https://github.com/wnafee/vector-compat
// Failed to resolve: com.android.support:support-animated-vector-drawable:25.0.0
//not needed
// compile 'com.android.support:support-animated-vector-drawable:25.0.0'
}
Do not put your vectors in drawable-anydpi
, old devices does not support that
put them in drawable
In my particular case, I had this problem because I was using a drawable selector as the image resource with several vectors in the selector, as in:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/vector_select_blue"/>
<item android:state_pressed="true" android:drawable="#drawable/vector_select_black"/>
.
.
etc
</selector>
Yes, pretty bad, but didn't know better at the time.
So, the right way of doing this is using the tint property in your vector file, as in:
<vector ..vector properties..
android:tint="#color/vector_color_selector">
<path ..path properties../>
</vector>
(You can also use the app:tint attribute in the AppCompatImageView)
And now, your vector_color_selector file should have the colors you want, as in:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#color/blue"/>
<item android:state_pressed="true" android:color="#color/black"/>
.
.
etc
</selector>
I hope this helps someone if previous answers didn't work for you. Stating the obvious, but I must say that you still need to set vectorDrawables.useSupportLibrary = true in gradle, use AppCompatImageView and use app:srcCompat or setImageDrawable + AppCompatResources.getDrawable to avoid any troubles with the vector compat library.
Use AppCompatImageView instead of ImageView as said by Harish Gyanani in comments , it works fine with this for me.
Official docs
I had the same problem and actually what was missing is I was using app:srcCompat on AppCompatTextView except of AppCompatImageView.
The way I have found the problematic part:
My error looks like:
Fatal Exception: android.content.res.Resources$NotFoundException
Resource ID #0x7f0700d1
Here are the steps I followed the resource id of the mentioned drawable :
APK Analyzer -> classesXXX.dex
In this dex file I opened the directory of my apps package name and went to R$drawable file
R$drawable -> Show as byte code.
Search for ID [0x7f0700d1] (check your own ID)
Find the image and check for all the usages (CMD + F7) of the resource
Fix
Hope it will help somebody.

What causes "RuntimeException: Binary XML file line #20: You must supply a layout_height attribute." (ActionBarScherlock is suspected)?

I have app with ActionBarScherlock and I use ACRA. I receive crash reports from some users with following error:
"java.lang.RuntimeException: Binary XML file line #20: You must supply a layout_height attribute.
at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:491)
at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:3602)
at android.view.ViewGroup$LayoutParams.<init>(ViewGroup.java:3554)
at android.widget.AbsListView$LayoutParams.<init>(AbsListView.java:4322)
at android.widget.AbsListView.generateLayoutParams(AbsListView.java:4116)
at android.widget.AbsListView.generateLayoutParams(AbsListView.java:74)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:332)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
at android.webkit.WebTextView$AutoCompleteAdapter.getView(WebTextView.java:650)
at android.widget.AbsListView.obtainView(AbsListView.java:1430)
at android.widget.AutoCompleteTextView$DropDownListView.obtainView(AutoCompleteTextView.java:1548)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1216)
at android.widget.AutoCompleteTextView.buildDropDown(AutoCompleteTextView.java:1376)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1140)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1022)
at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1005)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3717)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)"
Of course I've tried to google it and found that it is most likely caused by ActionBarScherlock (and I noticed that every user who encountered with this error uses android 2.3.*) but haven't found a solution.
It's a bit disconcerting that I can't reproduce this error on my own 2.3.* device...
So, what causes this error?
In my case this was due to a problem with ActionBarsherlock.
In my Android manifest I had android:theme="#style/AppTheme"
then when you go to styles, i saw my AppTheme's parent was "AppBaseTheme". This was the problem!
<style name="AppTheme" parent="AppBaseTheme">
I changed this to
<style name="AppTheme" parent="Theme.Sherlock">
And my problem was solved.
One of our #1 crashes came from this issue, especially on ZTE devices. While the actionbar worked on most screens, we were getting this crash when users interacted with a Webview Edittext/InputBox. The crash happened as a result of autocomplete on the Webview. Disabling autocomplete seemed to eliminate the crashes. Why autocomplete should have anything to do with the Actionbar is still a mystery.
Here we disable the autocomplete just for ZTE devices. We may expand the list later if we have problems on other devices.
public static boolean disableWebViewAutoCompleteForDevicesThatCrash(WebView webView)
{
// We may add some other bizarre devices to this list if the ZTE fix works well.
if ("ZTE".equals(Build.MANUFACTURER))
{
webView.getSettings().setSaveFormData(false);
webView.clearFormData();
return true;
}
else
{
return false;
}
}
The layout_height in this instance is defined as ?attr/actionBarSize which is a theme attribute with a value of #dimen/action_bar_height that is defined in three places: values/, values-land/, and values-sw600dp/.
This is usually cased by OEMs who've tinkered with the resource system causing some aspect of this chain to not load correctly. There's nothing we can really do, as far as I'm aware.
I had same problem and solve it by change in AndroidManifest.xml. You have to set theme of particular Activity or complete application to Theme.Sherlock.Light (I think you can specify only Theme.Sherlock).
In code it will be:
<application
...
android:theme="#style/Theme.Sherlock.Light">
or
<activity
...
android:theme="#style/Theme.Sherlock.Light">

Read Newer Theme Attributes On Older Platform

I am trying to read attribute values from themes and styles which were designed for platforms that are newer than I am running my application on.
Please don't ask why. If you know anything about the libraries I write then you should already know that I like to push the capabilities of the platform :)
I am operating under the presumption that when Android styles are compiled the attribute constants are what is used for the keys and therefore should theoretically be able to be read on any platform somehow. This is what I have observed to be happening with layout XMLs in my other libraries with no trouble.
Here is a base test case which shows the problem. This should be compiled using Android 3.0+.
<resources>
<style name="Theme.BreakMe">
<item name="android:actionBarStyle">#style/Widget.BreakMe</item>
</style>
<style name="Widget.BreakMe" parent="android:Widget">
<item name="android:padding">20dp</item>
</style>
</resources>
The fact that this uses android:actionBarStyle specifically is irreleveant. All that should be understood is that its an attribute which was only available starting with Android 3.0.
Here are the way that I have tried to access these values thus far on platforms prior to Android 3.0.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Break Me"
style="?android:attr/actionBarStyle"
/>
and
<declare-styleable name="Whatever">
<item name="datStyle" format="reference" />
</declare-styleable>
<style name="Theme.BreakMe.Take2">
<item name="datStyle">?android:attr/actionBarSize</item>
</style>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Break Me"
style="?attr/datStyle"
/>
and
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.actionBarStyle, outValue, true);
and
int[] Theme = new int[] { android.R.attr.actionBarSize };
int Theme_actionBarSize = 0;
TypedArray a = context.obtainStyledAttributes(attrs, Theme);
int ref = a.getResourceId(Theme_actionBarSize, 0);
and
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar, android.R.attr.actionBarStyle, 0);
All of them result in this error in LogCat:
E/ResourceType(5618): Style contains key with bad entry: 0x010102ce
The 0x010102ce constant is the attribute value of android.R.attr.actionBarStyle which seems to indicate the platform is rejecting the attribute before I can even get a chance to access its value.
I am looking for any other way to read attributes like this from the Theme. I'm fairly sure that once I've obtained the style reference I won't have trouble reading its attributes.
Is there any possible way to do this?
I am operating under the presumption that when Android styles are compiled the attribute constants are what is used for the keys and therefore should theoretically be able to be read on any platform somehow.
Possibly, though that is not how I am interpreting the C++ source code that raises the error you are seeing. Check out ResTable::Theme::applyStyle() in frameworks/base/libs/utils/ResourceTypes.cpp.
My interpretation is that Android has what amounts to an in-memory table of packages->types->possible entries:
numEntries = curPI->types[t].numEntries;
Your entry index is higher than the highest known entry:
if (e >= numEntries) {
LOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
bag++;
continue;
}
It is possible that they handle this different for android versus other packages -- android uses known values at firmware build time (and your generated entry index is higher, because it is from a newer platform), non-android ones assume anything's valid.
If my guesswork is correct, what you want to do will not work. That being said, my C++ days are seriously in my rear-view mirror, so I may be misinterpreting what I'm seeing.
Perhaps I'm missing the end goal here, but I put together the following example that was able to read out all the attributes without issue on any 2.x device. The example was compiled against a 3.0 targetSdk.
styles.xml (Declare the styles and themes)
<resources>
<style name="Theme.NewFeatures" parent="android:Theme">
<item name="android:actionBarStyle">#style/Widget.MyActionBar</item>
</style>
<style name="Widget.MyActionBar" parent="android:Widget">
<item name="android:padding">20dp</item>
</style>
</resources>
attrs.xml (Declare the attribute groups you wish to obtain at runtime)
<resources>
<declare-styleable name="ActionBarNewFeatures">
<attr name="android:actionBarStyle" />
</declare-styleable>
<declare-styleable name="MyWidgetNewFeatures">
<attr name="android:padding" />
</declare-styleable>
</resources>
AndroidManifest.xml (Apply the custom theme)
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.NewFeatures" >
<activity
android:name=".SomeActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
SomeActivity.java (Go digging for attributes)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypedArray a = obtainStyledAttributes(R.styleable.ActionBarNewFeatures);
//Get the style ID for the widget
int resid = a.getResourceId(R.styleable.ActionBarNewFeatures_android_actionBarStyle, -1);
a.recycle();
a = obtainStyledAttributes(resid, R.styleable.MyWidgetNewFeatures);
int padding = a.getDimensionPixelSize(R.styleable.MyWidgetNewFeatures_android_padding, -1);
a.recycle();
TextView tv = new TextView(this);
tv.setText(String.format("Padding will be %d px", padding));
setContentView(tv);
}
As long as I compile the example against 3.0 so it can resolved all the attribute names; on every 2.X device/emulator I have this will correctly read into the theme and then into the widget style to get the scaled padding dimension I had set.
Hope I didn't miss something big.
Probably, You must define a few themes. For old devices use folder res/values-v11/themes.xml. See section "Using Holo while supporting Android 2.x" in the http://android-developers.blogspot.com/2012/01/holo-everywhere.html

Categories

Resources