How can i change those font attributes of a SwitchPreference?
I already tried to use app:layout attribute with the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#android:id/title"
style="#android:style/TextAppearance.Widget.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="MY-FONT"
android:text="Title" />
<TextView
android:id="#android:id/summary"
style="#android:style/TextAppearance.Widget.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="MY-FONT"
android:text="Summary" />
</LinearLayout>
That doesn't work well, because the switch was missing and everything looks a bit messy.
What is an easy (and working) way to customize the fontfamily and textSize?
You need to create a Custom Switch Preference by extending its main class
public class CustomSwitchPreference extends SwitchPreference {
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSwitchPreference(Context context) {
super(context);
}
#Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
TextView title1= (TextView) holder.findViewById(android.R.id.title);
title1.setTypeface(ResourcesCompat.getFont(getContext(),R.font.noto_sans_regular));
TextView title2= (TextView) holder.findViewById(android.R.id.summary);
title2.setTypeface(ResourcesCompat.getFont(getContext(),R.font.noto_sans_regular));
}
}
and use this is in your preferences xml
from
<SwitchPreference
.....
/>
to
<com.example.myapp.CustomSwitchPreference
....
/>
This Worked for me
To change the font family in android first you need to have the font in your app something like this
Your font goes in the font directory under res
Now to use it, your going in the right way
<Button
...
android:fontFamily="#font/nameOfFont"
... />
Let me now if it works for you
Related
I have a big library of custom components that I want to use in my Android app.
All components use custom attributes to customize its content.
This is a sample component declared in a XML file:
<myapp.CustomTextView
android:id="#+id/text_view_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginBottom="8dp"
custom:textContent="This is my text" />
This is the custom attributed declared:
<declare-styleable name="CustomTextView">
<attr name="textContent" format="string" />
</declare-styleable>
And this is the implementation of the custom component:
public class CustomTextView extends TextView {
private Context context;
public CustomTextView(Context context) {
this(context, null);
}
public CustomTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
readAttrs(context, attrs);
}
private void readAttrs(Context context, AttributeSet attrs) {
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTextView,0, 0);
try {
String content = array.getString(R.styleable.CustomTextView_textContent);
initContent(context, content);
} finally {
array.recycle();
}
}
private void initContent(Context context, String content) {
...
}
}
The problem is that I'm using data binding in my app, so if I do this, the app doesn't compile:
<myapp.CustomTextView
android:id="#+id/text_view_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginBottom="8dp"
custom:textContent="#{mainView.content}" />
After reading a lot, the solution seems to be to create a bindingadapter for that custom attribute, but in my case, create a binding adapter for every custom attribute would be a huge work because there are tons of components and attributes.
Is there a way to reduce this amount of work or to adapt data binding to these custom attributes?
I have researched a lot and find many sources to this problem but no solutions working for me I don't know what's going wrong.
Some resources i have look into
Custom view style, android's attributes are ignored
https://androidpedia.net/en/tutorial/1446/creating-custom-views
https://infinum.com/the-capsized-eight/how-to-support-themes-in-custom-views-for-android-apps
This is repo for this problem
https://github.com/burhankhanzada199888/CustomView-Style-StackOverflow-Question/tree/master/app
I have 2 custom view in my activity first without style tag and second with style tag but cardView style only apply when using in xml
custom_view.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="com.google.android.material.card.MaterialCardView"
tools:style="#style/CustomCardView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="4dp"
android:background="?colorSurface"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:padding="8dp"
android:src="#mipmap/ic_launcher"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?colorAccent"
android:gravity="center"
android:text="Lorem ipsum"
android:textColor="#android:color/white"
android:textSize="25sp" />
</LinearLayout>
</merge>
activity_main.xml
<com.myapp.CustomCardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.myapp.CustomCardView
style="#style/CustomCardView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
CustomCardView.java
public class CustomCardView extends MaterialCardView {
public CustomCardView(Context context) {
this(context, null);
}
public CustomCardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomCardView, defStyleAttr, R.style.CustomCardView);
float imageSize = a.getDimension(R.styleable.CustomCardView_imageSize, 0);
float textSize = a.getDimension(R.styleable.CustomCardView_textSize, 0);
a.recycle();
inflate(context, R.layout.custom_view, this);
ImageView imageView = findViewById(R.id.imageView);
imageView.getLayoutParams().height = (int) imageSize;
imageView.getLayoutParams().width = (int) imageSize;
TextView textView = findViewById(R.id.textView);
textView.setTextSize(textSize);
}
}
styles.xml
<style name="CustomCardView" parent="Widget.MaterialComponents.CardView">
<item name="cardElevation">8dp</item>
<item name="cardCornerRadius">16dp</item>
<item name="android:layout_margin">8dp</item>
<item name="cardBackgroundColor">?colorPrimary</item>
<item name="imageSize">150dp</item>
<item name="textSize">50sp</item>
</style>
attrs.xml
<declare-styleable name="CustomCardView">
<attr name="imageSize" format="dimension|reference" />
<attr name="textSize" format="dimension|reference" />
</declare-styleable>
You can add in the attrs.xml:
<attr format="reference" name="customCardViewStyle"/>
Change the constructor:
public CustomCardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
to
public CustomCardView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.customCardViewStyle);
}
Then in your app theme add:
<item name="customCardViewStyle">#style/CustomCardView</item>
Just pay attention to <item name="android:layout_margin">...</item>. The LayoutParams are specific to the parent view type and you can't apply it with a theme.You can set the layout attributes in a style on in the layout.
It happens because you've removed super calls in public CustomCardView(Context context) and public CustomCardView(Context context, AttributeSet attrs) constructors. Indeed your constructors must be like these:
public CustomCardView(Context context) {
super(context)
this(context, null);
}
and
public CustomCardView(Context context, AttributeSet attrs) {
super(context, attrs)
this(context, attrs, 0);
}
There is TextView inside RecyclerView(Screen A) and inside a FrameLayout(Screen B), but both have maxLines=10.
In RecyclerView, the textview renders only 10 lines and additional text is ignored.
But the textview in LinearLayout, shows 10 lines but allows the user to scroll.
How to disable scroll and to just show maximum lines set using maxLines.
I have already tried,
android:isScrollContainer="false" - it doesn't work
android:enabled="false" - it disables the hyperlink clicks in the textview
Update:
I don't want textview in RecyclerView to scroll, I want to disable scrolling in LinearLayout only.
Tried the below line?
recyclerView.setNestedScrollingEnabled(false);
create a NoScrollTextView extends TextView like this :
public class NoScrollTextView extends TextView {
public NoScrollTextView(Context context) {
super(context);
}
public NoScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public NoScrollTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void scrollTo(int x, int y) {
//do nothing
}
}
Then use this in xml as :
<com.example.NoScrollTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="10"/>
Just set in class
TextView tv = (TextView) view.findViewById(R.id.tv);
tv.setMovementMethod(null);
and in layout
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:maxLines="8"
android:text="Lorem Ipsum is simply dummy text of the dummy text of t printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy."
android:textSize="14sp" />
I'm facing this weird problem where I have a custom view (with custom drawing) overriding ToggleButton, and for some reason overriding the onDraw and draw methods do not prevent the parent class from drawing a part of it, which makes my view look like it's glitched.
This bug seems to be happening only with API level 25, on a physical device or on the emulator.
Using the following code for my custom toggle Button:
public class CustomToggleButton extends ToggleButton {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomToggleButton(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
//nope, not drawing anything
}
#Override
public void draw(Canvas canvas) {
//nope, not drawing anything
}
}
And the following simple XML layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:text="Bottom left: buggy custom ToggleButton.\nBottom right: regular ToggleButton." />
<test.com.togglebuttonbug.CustomToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|left"
android:textOff="B"
android:textOn="A" />
<ToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|right"
android:textOff="B"
android:textOn="A" />
</FrameLayout>
The result is the following:
If you look carefully at the screenshot, you can see that for the phone on the right, at the bottom left, instead of having nothing like the empty draw methods should do, you can see a piece of gray drawing.
Would anybody have an idea of what could be causing this? Is that a bug on Android N?
I extended the TextView class to "CustomTextView" that's why I needed to set a custom font. So it's the result:
public class CustomTextView extends TextView {
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/nn.otf"));
this.setTextSize(30);
}
}
You can see that I setted a default textSize that it's 30:
When I want this CustomTextView, I use this code:
<com.calendar.CustomTextView
android:id="#+id/edData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DOM 21 GIU"
android:textSize="45dp"/>
If you notice, I setted the textSize value to 45dp, but the it remains 30 (from the custom class).
How do I set a different textSize? Also, for bold style?
you should remove the this.setTextSize(30); from the constructor, because the xml layout do the resize in during the super(context, attrs) call, and the bold font should be included in the otf file (usually are different otf files for different styles)
This is my solution: (I made tests with textColor and not textSize, but it's the same).
I edited the res/values/atrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTextView">
<attr name="textColor" format="string" />
</declare-styleable>
</resources>
Then, I edited my class like:
public class CustomTextView extends TextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CustomTextView(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomTextView);
String fontName = a.getString(R.styleable.CustomTextView_fontName);
if (textColor != null) {
this.setTextColor(Color.parseColor(textColor));
} else {
this.setTextColor(Color.parseColor("#000000"));
}
a.recycle();
}
}
}
So this work:
<com.imgspa.listviewadapter.CustomTextView
android:id="#+id/ed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
listviewadapter:textColor="#FF0000"/>
<com.imgspa.listviewadapter.CustomTextView
android:id="#+id/edRis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35dp" />
The first custom textview text is red, the second one is black
To set the style just use android:textStyle="bold". For your other problem, you can check the textSize from the attributes I believe using attrs.getAttribute(NAME OF ATTRIBUTE) method and then you can set it to that value or set it to 30 depending on what you want.