告別findView和ButterKnife

寫在前面

在以往的android開發(fā)中蜡励,我們需要使用到findviewById方法來進(jìn)行初始化view,所以對(duì)于頁面復(fù)雜的情況嗦篱,經(jīng)常會(huì)看到十幾二十行的findviewById方法,而如果需要設(shè)置點(diǎn)擊事件,則又需要十幾二十行的代碼损晤,寫著很枯燥也很耽擱時(shí)間。作為一個(gè)程序員而不是搬運(yùn)工红竭,千萬不要做沒有效率的事尤勋,好在jake大神給我們帶來了ButterKnife,在一段時(shí)間內(nèi)為我們自動(dòng)綁定了view茵宪,代替了繁雜的手寫步驟最冰。

可是相信使用過ButterKnife的同學(xué)都有一個(gè)感受,就是如果一個(gè)頁面view過多的話稀火,也需要一長(zhǎng)串的bindView代碼暖哨,導(dǎo)致一個(gè)頁面輕輕松松300行+的代碼量,看著也有點(diǎn)不舒服凰狞。而這些也都是重復(fù)性的工作篇裁,那么有什么辦法解決嗎?

有胺颉茴恰!

DataBinding

說實(shí)話,DataBinding也出來蠻久了斩熊,可是用的人也蠻少的往枣。原因可能是大家在選擇的時(shí)候多選擇了比較流行的MVP,二來是DataBinding還沒有像前端那樣完善粉渠,處于一個(gè)觀望的狀態(tài)分冈。但是最近已經(jīng)出現(xiàn)了越來越多的DataBinding的文章,說明越來越多的開發(fā)者開始注重這一塊的技術(shù)霸株,畢竟是金子總會(huì)發(fā)光的雕沉,不多說。

首先去件,我們需要開啟DataBinding坡椒,不需要引入額外的依賴庫,因?yàn)镈ataBinding是在support包中的尤溜。

android {
    …
    dataBinding {
        enabled = true
    }
}

然后倔叼,我們只需要在改變一下xml的寫法:

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

    </data>

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.ditclear.app.MainActivity">

        <TextView
            android:id="@+id/content_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Hello World!"/>
    </RelativeLayout>

</layout>

其實(shí)和以前差不多,就是外面包了一層<layout>宫莱,所以遷移起來很快丈攒。

然后就可以使用了,這樣寫了之后,系統(tǒng)會(huì)給你生成一個(gè)以xml文件名為前綴的文件巡验。比如activity_main.xml际插,則會(huì)在build文件夾下生成ActivityMainBinding.java的文件,里面有各種綁定View的操作显设,這樣我們就不用在自己的activity中寫了框弛。而使用的話直接使用ActivityMainBinding的對(duì)象就好了。
例子:

package com.ditclear.app;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

import com.ditclear.app.databinding.ActivityMainBinding;//生成的bind文件

public class MainActivity extends AppCompatActivity {


    private ActivityMainBinding mBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);

        mBinding.contentTv.setText("this is bindText");//輕輕松松拿到view
    }
}

很簡(jiǎn)單敷硅,而且activity瞬間簡(jiǎn)潔了功咒。

當(dāng)然還有更簡(jiǎn)單的寫法,生成的binding文件和DataBindingUtil.setContentView()方法其實(shí)都是固定的绞蹦,我們可以使用泛型來簡(jiǎn)化這些步驟力奋,相信大家都想到了。

首先抽象出一個(gè)基類BaseBindActivity:

**
 * 頁面描述:activity基類
 * <p>
 * Created by ditclear on 2017/4/16.
 */

public abstract class BaseBindActivity<VB extends ViewDataBinding> extends AppCompatActivity {

    protected VB mBinding;
    ...

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      
        View rootView = getLayoutInflater().inflate(this.getLayoutId(), null, false);
        mBinding = DataBindingUtil.bind(rootView);
        super.setContentView(rootView);
    
        ...
        initView();
    }
  
    @LayoutRes
    protected abstract int getLayoutId();
  
    protected void initView();
}

接下來幽七,我們繼承它然后傳入layoutId就行了景殷。

package com.ditclear.app;

import com.ditclear.app.base.BaseBindActivity;
import com.ditclear.app.databinding.ActivityMainBinding;

public class MainActivity extends BaseBindActivity<ActivityMainBinding> {


    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {

        mBinding.contentTv.setText("this is bindText");
    }


}

需要注意的是,如果是以include的方式存在于xml文件中的話澡屡,我們需要為include的布局設(shè)置一個(gè)id猿挚,并且include的布局也需要寫成databinding的形式。

toolbar_default.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

    </data>

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="@color/colorPrimary"
        app:theme="@style/AppTheme">

        <TextView
            android:id="@+id/title_tv"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:gravity="center"
            android:textColor="@color/text_default"
            android:textSize="@dimen/text_size_default"
            android:textStyle="bold"/>
    </android.support.v7.widget.Toolbar>
</layout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

    </data>

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.ditclear.app.MainActivity">

        <include
            android:id="@+id/toolbar_layout"
            layout="@layout/toolbar_default"/>

        <TextView
            android:id="@+id/content_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Hello World!"/>
    </RelativeLayout>

</layout>

這樣我們就能直接操作toolbar了

 @Override
    protected void initView() {
      
        mBinding.toolbarLayout.titleTv.setText("main");
        mBinding.contentTv.setText("this is bindText");
    }

當(dāng)然驶鹉,由于有一些子類的布局并不需要include一個(gè)toolbar布局绩蜻,所以在BaseBindActivity里我們還是通過findViewById來進(jìn)行操作,畢竟不能忘本啊室埋。

  /**
     * 初始化toolbar
     */
    private void initToolBar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
          //有些布局可能不需要toolbar,判斷是否為空办绝,來進(jìn)行剩下的操作
          //recyclerView和RefreshLayout同理
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setTitle(null);
            setShowBackNavigation(true);
        }
    }

這樣我們就能操作toolbar了,和以前的寫法一模一樣姚淆,限制就是統(tǒng)一了toolbar的id為toolbar孕蝉,但是我覺得這也能算是團(tuán)隊(duì)間的規(guī)范吧,免得出現(xiàn)形形色色的名稱腌逢。

recyclerView和RefreshLayout同理降淮。

效果

Image.png

最后

這只是最基礎(chǔ)的綁定view的例子以及使用泛型和DataBinding來構(gòu)造我們的基類,只是寫了一個(gè)BaseActivity搏讶,F(xiàn)ragment同樣的道理佳鳖。DataBinding當(dāng)然不止這些,還能簡(jiǎn)化RecyclerView的操作媒惕,告別反復(fù)的自定義Adapter系吩,推薦大帥的DataBingding入門指南和用于綁定的RecyclerView的庫DataBindingAdapter

項(xiàng)目地址:https://github.com/ditclear/BaseViewBinding

ending...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吓笙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子巾腕,更是在濱河造成了極大的恐慌面睛,老刑警劉巖絮蒿,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叁鉴,居然都是意外死亡土涝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門幌墓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來但壮,“玉大人,你說我怎么就攤上這事常侣±” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵胳施,是天一觀的道長(zhǎng)溯祸。 經(jīng)常有香客問我,道長(zhǎng)舞肆,這世上最難降的妖魔是什么焦辅? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮椿胯,結(jié)果婚禮上筷登,老公的妹妹穿的比我還像新娘。我一直安慰自己哩盲,他們只是感情好前方,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著种冬,像睡著了一般镣丑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娱两,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天莺匠,我揣著相機(jī)與錄音,去河邊找鬼十兢。 笑死趣竣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旱物。 我是一名探鬼主播遥缕,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宵呛!你這毒婦竟也來了单匣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎户秤,沒想到半個(gè)月后码秉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸡号,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年转砖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲸伴。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡府蔗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汞窗,到底是詐尸還是另有隱情姓赤,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布杉辙,位于F島的核電站模捂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蜘矢。R本人自食惡果不足惜狂男,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望品腹。 院中可真熱鬧岖食,春花似錦、人聲如沸舞吭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羡鸥。三九已至蔑穴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惧浴,已是汗流浹背存和。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衷旅,地道東北人捐腿。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像柿顶,于是被迫代替她去往敵國和親茄袖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容