Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One-line font applying using Android-M data-binding doesn't work

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?

like image 430
Ashkan Sarlak Avatar asked Sep 14 '15 05:09

Ashkan Sarlak


People also ask

Which is better view binding or data binding in Android?

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.

Is data binding good in Android?

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.

What is one way data binding in Android?

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.

How do I enable data binding and view binding?

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.


1 Answers

Provided the above layout and setup, assuming following:

Inside your RecyclerView adapter you have bound the view by one of these ways:

  1. 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());
    }
    
  2. Or in its onBindViewHolder method

        @Override
        public void onBindViewHolder(MyAdapter.MyHolder holder, int position) {
            DataBindingUtil.bind(holder.itemView);
            //...
        }
    

Following resource setup

Your assets folder should look similar to this:

assets folder

Your string resource file should have full qualified name for font:

<string name="kenyan">kenyan_rg.ttf</string>

With this ensured, it should work (and it does for me)

like image 84
subhash Avatar answered Oct 17 '22 16:10

subhash