I've noticed that the SwitchCompat's font does not seem to change with what I've set in the fontFamily field. I've also tried using styles with custom fontFamily (which works on TextViews) and even the switchTextAppearance field. It does apply on the preview (I know the preview is not really accurate) but not when I tried running it on my test device.
Here's my SwitchCompat:
<android.support.v7.widget.SwitchCompat
style="#style/MyStyle.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/my_font_family"
android:text="Enable"
app:switchTextAppearance="#style/MyStyle.Body"/>
and here's my style:
<style name="MyStyle.Body" parent="Base.TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">#font/my_font_family</item>
<item name="android:textColor">#color/color_primary_text</item>
</style>
As you can see, I only really want to change it's font
EDIT
I've changed my style to this
<style name="MyStyle.Switch" parent="Widget.AppCompat.CompoundButton.Switch">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#color/color_primary_text</item>
<item name="android:fontFamily">#font/my_font_family</item>
<item name="fontFamily">#font/my_font_family</item>
</style>
still doesn't work though
XML settings is not working, therefore I use following code:
someSwitch.setTypeface(ResourcesCompat.getFont(context, R.font.roboto));
Try
parent="Base.TextAppearance.AppCompat.Body1"
replace into this
parent="TextAppearance.AppCompat.Widget.Switch"
Try below
public class CustomSwitchCompact extends SwitchCompat {
public CustomSwitchCompact(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CustomSwitchCompact(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomSwitchCompact(Context context) {
super(context);
init();
}
private void init() {
if (!isInEditMode()) {
Typeface myFonts = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto_Bold.ttf");
setTypeface(myFonts);
}
}
}
XML file
<com.test.CustomSwitchCompact
android:id="#+id/switch_compat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:checked="false"
android:padding="20dp"
android:text="SwitchCompat"
android:textOff="OFF"
android:textOn="ON"
app:showText="true" />
Another way to achieve SwitchCompact with custom font
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/adamSwitch"
android:textColor="#color/top_color"
android:textAppearance="#color/top_color"
android:gravity="center"
app:showText="true"
android:fontFamily="#font/my_font_family"
app:theme="#style/Custom.Widget.SwitchCompat"
app:switchPadding="5dp"
/>
in style.xml
<style name="Custom.Widget.SwitchCompat" parent="Widget.AppCompat.CompoundButton.Switch" >
<item name="android:textColorPrimary">#color/blue</item>
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">#font/my_font_family</item>
<item name="android:textColor">#color/color_primary_text</item>
</style>
The only thing that works for me is setSwitchTypeface, not setTypeface:
my_switch.setSwitchTypeface(ResourcesCompat.getFont(context, R.font.my_font))
I've used android:textAppearance instead of android:switchTextAppearance and custom font works now. Also my switch style have Widget.AppCompat.CompoundButton.Switch as parent
Related
Is there a way to change the theme of a TextInputLayout programmatically in Android.
If I have the following TextInputLayout for ex.:
<android.support.design.widget.TextInputLayout
android:id="#+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="16dp"
android:theme="#style/TextInputLayoutTheme"
app:errorTextAppearance="#style/Error">
<android.support.v7.widget.AppCompatEditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:paddingTop="8dp"/>
</android.support.design.widget.TextInputLayout>
Could I somehow change this line android:theme="#style/TextInputLayoutTheme" to another theme programmatically?
There is no way to change theme of any view or any layout at runtime. Because of themes and styles are applied during creation of view, recursively. (Themes also applies child views of layouts)
But, you can change that theme before creation of view using XML layout or programmatically.
Programmatically:
Method 1 - Create TextInputLayout programmatically with wrapping Context with android.view.ContextThemeWrapper and use.
TextInputLayout layout = new TextInputLayout(new ContextThemeWrapper(getContext(), R.style. TextInputLayoutTheme));
Method 2 - Extend TextInputLayout and use your own layout. Pass ContextThemeWrapper as context.
public class MyTextInputLayout extends TextInputLayout {
public MyTextInputLayout(Context context) {
super(new ContextThemeWrapper(context, R.style.AppTheme));
}
public MyTextInputLayout(Context context, AttributeSet attrs) {
super(new ContextThemeWrapper(context, R.style.AppTheme), attrs);
}
public MyTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(new ContextThemeWrapper(context, R.style.AppTheme), attrs, defStyleAttr);
}
}
Now, you can use MyTextInputLayout in your XML layout
With XML Layout:
1) In attrs.xml file, create new attribute named textInputLayoutTheme
<attr name="textInputLayoutTheme" format="reference"/>
2) In your AppTheme in styles.xml file set your #style/TextInputLayoutTheme as textInputLayoutTheme.
<resources>
<style name="AppTheme" parent="PARENT_THEME">
<item name="textInputLayoutTheme">#style/TextInputLayoutTheme</item>
</style>
<style name="AppTheme.Secondary">
<item name="textInputLayoutTheme">#style/TextInputLayoutTheme_Secondary</item>
</style>
</resources>
3) In your layout.xml file, set ?attr/textInputLayoutTheme as a TextInputLayout theme
<android.support.design.widget.TextInputLayout
android:id="#+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="16dp"
android:theme="#?attr/textInputLayoutTheme"
app:errorTextAppearance="#style/Error">
Now, when you change your application theme from AppTheme to AppTheme.Secondary TextInputLayoutTheme_Secondary will be used as a theme of your TextInputLayout instead of TextInputLayoutTheme.
Unfortunately the accepted answer is not working for me.
My solution was to wrap TextInputLayout in a custom layout.
view_input_layout_wrapper.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/AppThemeMaterial"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/til"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
</FrameLayout>
TextInputLayoutWrapper
class TextInputLayoutWrapper(context: Context) : FrameLayout(context) {
var inputLayout: TextInputLayout
private set
init {
inflate(context, R.layout.view_input_layout_wrapper, this)
inputLayout = findViewById(R.id.til)
}
}
Implementation in the view (fragment/activity):
private fun addNewField(fieldName: String) {
val textInputLayoutWrapper = TextInputLayoutWrapper(
requireContext()
).apply {
inputLayout.hint = fieldName
}
fieldsContainerViewGroup.addView(textInputLayoutWrapper)
}
NOTE: My app theme is not material theme, so I must add theme="#style/AppThemeMaterial" in the root ViewGroup of the TextInputLayout.
<style name="AppThemeMaterial" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowBackground">#android:color/black</item>
</style>
I have an Android application which uses Material design theme with backward compatibility through AppCompat.
There are multiple Textview's and EditText's in my application. I would like the same properties to be applied to all these TextView's and EditText's across the application. In order to achieve this, i have defined a custom style as shown below:
<!-- Base application theme. -->
<style name="ParentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="ArabicTheme" parent="ParentTheme">
<item name="android:editTextStyle">#style/arabicEditText</item>
<item name="android:textViewStyle">#style/arabicTextView</item>
</style>
<style name="arabicEditText" parent="#android:style/Widget.EditText">
<item name="android:gravity">right</item>
<item name="android:ellipsize">end</item>
</style>
<style name="arabicTextView" parent="#android:style/Widget.TextView">
<item name="android:gravity">right</item>
</style>
In my AndroidManifest.xml file under the <Application> tag, i have set android:theme="#style/ArabicTheme".
Below is the output of the activity:
As seen in the above output, the Style is being applied to TextView only. However, The same is not being applied to EditText.
Incase, if i explicitly specify these properties to the EditText in the corresponding Actitivy's xml as shown below:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="Name"
android:ellipsize="end"
android:gravity="right"
android:ems="10"
android:layout_below="#+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="16dp"
android:id="#+id/editText" />
i.e I have explicitly added android:ellipsize="end" and android:gravity="right" to the <EditText>, and only then the output is as expected:
Like i said, i have multiple TextView's and EditText's and i cannot explicitly add these properties to all of them. So, is there a way i can achieve this using Styles or any other approach? Am i doing something wrong here?
Your approach is correct. Just remove android: from the editText's attribute name:
<item name="editTextStyle">#style/arabicEditText</item>
I cannot explain this though. I guess appCompat things don't reuse android attributes, but add another ones with similiar names. Same goes with colorPrimary, srcCompat and others.
I have been doing this
public class LightEditText extends android.widget.EditText{
public LightEditText(Context context) {
super(context);
setFont();
}
public LightEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setFont();
}
public LightEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setFont();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LightEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setFont();
}
/**
* This method is used to set the given font to the TextView.
*/
private void setFont() {
Typeface typeface = TypefaceCache.get(getContext().getAssets(), "fonts/Roboto-Light.ttf");
setTypeface(typeface);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
Then inside your xml file
<com.packagename.LightEditText
android:id="#+id/edtTaskName"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
Do the above method for setting common properties(fontType,style..etc) to editext
I've found an improvement that may help not to hardcode view values into java classes in my android app. I wonder how can i get it to work. I want to to use this kind of view in my adapter (that means that i cannot use #style attribute in my layout's root). What am i doing wrong?
Code:
styles.xml:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="customViewStyleRef">#style/CustomViewStyle</item>
</style>
<attr name="customViewStyleRef" format="reference"/>
<style name="CustomViewStyle" parent="#android:style/Widget.TextView">
<item name="android:layout_margin">10dp</item>
</style>
</resources>
View class:
public class CustomView extends View {
public CustomView(Context context) {
super(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs, R.attr.customViewStyleRef);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, R.attr.customViewStyleRef);
}
public void init(#NonNull ViewGroup parentView) {
inflate(getContext(), R.layout.custom_view, parentView);
}
}
View layout:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f00"
android:textColor="#fff"
android:textSize="50sp"
android:text="test text"/>
</merge>
Problem: The TextView container does not have any padding that i specified in styles.xml (see the image).
You should initialize the TextView, then use the style for the TextView or you can solve this problem by putting style name inside the TextView and use an id for the TextView it will help for using it.
<TextView
android:id="#+id/custom_tv"
style="#style/CustomViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f00"
android:textColor="#fff"
android:textSize="50sp"
android:text="test text"/>
I think i've figured this out. My built files were somehow cached and i couldn't get it to work. And i took a wrong testing parameter. My approach worked 😁
In my Android application I need to apply style for a group of buttons, instead of styling each button individual. Something like this:
<?xml version="1.0" encoding="utf-8"?>
<!-- put here style="#ststyle/Button_Style" -->
<Button android:id="#+id/button1" android:text="#string/b01" />
<Button android:id="#+id/button2" android:text="#string/b02" />
<Button android:id="#+id/button4" android:text="#string/b03" />
<!-- end style -->
You can write the style for button like this ;
style_btn.xml
<style name="style_btn" parent="Wrap">
<item name="android:background">#drawable/btn_bg</item>
<item name="android:gravity">center</item>
<item name="android:textColor">#android:color/white</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_marginTop">4dp</item>
<item name="android:minWidth">90dp</item>
</style>
apply that style to your button :
<Button
android:id="#+id/attach_file"
style="#style/style_btn"
android:layout_centerVertical="true"
android:background="#drawable/orange_bg"
android:drawablePadding="10dp"
android:drawableRight="#drawable/attach"
android:text="#string/str_email_attach" />
If you need the style to all of the buttons in your application, mention in your App theme style, Then no need to apply for every button.
<style name="YourTheme" parent="android:Theme.Light">
<item name="android:buttonStyle">#style/Button</item>
</style>
If you need the style to particluar button , then apply to every button
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/Button"
android:text="Button" />
I know I'm late joining the party but I stumbled across this when trying to figure out the same problem myself.
What I did was:
Depending on how may button groups you have (say 3 for example) you need to subclass button and create three custom button classes (see below)
//Custom button 1
public class CustomButton1 extends Button {
public CustomButton1(Context context, AttributeSet attrs) {
super(context, attrs, R.attr.attrStyle1);
}
public CustomButton1(Context context, AttributeSet attrs, int defStyle) {
super(context, null, R.attr.attrStyle1);
}
}
//Custom button 2
public class CustomButton2 extends Button {
public CustomButton2(Context context, AttributeSet attrs) {
super(context, attrs, R.attr.attrStyle2);
}
public CustomButton2(Context context, AttributeSet attrs, int defStyle) {
super(context, null, R.attr.attrStyle2);
}
}
//Custom button 3
public class CustomButton3 extends Button {
public CustomButton3(Context context, AttributeSet attrs) {
super(context, attrs, R.attr.attrStyle3);
}
public CustomButton3(Context context, AttributeSet attrs, int defStyle) {
super(context, null, R.attr.attrStyle3);
}
}
You can see from the custom classes I have passed a custom attr. These I define in my styles.xml and use them as reference. See my styles.xml below:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
<style name="theme1">
<item name="#attr/attrStyle1">#style/CustomButton1</item>
<item name="#attr/attrStyle2">#style/CustomButton2</item>
<item name="#attr/attrStyle3">#style/CustomButton3</item>
<item name="android:background">#color/warning_yellow_colour</item>
</style>
<style name="CustomButton1" parent = "#android:style/Widget.Button">
<item name="android:textColor">#color/white_colour</item>
<item name="android:padding">20dp</item>
<item name="android:background">#color/banner_background_sensor_colour</item>
</style>
<style name="CustomButton2" parent = "#android:style/Widget.Button">
<item name="android:textColor">#color/white_colour</item>
<item name="android:padding">20dp</item>
<item name="android:background">#color/button_red_colour</item>
</style>
<style name="CustomButton3" parent = "#android:style/Widget.Button">
<item name="android:textColor">#color/white_colour</item>
<item name="android:padding">20dp</item>
<item name="android:background">#color/text_blue_colour</item>
</style>
<attr name="attrStyle1" format="reference"/>
<attr name="attrStyle2" format="reference"/>
<attr name="attrStyle3" format="reference"/>
By linking the style to the attr, you then apply that style to your custom class, which you can then duplicate as many times as needed
CustomButton1 theme1 = (CustomButton1)findViewById(R.id.theme1);
CustomButton2 theme2 = (CustomButton2)findViewById(R.id.theme2);
CustomButton3 theme3 = (CustomButton3)findViewById(R.id.theme3);
Hopefully this is of benefit to someone!
I want to set style or font to the text in a TextView like the image shown below:
<TextView
style="#style/CodeFont"
android:text="#string/hello" />
You need to Make that codefont style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
Straight from : http://developer.android.com/guide/topics/ui/themes.html
You need a custom font and then you can do this:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
MyTextView.setTypeface(mFont);
You have to create a "fonts" folder in your assets folder. Drop your font in there.
You could also create a custom TextView of course. Refer to this answer, I gave a while back, if you prefer that.
There is another way if you want to change it on many TextViews, Use a class:
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyTextView(Context context) {
super(context);
init();
}
private void init() {
if (!isInEditMode()) {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ubuntu-L.ttf");
setTypeface(tf);
}
}
}
and in the Layout replace:
<TextView
...
/>
With:
<com.WHERE_YOUR_CLASS_IS.MyTextView
...
/>
You could create a layout.xml file that would have your textview in it. Something like :
textView.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
style="#android:style/Holo.ButtonBar" >
If you dont want this then you could create your custom style. Something like this :
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Custom" parent="#android:style/TextAppearance.Large" >
<item name="android:typeface">monospace</item>
</style>
</resources>
and in the layout file change the style to something like :
style="#style/Custom"