I have an android application where I make use of a custom font, let's call it my_font.ttf which I have saved in my font folder in the res package.
I also have a custom number picker where I need to set the font for the values in the picker. This is my attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="NumPicker">
<attr name="max" format="integer" />
<attr name="min" format="integer" />
<attr name="selectedTextColor" format="color" />
<attr name="selectedTextSize" format="float" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
<attr name="typeface" format="enum">
<enum name="font" value="0"/>
<enum name="sans" value="1"/>
<enum name="serif" value="2"/>
<enum name="monospace" value="3"/>
</attr>
</declare-styleable>
</resources>
I want to know how I can add my_font.ttf into this attrs.xml so that I can use it in my layout file to set the font. Like those serif, sans, monospace ones work as they are built in fonts, but I am not sure how to use my font.
Here is my layout file which makes use of the custom NumPicker:
<com.myproject.slidertest.selectors.numberpicker.NumPicker
android:id="#+id/numberPicker"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:paddingLeft="40dp"
android:paddingRight="40dp"
android:layout_gravity="center_horizontal"
app:typeface="serif"<!-- I want to be able to change this font to my font-->
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:selectedTextColor="#color/color_blue"
app:textColor="#color/colorTextDefault"
app:max="50"
app:min="10"
/>
Any help or advice will be highly appreciated.
Add another attr
<attr fontTextAppearance format="reference">
In the custom view, if the typeface type is font, look for the typefaceFont reference.
val textAppearance = ta.getResourceId(R.styleable.NumPicker_fontTextAppearance, -1)
if (textAppearance != -1) {
textView.setTextAppearance(textAppearance)
}
<com.myproject.slidertest.selectors.numberpicker.NumPicker
android:id="#+id/numPicker"
style="#style/NumPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:fontTextAppearance="#style/NumPickerFont"
/>
<style name="NumPickerFont">
<item name="android:textColor">#color/white</item>
<item name="android:textSize">40sp</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:letterSpacing">0.18</item>
<item name="android:fontFamily">#font/some_font</item>
</style>
Related
I have a custom view with 4 rectangles in it. I want to make this view configurable from xml.
Is it possible to make it like:
custom:rectColor="red|cyan|blue|green" //each color correspond rectangle
with
<attr name="rectColor" format="color">
<flag name="red" value="2" />
<flag name="cyan" value="5" />
<flag name="blue" value="7" />
<flag name="green" value="9" />
</attr>
Or it must be:
<attr name="firstRectColor" format="color" />
<attr name="secondRectColor" format="color" />
<attr name="thirdRectColor" format="color" />
<attr name="fourthRectColor" format="color" />
and each view should contains:
custom:firstRectColor="red"
custom:secondRectColor="red"
custom:thirdRectColor="red"
custom:fourthRectColor="red"
And if it possible. How can I get set of color values from attributes.
Thanks
Read this documentation.. it shows you how to declare custom attributes and access them in your layout file..
http://developer.android.com/training/custom-views/create-view.html
i added a project library to my project, it has some custom attributes defined in its attrs.xml how can i use these attributes ?
Library code:
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="NumberProgressBar">
<attr name="progress" format="integer"/>
<attr name="max" format="integer"/>
<attr name="progress_unreached_color" format="color"/>
<attr name="progress_reached_color" format="color"/>
<attr name="progress_reached_bar_height" format="dimension"/>
<attr name="progress_unreached_bar_height" format="dimension"/>
<attr name="progress_text_size" format="dimension"/>
<attr name="progress_text_color" format="color"/>
<attr name="progress_text_offset" format="dimension"/>
<attr name="progress_text_visibility" format="enum">
<enum name="visible" value="0"/>
<enum name="invisible" value="1"/>
</attr>
</declare-styleable>
<declare-styleable name="Themes">
<attr name="numberProgressBarStyle" format="reference"/>
</declare-styleable>
</resources>
My xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:widget="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/lessens_listview_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:drawableLeft="#drawable/bbb"
android:drawablePadding="5dp"
android:text="TextView"
android:textColor="#000000"
android:textSize="26dp" />
<com.daimajia.numberprogressbar.NumberProgressBar
android:id="#+id/number_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/lessens_listview_textview"
android:layout_marginLeft="12dp"
custom:progress_reached_bar_height="5dp"/>
</RelativeLayout>
here i get error in custom:progress_reached_bar_height="5dp"
as the library's Readme says i can use attributes like this but i cant.
library Readme:
<com.daimajia.numberprogressbar.NumberProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:progress_unreached_color="#CCCCCC"
custom:progress_reached_color="#3498DB"
custom:progress_unreached_bar_height="0.75dp"
custom:progress_reached_bar_height="1.5dp"
custom:progress_text_size="10sp"
custom:progress_text_color="#3498DB"
custom:progress_text_offset="1dp"
custom:progress_text_visibility="visible"
custom:max="100"
custom:progress="80"
/>
Depends how you declare the namespace.
In your case you have declared:
xmlns:widget="http://schemas.android.com/apk/res-auto"
that means you can call the attributes using widget as prefix:
widget:progress_reached_bar_height="5dp"
If you want to use the custom prefix change the declaration in this way:
xmlns:custom="http://schemas.android.com/apk/res-auto"
I have the following situation:
in styles.xml:
<style name="fooStyle">
<item name="android:padding">?fooView.padding</item>
<item name="android:background">?fooView.background</item>
<item name="android:gravity">?fooView.gravity</item>
</style>
in attrs.xml:
<attr name="fooView.padding" format="dimension" />
<attr name="fooView.background" format="color|reference" />
<attr name="fooView.gravity" format="????"/>
in themes.xml:
<style name="fooViewTheme" parent="android:Theme">
<item name="fooView.padding" >2dip</item>
<item name="fooView.background" >#AA000000</item>
<item name="fooView.gravity">right|bottom</item>
</style>
The problem is that I cannot figure out what the format for the fooView.gravity should be. I've already tried with string, enum and flag but none seem to work: I always get a java.lang.NumberFormatException: unable to parse 'right|bottom' as integer as soon as the view that uses this theme gets loaded.
All answers are appreciated.
Those are the gravity values used by Android. You can use that in your attrs.xml:
<resources>
<declare-styleable name="MyCustomView">
<attr name="gravity">
<flag name="bottom" value="80" />
<flag name="center" value="17" />
<flag name="center_horizontal" value="1" />
<flag name="center_vertical" value="16" />
<flag name="clip_horizontal" value="8" />
<flag name="clip_vertical" value="128" />
<flag name="end" value="8388613" />
<flag name="fill" value="119" />
<flag name="fill_horizontal" value="7" />
<flag name="fill_vertical" value="112" />
<flag name="left" value="3" />
<flag name="right" value="5" />
<flag name="start" value="8388611" />
<flag name="top" value="48" />
</attr>
</declare-styleable>
</resources>
In your layout XML you can use it this way:
<MyCustomView
custom:gravity="center|bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
And in Java code you can read the value using this:
int gravity = a.getInt(R.styleable.MyCustomView_gravity, Gravity.NO_GRAVITY);
and directly set it to a sub view, if that makes sense for you:
someSubView.setGravity(gravity);
You can look up those gravity values in the source of android.view.Gravity or here
It's a flag attribute. You need to define it in your attributes xml like this:
<attr name="gravity">
<flag name="right" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<!-- etc. -->
</attr>
...and then access the values using bit masks, like this:
boolean right = (array.getInt(R.styleable.fooView_gravity, 0) & 0x01) == 0x01;
boolean bottom = (array.getInt(R.styleable.fooView_gravity, 0) & 0x02) == 0x02;
boolean left = (array.getInt(R.styleable.fooView_gravity, 0) & 0x04) == 0x04;
// etc.
...and of course, these values can be used from XML as well:
<style name="fooViewTheme" parent="android:Theme">
<item name="fooView.gravity">right|bottom</item>
</style>
As you only need a small selection of attributes, I'd suggest using the type "enum".
http://developer.android.com/training/custom-views/create-view.html
<attr name="labelPosition" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="1"/>
</attr>
Referencing:
custom:labelPosition="left"
In Code:
mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
Seems to be integer? Doc.
Would make sense since it can be 'ored'
Edit: sorry, probably misread the problem... It's clearly saying in the error that it's int, but bottom can't be converted to int :/
Edit2: Here are the int values if you need to work-around. Sorry for no real solution.
I'm writing a few custom views which share some same-named attributes. In their respective <declare-styleable> section in attrs.xml I'd like to use the same names for attributes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView1">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
</resources>
I'm getting an error saying that myattr1 and myattr2 are already defined. I found that I should omit the format attribute for myattr1 and myattr2 in MyView2, but if I do that, I obtain the following error in the console:
[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute
Is there a way I could accomplish this, maybe some sort of namespacing (just guessing)?
Solution: Simply extract common attributes from both views and add them directly as children of the <resources> node:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<declare-styleable name="MyView1">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
</resources>
I am posting this answer as the above-posted solution didn't work out for me in Android Studio. I need to share my custom attributes among my custom views so I tried the above solution in Android Studio but had no luck. So I experiment and go a way to do it. Hope it might help someone looking for the same problem.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- parent styleable -->
<declare-styleable name="MyView">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
</resources>
This works for me completely.
We need to make a Parent styleable and then we need to inherit that parent styleable. For example, as I have done above :
Parent styleable name MyView and inherited this to my other styleable like MyView1 and MyView2 respectively.
As Priya Singhal answered, Android Studio requires the common attribute names to be defined within their own style name. They can't be at the root any more.
However, there are a couple other things to note (which is why I am also adding an answer):
The common styles don't need to be named the same thing as a view. (Thanks to this answer for pointing that out.)
You don't need to use inheritance with a parent.
Example
Here is what I did in a recent project that has two custom views that both share the same attributes. As long as the custom views still have the names for the attributes and don't include a format, I can still access them as normal from code.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes to all custom text based views -->
<declare-styleable name="TextAttributes">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<!-- custom text views -->
<declare-styleable name="View1">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
Streamlined example
In fact, I don't even need to put the attributes under a custom name. As long as I define them (give them a format) for at least one custom view, I can use them anywhere (without the format). So this also works (and looks cleaner):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="View1">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
For a large project, though, this could get messy and defining them at the top in a single location might be better (as recommended here).
Thanks Lewis
I had the same problem , and your inheritance solution gave me the hint for doing it like below and it works fine.I just declared common attributes at the above and rewrite it in the body of style declaration again without formatting.
I hope it helps someone
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
Just in case someone still stuck with this problem after tried available solution. I stuck with add subtitle attribute with string format.
My solution is remove the format.
before:
<attr name="subtitle" format="string"/>
after:
<attr name="subtitle"/>
I'm trying to create custom attributes to my button but I dont know which format I must use to images in attributes declaration...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TCButton">
<attr name="Text" format="string"/>
<attr name="BackgroundImage" format="android:drawable" />
</declare-styleable>
</resources>
Error is in the format="android:drawable"...
You can use format="integer", the resource id of the drawable, and AttributeSet.getDrawable(...).
Here is an example.
Declare the attribute as integer in res/values/attrs.xml:
<resources>
<declare-styleable name="MyLayout">
<attr name="icon" format="integer" />
</declare-styleable>
</resources>
Set the attribute to a drawable id in your layout:
<se.jog.MyLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
myapp:icon="#drawable/myImage"
/>
Get the drawable from the attribute in your custom widget component class:
ImageView myIcon;
//...
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyLayout);
Drawable drawable = a.getDrawable(R.styleable.MyLayout_icon);
if (drawable != null)
myIcon.setBackgroundDrawable(drawable);
To see all options possible check the android src here
I think it will be better to use it as a simple reference:
<declare-styleable name="TCButton">
<attr name="customText" format="string"/>
<attr name="backgroundImage" format="reference" />
</declare-styleable>
And set it in your xml like this:
<your.package.name.TCButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:customText="Some custom text"
custom:backgroundImage="#drawable/myImage"
/>
And in your class set the attributes like this:
public TCButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MembershipItemView, 0, 0);
String customText;
Drawable backgroundImage;
try {
customText = a.getString(R.styleable.TCButton_customText);
backgroundImage = a.getDrawable(R.styleable.TCButton_backgroundImage);
} finally {
a.recycle();
}
if(!TextUtils.isEmpty(customText)) {
((TextView)findViewById(R.id.yourTextView)).setText(customText);
}
if(null != backgroundImage) {
((ImageView)findViewById(R.id.yourImageView)).setBackgroundDrawable(backgroundImage);
}
}
PS:
Don't forget to add this line for the root element of the layout you are using your custom view in
xmlns:custom="http://schemas.android.com/apk/res-auto"
If you don't set this, you won't be able to access your custom attributes.
From AOSP code, I found how google engineers declare ImageView#src attr.
<declare-styleable name="ImageView">
<attr name="src" format="reference|color" />
<attr name="scaleType">
<enum name="matrix" value="0" />
<enum name="fitXY" value="1" />
<enum name="fitStart" value="2" />
<enum name="fitCenter" value="3" />
<enum name="fitEnd" value="4" />
<enum name="center" value="5" />
<enum name="centerCrop" value="6" />
<enum name="centerInside" value="7" />
</attr>
<attr name="adjustViewBounds" format="boolean" />
<attr name="maxWidth" format="dimension" />
<attr name="maxHeight" format="dimension" />
<attr name="tint" format="color" />
<attr name="baselineAlignBottom" format="boolean" />
<attr name="cropToPadding" format="boolean" />
<attr name="baseline" format="dimension" />
<attr name="drawableAlpha" format="integer" />
<attr name="tintMode" />
</declare-styleable>
Above code is a sample and it can cover most case in our development.