I'm trying to put the custom XML namespace in the styles.xml and inherit it in the layout. I don't know how to declare the custom XML namespace in the styles.xml as I do in layout xml (e.g. xmlns:app="http://schemas.android.com/tools").
How do I use custom XML namespace in the styles.xml?
What I have:
The font asset, ReallyCoolFont.ttf is saved in the asset/fonts.
my_layout.xml:
<TextView
<!-- more attributes here -->
app:customFont="fonts/ReallyCoolFont.ttf"
<!-- more attributes here -->
</TextView>
styles.xml:
<style name="CoolTextView">
<!-- more items here -->
<!-- more items here -->
</style>
What I'd like to have:
my_layout.xml:
<TextView
<!-- more attributes here -->
style="#style/CoolTextView
<!-- more attributes here -->
</TextView>
styles.xml:
<style name="CoolTextView">
<!-- more items here -->
<item name="app:customFont">ReallyCoolFont.ttf</item>
<!-- more items here -->
</style>
Error I get:
Error:(1403, 21) No resource found that matches the given name: attr 'app:customFont'.
You need to define an attribute for your fonts in attr.xml file in res folder:
<attr name="myfonts" format="string" />
And you need to define custom style for your TextView and here we use our defined attribute(myfonts):
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
Then styles can be declared:
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
summary of what you have so far:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myfonts" format="string">
</attr>
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
</resources>
4)Now your layout would be:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.MyCustomTextView
android:id="#+id/result"
style="#style/CoolTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HELLO WORLD!"
android:textSize="24dp"
android:gravity="center" >
</com.example.MyCustomTextView>
</RelativeLayout>
5)and your MyCustomTextView is:
public class MyCustomTextView extends TextView {
private static final String TAG = "TextView";
public MyCustomTextView(Context context) {
super(context);
}
public MyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
settingFont(context, attrs);
}
public MyCustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
settingFont(context, attrs);
}
private void settingFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.MyCustomStyle);
String customFont = a.getString(R.styleable.MyCustomStyle_myfonts);
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), customFont);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
a.recycle();
return;
}
setTypeface(tf);
a.recycle();
}
}
I assumed you put the font in asset not in asset/fonts directory.
also I highly recommend read this.
You don't need to add any prefix to reference your custom attributes in the style resource files. Doing it like this will work just fine:
<style name="CoolTextView">
<item name="customFont">ReallyCoolFont.ttf</item>
</style>
The answer is to NOT specify the namespace in the style.
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:custom="http://schemas.android.com/apk/res/com.custom.project">
<style name="CustomStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="customAttr">value</item> <!-- tee hee -->
</style>
</resources>
You don't need any prefixes, it will work without them. This is code from one of my projects, which works just fine
<style name="defaultTriangle">
<item name="triangleColor">#FF33B5E5</item>
<item name="triangleStrokeColor">#android:color/black</item>
<item name="triangleStrokeWidth">3dp</item>
</style>
<si.kseneman.views.Triangle
style="#style/defaultTriangle"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:padding="10dp"
android:rotation="0"
/>
I've done next for custom font
CustomTextView
public class KlavikaTextView extends TextView {
private final static int KLAVIKA_BOLD = 0;
private final static int KLAVIKA_BOLD_ITALIC = 1;
private final static int KLAVIKA_LIGHT = 2;
private final static int KLAVIKA_LIGHT_ITALIC = 3;
private final static int KLAVIKA_MEDIUM = 4;
private final static int KLAVIKA_MEDIUM_ITALIC = 5;
private final static int KLAVIKA_REGULAR = 6;
private final static int KLAVIKA_REGULAR_ITALIC = 7;
public KlavikaTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context) {
super(context);
}
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.KlavikaTextView);
// The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.KlavikaTextView_typeface, KLAVIKA_REGULAR);
// You can instantiate your typeface anywhere, I would suggest as a
// singleton somewhere to avoid unnecessary copies
switch (typeface) {
case KLAVIKA_BOLD:
setTypeface(App.klavikaBold);
break;
case KLAVIKA_BOLD_ITALIC:
setTypeface(App.klavikaBoldItalic);
break;
case KLAVIKA_LIGHT:
setTypeface(App.klavikaLight);
break;
case KLAVIKA_LIGHT_ITALIC:
setTypeface(App.klavikaLightItalic);
break;
case KLAVIKA_MEDIUM:
setTypeface(App.klavikaMedium);
break;
case KLAVIKA_MEDIUM_ITALIC:
setTypeface(App.klavikaMediumItalic);
break;
case KLAVIKA_REGULAR_ITALIC:
setTypeface(App.klavikaRegularItalic);
break;
case KLAVIKA_REGULAR:
default:
setTypeface(App.klavikaRegular);
break;
}
}}
Then in values I've created attr.xml
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="klavika_bold" value="0" />
<enum name="klavika_bold_italic" value="1" />
<enum name="klavika_light" value="2" />
<enum name="klavika_light_italic" value="3" />
<enum name="klavika_medium" value="4" />
<enum name="klavika_medium_italic" value="5" />
<enum name="klavika_regular" value="6" />
<enum name="klavika_regular_italic" value="7" />
</attr>
<!--
Tell Android that the class "KlavikaTextView" can be styled,
and which attributes it supports-->
<declare-styleable name="KlavikaTextView">
<attr name="typeface" />
</declare-styleable>
Next created the style
<style name="TextView.Example">
<item name="typeface">klavika_bold</item>
</style>
This style you can use for your xml Layouts
style="#style/TextView.Example"
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.my.project">
<style name="my_style"> <item name="custom:tag">some_value</item> </style>
</resources>
you are trying to apply XML namespacing to an attribute value, which won't work. In this case, you should specify the package name directly, like this:
<style name="my_style"> <item name="com.my.project:tag">some_value</item> </style>
Fast solution via code!
String pathFont = "fonts/ReallyCoolFont.ttf";
TextView text = (TextView) findViewById(R.id.TextView1);
Typeface fontFace = Typeface.createFromAsset( getAssets(), pathFont );
text.setTypeface( fontFace );
Third-party libraries , solve the problem, in XML!
1 - https://github.com/leok7v/android-textview-custom-fonts
2 - https://github.com/ragunathjawahar/android-typeface-textview
My suggestion
You will have other needs, and for each component
you will have to customize a class.
Another problem you have other layouts and N TextView components
for maintenance you will have a lot of work .
I use this method in projects in the OnCreate of my activity
if I need to change the font I have to do this
only in the OnCreate method of each activity .
private static final String FONT = "ReallyCoolFont.ttf";
public static void allTextView(final Context context, final View root) {
String fontPath = FONT;
try {
if (root instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) root;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++)
allTextView(context, viewGroup.getChildAt(i) );
} else if (root instanceof TextView)
((TextView) root).setTypeface(Typeface.createFromAsset(context.getAssets(), fontPath));
} catch (Exception e) {
e.printStackTrace();
}
}
// call in OnCreate Activity
allTextView(this, findViewById(R.layout.main) );
The custom attributes are defined using <declare-styleable> tags; usually the file is called attrs.xml. The namespace declaration will have your app's package name in it.
The whole process is described here: Creating a View Class | Android Developers
Related
I have an android application with english and arabic as choosable langagues.
My problem is that I need to use a specific font for each langague.
What is the proper way to implement this ?
My idea was to create two different themes in styles.xml, like this :
<resources>
<!-- English application theme. -->
<style name="EnglishTheme" parent="Theme.AppCompat.Light.NoActionBar">
... all my others attributes ...
<item name="pathBoldFont">fonts/FontEnglish-Bold.ttf</item>
<item name="pathRegularFont">fonts/FontEnglish-Regular.ttf</item>
<item name="pathThinFont">fonts/FontEnglish-Thin.ttf</item>
</style>
<!-- Arabic application theme. -->
<style name="ArabicTheme" parent="Theme.AppCompat.Light.NoActionBar">
... all my others attributes ...
<item name="pathBoldFont">fonts/FontArabic-Bold.ttf</item>
<item name="pathRegularFont">fonts/FontArabic-Regular.ttf</item>
<item name="pathThinFont">fonts/FontArabic-Thin.ttf</item>
</style>
</resources>
At application runtime, I check user's locale and load the correct theme. But obviously, this is not very DRY, because I have to write twice every other attributes of the theme.
I've read that this is not possible to update programmatically theme attributes (just fonts in my case) so what could be a better solution ?
FYI I use InflationX/Calligraphy for my custom fonts.
just create a custom TextView Class where u set your fonts and in there whenever you get a font u check for the language selected
public class CustomTextView extends android.support.v7.widget.AppCompatTextView {
public CustomTextView (Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomTextView,
0, 0);
try {
int custom_font = a.getInt(R.styleable.CustomTextView_custom_font, 0);
switch (custom_font) {
//Regular
case 0:
if(language == "english")
setTypeface(/*return Typeface Regular for english*/);
else setTypeface(/*return Typeface Regular for arabic*/);
break;
//Bold
case 1:
if(language == "english")
setTypeface(/*return Typeface Boldfor english*/);
else setTypeface(/*return Typeface Boldfor arabic*/);
break;
}
} finally {
a.recycle();
}
}
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
and in your attr.xml
<declare-styleable name="CustomTextView">
<attr name="custom_font" format="string">
<enum name="regular" value="0" />
<enum name="bold" value="1" />
</attr>
</declare-styleable>
Use it like this
<CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:custom_font="bold"/>
When I changed my minSdkVersion then I am getting this error:
android.view.InflateException: Binary XML file line #43: Error inflating class TextView
Eariler it was working fine before I have made the changes.
Here is my style :
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/white</item>
<item name="colorControlNormal">#color/greyDark</item>
<item name="colorControlActivated">#color/off_white</item>
<item name="android:windowBackground">#color/pink</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">normal</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowAllowEnterTransitionOverlap" tools:targetApi="lollipop">true</item>
<item name="android:windowAllowReturnTransitionOverlap" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:targetApi="lollipop">#android:transition/move</item>
<item name="android:windowSharedElementExitTransition" tools:targetApi="lollipop">#android:transition/move</item>
</style>
<style name="AlertDialogCustom" parent="#android:style/Theme.Dialog">
<item name="android:textColor">#color/pink</item>
<item name="android:typeface">normal</item>
<item name="android:height">5dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#color/white</item>
</style>
I guess there is something wrong with the parent property of a style.
If you are changing your version then also change the support library.You have to change the support lib like for e.g.for api 23 you have to chnage the appcompact library version to 23.
Hope this help.:)
You should try changing
<style name="AlertDialogCustom" parent="#android:style/Theme.Dialog">
to
<style name="AlertDialogCustom" parent="Theme.AppCompat.Dialog">
This is the issue with your font family which you are using in style. May be sans-serif-light font is not available in your assests>>fonts folder. So check with this how to use custom fonts in android.
Here are the steps to follow:
Android Studio:
Step1: Adding font family files to app
A) Go to the (project folder)
B) Then app>src>main
C) Create folder 'assets>fonts' into the main folder.
D) Put your 'abc.ttf' or 'abc.otf' font file into the fonts folder.
Step 2:
Now Create attrs.xml under res folder if it's not exists and add declare-styleable
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Font">
<attr name="typeface">
<enum name="FuturaLT" value="0" />
<enum name="FuturaLT_Heavy" value="1" />
<enum name="FuturaLT_Light" value="2" />
</attr>
</declare-styleable>
</resources>
//Here FuturaLT/FuturaLT_Heavy/FuturaLT_Light are file names
Note: – enum name should be font type name with underscore(_) uses, it will be easy for you to understand font family usage in your native code. No special character or other letter, otherwise you will got error in gen folder for same attribute id.
Step 3: Create your custom view(Button, TextView, EditText) class:-
package com.myapp.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.TextView;
import com.myapp.R;
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
try {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Font);
int font = a.getInt(R.styleable.Font_typeface, 0);
a.recycle();
String str;
switch (font) {
case 1:
str = "fonts/FuturaLT.otf";
break;
case 2:
str = "fonts/FuturaLT_Heavy.otf";
break;
case 3:
str = "fonts/FuturaLT_Light.otf";
break;
default:
str = "fonts/FuturaLT.otf";
break;
}
setTypeface(FontManager.getInstance(getContext()).loadFont(str));
} catch (Exception e) {
e.printStackTrace();
}
}
#SuppressWarnings("unused")
private void internalInit(Context context, AttributeSet attrs) {
}
}
Step 4: Add FontManager.java support class
package com.myapp.views;
import android.content.Context;
import android.graphics.Typeface;
import java.util.HashMap;
import java.util.Map;
public class FontManager {
private Map<String, Typeface> fontCache = new HashMap<String, Typeface>();
private static FontManager instance = null;
private Context mContext;
private FontManager(Context mContext2) {
mContext = mContext2;
}
public synchronized static FontManager getInstance(Context mContext) {
if (instance == null) {
instance = new FontManager(mContext);
}
return instance;
}
public Typeface loadFont(String font) {
if (false == fontCache.containsKey(font)) {
fontCache.put(font, Typeface.createFromAsset(mContext.getAssets(), font));
}
return fontCache.get(font);
}
}
Step 5: Usage in XML layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.myapp.views.CustomTextView
android:id="#+id/tv_time_slot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:typeface="FuturaLT" />
</LinearLayout>
You can also use in java code directly:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/FuturaLT.ttf");
tvText.setTypeface(tf);
Note:- If you don't use here FontManager to apply typeface and directly use
then you are not able to see your views in graphics preview.
I'm working on an OpenSource lib as an alternative for the built-in android PopupMenu, in my lib I'd like to make everything customizable such that if you want to use it and change the popup colors/dimensions it becomes easy.
The full source code is here:
https://github.com/shehabic/Droppy/tree/styleable_ui
I'm few issues .. briefly I learned that to make your widget/custom view styleable you have to define 1-Custom View, 2-Styleable attributes, 3-Default values for such styleable attributes.
so I have the following xml files:
res/droppy__attr.xml
<resources>
<declare-styleable name="Droppy">
<attr name="droppyMenuItemTitleStyle" format="reference"/>
</declare-styleable>
<declare-styleable name="DroppyMenuItemTitle">
<attr name="android:textColor"/>
<attr name="android:minWidth"/>
<attr name="android:minHeight"/>
<attr name="android:layout_height"/>
<attr name="android:layout_width"/>
<attr name="android:layout_gravity"/>
<attr name="android:gravity"/>
<attr name="android:layout_weight"/>
</declare-styleable>
</resource>
res/droppy__styles.xml
<resources>
<style name="Theme.DroppyDefaults" parent="android:Theme">
<item name="droppyMenuItemTitleStyle">#style/Droppy.DroppyMenuItemTitle</item>
</style>
<style name="Droppy">
</style>
<style name="Droppy.DroppyMenuItemTitle">
<item name="android:textColor">#color/darkgrey</item>
<item name="android:minWidth">128dp</item>
<item name="android:minHeight">30dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_gravity">end|center_vertical</item>
<item name="android:gravity">center_vertical</item>
<item name="android:layout_weight">1</item>
</style>
</resource>
res/droppy__defaults.xml
<resources>
<!-- Menu Item Title -->
<color name="default_menu_item_title_textColor">#color/darkgrey</color>
<dimen name="default_menu_item_title_minWidth">128dp</dimen>
<dimen name="default_menu_item_title_minHeight">30dp</dimen>
<dimen name="default_menu_item_title_layout_width">0dp</dimen>
<!-- There's no easy way to set default values for the following -->
<!--<float name="default_menu_item_title_layout_weight">1</float>-->
<!--<item name="default_menu_item_title_layout_gravity">end|center_vertical</item>-->
<!--<item name="default_menu_item_title_gravity">center_vertical</item>-->
</resources>
In the block above here's the 1st issue,
Now here's the code I use in my custom view:
DroppyMenuItem.java
public class DroppyMenuItemTitle extends TextView {
public DroppyMenuItemTitle(Context context) {
this(context, null);
}
public DroppyMenuItemTitle(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.droppyMenuItemTitleStyle);
}
public DroppyMenuItemTitle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final int defaultWidth = ViewGroup.LayoutParams.MATCH_PARENT;
final float defaultWeight = 1;
final int defaultGravity = Gravity.CENTER_VERTICAL;
final int defaultLayoutGravity = Gravity.END | Gravity.CENTER_VERTICAL;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DroppyMenuItemTitle, defStyleAttr, 0);
int width = (int) a.getDimension(R.styleable.DroppyMenuItemTitle_android_layout_width, defaultWidth);
int height = a.getInt(R.styleable.DroppyMenuItemTitle_android_layout_height, ViewGroup.LayoutParams.WRAP_CONTENT);
setGravity(a.getInt(R.styleable.DroppyMenuItemTitle_android_gravity, defaultGravity));
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width, height);
lp.width = width;
lp.height = height;
lp.weight = a.getFloat(R.styleable.DroppyMenuItemTitle_android_layout_weight, defaultWeight);
lp.gravity = a.getInteger(R.styleable.DroppyMenuItemTitle_android_layout_gravity, defaultLayoutGravity);
setLayoutParams(lp);
}
As per the following line:
int width = (int) a.getDimension(R.styleable.DroppyMenuItemTitle_android_layout_width, defaultWidth);
if I use that customView and specify width as wrap_content or match_parent, it works fine as these are translated to -1 and -2.
But if specify it as XXdp (e.g. 20dp) it fails as the number now is actually a float not int
the error I get is as follows:
E/AndroidRuntime(2940): java.lang.NumberFormatException: Invalid int: "20.0dip"
The problem I am trying to solve is to have a custom font in an android application. I have followed a few tutorials and stack overflow questions but I can't seem to get exactly what I want.
I have a custom attribute defined in attrs.xml:
<resources>
<declare-styleable name="CustomTextView">
<attr name="customTypeface" format="string"/>
</declare-styleable>
and that customTypeface defined in the style:
<style name="posTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:textViewStyle">#style/posThemeTextViewStyle</item>
</style>
<style name="posThemeTextViewStyle" parent="android:Widget.TextView">
<item name="android:textSize">50sp</item>
<item name="customTypeface">Fonts/MuseoSans_100.otf</item>
</style>
in an activity the form looks looks like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="LOL OL U MAD BRO!"
/>
<myApplication.Controls.CustomTextView
android:id="#+id/tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="LOL OL U MAD BRO!"
></myApplication.Controls.iQTextView>
</LinearLayout>
and when I go about trying to get the attribute:
public CustomTextView(Context context, IAttributeSet attrs, int defStyle)
: base(context, attrs, defStyle)
{
var a = context.ObtainStyledAttributes(attrs,
Resource.Styleable.CustomTextView);
var customFont = a.GetString(Resource.Styleable.CustomTextView_customTypeface);
SetCustomFont(customFont);
a.Recycle();
}
customFont is null, unless I implicitly define custom:customTypeface="" in the activity but I don't want to have to define the font for every single instance of the control.
What am I missing?
Shouldn't those two lines :
var a = context.ObtainStyledAttributes(attrs,
Resource.Styleable.CustomTextView);
var customFont = a.GetString(Resource.Styleable.CustomTextView_customTypeface);
be :
var a = context.ObtainStyledAttributes(attrs,
R.Styleable.CustomTextView);
var customFont = a.GetString(R.Styleable.CustomTextView_customTypeface);
I have a custom control which extends the DialogPreference where I have custom attributes and I want to define default values for them.
Here is the relevent part of my attrs.xml:
<!-- definition of my custom attributes -->
<declare-styleable name="MyPreference">
<attr name="myAttr1" format="string" />
<attr name="myAttr2" format="reference" />
</declare-styleable>
<!-- declatation of my style for my AppTheme -->
<declare-styleable name="AppTheme">
<attr name="myPreferenceStyle" format="reference" />
</declare-styleable>
themes.xml:
<style name="AppTheme" parent="#style/Theme.Sherlock.Light.DarkActionBar">
<!-- try of replacing the default text color -->
<item name="android:textAppearance">#style/WhiteText</item>
<item name="myPreferenceStyle">#style/Preference.My</item>
</style>
styles.xml:
<style name="WhiteText" parent="#android:style/TextAppearance">
<!-- set the default color to white... however it doesn't work -->
<item name="android:textColor">#fff</item>
</style>
<style name="Preference">
<item name="android:positiveButtonText">#android:string/ok</item>
<item name="android:negativeButtonText">#android:string/cancel</item>
</style>
<style name="Preference.My">
<item name="android:dialogLayout">#layout/preferences_my_picker</item>
<item name="myAttr1">#string/unknown</item>
<item name="myAttr2">#array/bits</item>
</style>
So I have defined that I want that the class MyPreference should have the default values like this:
android:positiveButtonText = "OK"
android:negativeButtonText = "Cancel"
android:dialogLayout = <ref to a layout>
myAttr1 = "Unknown"
myAttr2 = [1, 2, 4]
But when I try to access them I get nothing:
public MyPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyPreference, defStyle, 0);
String txt = a.getText(R.styleable.MyPreference_myAttr1);
// txt == null :(
int bitsResId = a.getResourceId(R.styleable.MyPreference_myAttr2, -1);
// next line will crash bitsResId == -1
int[] bits = res.getIntArray(bitsResId);
a.recycle();
}
public MyPreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.myPreferenceStyle);
}
I would be really helpful if somebody could explain me what I do wrong. And also why I cannot change the default text color to white.