I'm trying to apply some custom font to my TextView
with one line as described in a post by Lisa Wray. The TextView
is part of an item that goes into a RecyclerView
I've added data binding dependency to my top level build file.
classpath 'com.android.tools.build:gradle:1.3.0'
classpath "com.android.databinding:dataBinder:1.0-rc1"
I have also applied the plugin to my main module:
apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'
Here is the item.xml
file that will be added to the RecyclerView
.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools">
<data></data>
<android.support.v7.widget.CardView
android:id="@+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="100dp"
android:layout_height="130dp"
android:layout_gravity="center"
card_view:cardCornerRadius="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="100dp"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:font="@{@string/font_yekan}"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</layout>
I've added a layout
root element and app:font="@{@string/font_yekan}"
combined with a static setter method:
@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName) {
textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}
should do the trick. But when I run the program, the font isn't changed. However, when I remove the above static method, I get the following error:
Cannot find the setter for attribute 'app:font' with parameter type java.lang.String.
So data binding framework has recognized the binding stuff, but the setter method doesn't get called (Logs don't print output).
What is the problem here?
View binding and data binding both generate binding classes that you can use to reference views directly. However, view binding is intended to handle simpler use cases and provides the following benefits over data binding: Faster compilation: View binding requires no annotation processing, so compile times are faster.
Using data binding can lead to faster development times, faster execution times and more readable and maintained code. Android data binding generates binding classes at compile time for layouts.
Data binding in Android Updating the views from the data source is a simple one-way binding. In that case, you'll only access data from the data source and update the layout. Two-way data binding is nothing but updating the data source if there are any changes in the layout and vice versa.
Step 2: Enabling the ViewBinding Feature There is a need to enabling the ViewBinding feature in Android Studio 4.0 and above, inside the app-level build gradle file. Invoke the following code snippet inside the android{} body of the gradle file.
Provided the above layout and setup, assuming following:
RecyclerView
adapter you have bound the view by one of these ways:In onCreateViewHolder method of your adapter class
@Override
public MyAdapter.MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.recycler_item,
parent, false);
return new MyHolder(binding.getRoot());
}
Or in its onBindViewHolder method
@Override
public void onBindViewHolder(MyAdapter.MyHolder holder, int position) {
DataBindingUtil.bind(holder.itemView);
//...
}
Your assets folder should look similar to this:
Your string resource file should have full qualified name for font:
<string name="kenyan">kenyan_rg.ttf</string>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With