安卓大變天!ButterKnife被棄用:Resource IDs will be non-final in Android Gradle Plugin version 5.0

2020-10-25 10:01:41

碼字辛苦!轉載請註明出處!

0.前言

最近,AndroidStudio升級到了4.1版本,在使用ButterKnife時,使用BindView註解給出了這樣的提示:Resource IDs will be non-final in Android Gradle Plugin version 5.0,WTF?一個月改一次API的老谷歌又來坑開發者了???

是的,在未來,所有的R.id.*都會變成變數,儘管不知道這樣做是出於什麼原因。

ButterKnife的作者也跳出來宣稱,開發已經進入尾聲,將不再更新並棄用,推薦我們使用谷歌官方推出的 View Binding

有趣的是,我在注意到這個改動前,推播了一個帶著這個警告的版本,而這個版本並沒有發生任何的異常崩潰。

也就是說,如果專案緊張,暫時保持不動也沒有問題,但我們仍需要逐漸的將使用ButterKnife的專案遷移到ViewBinding,或者乾脆直接改用親兒子kotlin(會自動繫結佈局)

1.使用View Binding

首先,我們需要啟用這個工具,在app的build.gradle中,新增如下內容:

android {
        ...
        viewBinding {
            enabled = true
        }
    }
    

2.在Activity中使用

假設我們有一個activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>
</RelativeLayout>

AndroidStudio會檢測所有的XML檔案,使用駝峰法命名+Binding字尾,建立繫結類:比如activity_main,會生成一個ActivityMainBinding類。

我們這樣使用它:

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //注意!!!在setContentView之前!!!
        ActivityMainBinding inflate = ActivityMainBinding.inflate(getLayoutInflater());

        //注意!!!這裡是inflate.getRoot(),不是R.layout.activity_main
        setContentView(inflate.getRoot());

        //這裡的tv就是XML中的id為tv的TextView
        inflate.tv.setText("Fxxk gooooooogie !!!");
    }

用起來還是蠻簡單的,但這仍然掩蓋不了谷歌的迷惑行為,ButterKnife的註解式程式設計程式碼更加清晰不是嘛~

3.在Fragment中使用

假設我們有一個fragement_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
</RelativeLayout>

我們這樣使用它:

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        FragementMainBinding inflate = FragementMainBinding.inflate(inflater, container, false);
        inflate.tv.setText("Holy G00gie");
        return inflate.getRoot();
    }

最後是老規矩,雖然CSDN有了訂閱付款,但我還是更青睞自願打賞(雖然基本沒有收入QvQ)