ViewBinding--->BaseActivity/BaseFragment

在實(shí)際的開發(fā)當(dāng)中呜叫,我們總是會用到很多公用的方法空繁,可能我們習(xí)慣性的給封裝成一個(gè)公用的代碼塊方法,但其實(shí)開發(fā)一個(gè)APP來說朱庆,界面的交互都是通過activity和fragment來構(gòu)造的家厌,所以我們不妨封裝一個(gè)通用的activity和fragment父類,讓所有的activity和fragment都集成其中椎工,而在使用這些通用的方法的時(shí)候也方便我們直接去引用

封裝的方法有很多,但基本上都是大同小異维蒙,這里我們?nèi)ナ褂胿iewBing,沒有原因殖熟,因?yàn)橄矚g钳榨,哈哈哈,那什么是viewBinding呢饼齿?沒有比官方文檔更詳細(xì)的介紹了,有興趣的話可以具體的看看

viewBinding官方文檔

View Binding是Android Studio 3.6推出的新特性吃型,目的是為了替代findViewById(內(nèi)部實(shí)現(xiàn)還是使用findViewById)勤晚。运翼。在啟動視圖綁定后血淌,系統(tǒng)會為改模塊中的每個(gè)xml文件生成一個(gè)綁定類悠夯,綁定類的實(shí)例包含對在相應(yīng)布局中具有 ID 的所有視圖的直接引用沦补。

View Binding 的優(yōu)點(diǎn)

1夕膀、Null 安全:由于視圖綁定會創(chuàng)建對視圖的直接引用产舞,因此不存在因視圖 ID 無效而引發(fā) Null 指針異常的風(fēng)險(xiǎn)易猫。此外准颓,如果視圖僅出現(xiàn)在布局的某些配置中,則綁定類中包含其引用的字段會使用 @Nullable 標(biāo)記炮赦。
2眼五、類型安全:每個(gè)綁定類中的字段均具有與它們在 XML 文件中引用的視圖相匹配的類型看幼。這意味著不存在發(fā)生類轉(zhuǎn)換異常的風(fēng)險(xiǎn)诵姜。

接下來就是進(jìn)行我們的封裝方法了棚唆,首先需要在我們的項(xiàng)目去啟用viewBinding

android{
     //使用viewBinding
    buildFeatures {
        viewBinding = true
        }
}

然后就是封裝我們的基類了,從官方的來說其實(shí)很簡單

 protected VB binding;

 binding = getViewBinding();
 setContentView(binding.getRoot());

其實(shí)總體來說只有三行代碼瞎惫,其他的便是我們自己的拓展功能,這里不做過多贅述乘寒,直接上干貨

BaseActivity

public abstract class BaseAppCompatActivity<VB extends ViewBinding> extends AppCompatActivity
        implements View.OnClickListener {

    public static final int NON_CODE = -1;

    /*獲取屏幕信息*/
    protected int mScreenWidth = 0;
    protected int mScreenHeight = 0;
    protected float mScreenDensity = 0.0f;

    protected Context mContext = null;
    protected ImmersionBar mImmersionBar;
    protected VB binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //傳參
        Bundle extras = getIntent().getExtras();
        if (null != extras) {
            getBundleExtras(extras);
        }

        //注冊EventBus
        if (isBindEventBusHere()) {
            EventBus.getDefault().register(this);
            Log.e("eventBus", "register");
        }

        mContext = this;

        // 加入到Activity棧
        BaseAppManager.getInstance().addActivity(this);

        /* 獲取屏幕信息 */
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        mScreenDensity = displayMetrics.density;
        mScreenHeight = displayMetrics.heightPixels;
        mScreenWidth = displayMetrics.widthPixels;
        if (isImmersionBarEnabled()) {
            initImmersionBar();
        }
        binding = getViewBinding();
        setContentView(binding.getRoot());

        if (hasTitleBar()) {
            setCustomTitle(getTitle());
            onTitleBarBackClick();
        }
        initViewsAndEvents();
        addListener();
    }

    protected void initImmersionBar() {
        mImmersionBar = ImmersionBar.with(this);
        mImmersionBar.init();
        if (ImmersionBar.isSupportStatusBarDarkFont())
            mImmersionBar.statusBarDarkFont(true).keyboardEnable(true).init();
    }

    //綁定標(biāo)題欄
    protected boolean hasTitleBar() {
        return findViewById(R.id.title_bar) != null;
    }

    //設(shè)置標(biāo)題title
    protected void setCustomTitle(CharSequence title) {
        if (hasTitleBar()) {
            TextView titleView = findViewById(R.id.title_tv_message);
            if (titleView != null) {
                titleView.setText(title);
                setTitle("");
            }
        }
    }

    //獲取標(biāo)題欄返回鍵
    protected void onTitleBarBackClick() {
        if (hasTitleBar()) {
            ImageButton backView = findViewById(R.id.actionbar_back);
            if (backView != null) {
                backView.setOnClickListener(v -> finish());
            }
        }
    }

    /**
     * 是否可以使用沉浸式
     */
    protected boolean isImmersionBarEnabled() {
        return true;
    }

    /**
     * bind layout resource file
     */
    protected abstract VB getViewBinding();

    /**
     * init activity view and bind event
     */
    protected abstract void initViewsAndEvents();

    /**
     * 是否注冊EventBus
     */
    protected boolean isBindEventBusHere() {
        return false;
    }

    protected void getBundleExtras(Bundle extras) {
    }

    /**
     * 給 View 控件添加點(diǎn)擊事件監(jiān)聽器
     */
    protected void addListener() {
    }

    /**
     * view的點(diǎn)擊事件
     * 屏蔽快速點(diǎn)擊而引發(fā)的問題
     */
    protected void onWidgetClick(View view) {
    }

    private long lastTime = 0L;
    private View currentView = null;

    @Override
    public void onClick(View view) {
        long nowTime = System.currentTimeMillis();
        if (nowTime - lastTime > 1000L || view.getId() == currentView.getId()) {
            lastTime = nowTime;
            currentView = view;
            onWidgetClick(view);
        }
    }

    /**
     * startActivity
     *
     * @param clazz target Activity
     */
    protected void go(Class<? extends Activity> clazz) {
        _goActivity(clazz, null, NON_CODE, false);
    }

    /**
     * startActivity with bundle
     *
     * @param clazz target Activity
     */
    protected void go(Class<? extends Activity> clazz, Bundle bundle) {
        _goActivity(clazz, bundle, NON_CODE, false);
    }

    /**
     * startActivity then finish this
     *
     * @param clazz target Activity
     */
    protected void goAndFinish(Class<? extends Activity> clazz) {
        _goActivity(clazz, null, NON_CODE, true);
    }

    /**
     * startActivity with bundle and then finish this
     *
     * @param clazz  target Activity
     * @param bundle bundle extra
     */
    protected void goAndFinish(Class<? extends Activity> clazz, Bundle bundle) {
        _goActivity(clazz, bundle, NON_CODE, true);
    }

    /**
     * startActivityForResult
     */
    protected void goForResult(Class<? extends Activity> clazz, int requestCode) {
        _goActivity(clazz, null, requestCode, false);
    }

    /**
     * startActivityForResult with bundle
     */
    protected void goForResult(Class<? extends Activity> clazz, Bundle bundle, int requestCode) {
        _goActivity(clazz, bundle, requestCode, false);
    }

    /**
     * startActivityForResult then finish this
     */
    protected void goForResultAndFinish(Class<? extends Activity> clazz, int requestCode) {
        _goActivity(clazz, null, requestCode, true);
    }

    /**
     * startActivityForResult with bundle and then finish this
     */
    protected void goForResultAndFinish(Class<? extends Activity> clazz, Bundle bundle, int requestCode) {
        _goActivity(clazz, bundle, requestCode, true);
    }

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(layoutResID);
    }

    @Override
    public void finish() {
        super.finish();
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
        BaseAppManager.getInstance().removeActivity(this);
    }

    @Override
    protected void onDestroy() {
        if (isBindEventBusHere()) {
            EventBus.getDefault().unregister(this);
            Log.e("eventBus", "unregister");
        }
        if (mImmersionBar != null) {
            mImmersionBar.destroy();
        }
        BaseAppManager.getInstance().removeActivity(this);
        super.onDestroy();
    }

    /**
     * Activity 跳轉(zhuǎn)
     *
     * @param clazz  目標(biāo)activity
     * @param bundle 傳遞參數(shù)
     * @param finish 是否結(jié)束當(dāng)前activity
     */
    private void _goActivity(Class<? extends Activity> clazz, Bundle bundle, int requestCode, boolean finish) {
        if (null == clazz) {
            throw new IllegalArgumentException("you must pass a target activity where to go.");
        }
        Intent intent = new Intent(this, clazz);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        if (null != bundle) {
            intent.putExtras(bundle);
        }
        if (requestCode > NON_CODE) {
            startActivityForResult(intent, requestCode);
        } else {
            startActivity(intent);
        }
        if (finish) {
            finish();
        }
    }
}

BaseFragment

public abstract class BaseFragment<VB extends ViewBinding> extends Fragment
        implements View.OnClickListener {

    private static final int NON_CODE = -1;
    protected Context mContext;
    protected VB binding;

    //加載布局
    protected abstract VB getViewBinding(LayoutInflater inflater, ViewGroup viewGroup);

    protected abstract void initViewsAndEvents();

    /*是否綁定eventbus事件* */
    protected boolean isBindEventBusHere() {
        return false;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (isBindEventBusHere()) {
            EventBus.getDefault().register(this);
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = getViewBinding(inflater, container);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //屏幕適配
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        initViewsAndEvents();
        addListener();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (isBindEventBusHere()) {
            EventBus.getDefault().unregister(this);
        }
    }

    /**
     * 給 View 控件添加點(diǎn)擊事件監(jiān)聽器
     */
    protected void addListener() {
    }

    protected void onWidgetClick(View view) {
    }

    private long lastTime = 0L;
    private View currentView = null;

    @Override
    public void onClick(View view) {
        long nowTime = System.currentTimeMillis();
        if (nowTime - lastTime > 1000L || view.getId() == currentView.getId()) {
            lastTime = nowTime;
            currentView = view;
            onWidgetClick(view);
        }
    }

    /**
     * startActivity
     *
     * @param clazz target Activity
     */
    protected void go(Class<? extends Activity> clazz) {
        _goActivity(clazz, null, NON_CODE, false);
    }

    /**
     * startActivity with bundle
     *
     * @param clazz target Activity
     */
    protected void go(Class<? extends Activity> clazz, Bundle bundle) {
        _goActivity(clazz, bundle, NON_CODE, false);
    }

    protected void goForResult(Class<? extends Activity> clazz, int requestCode) {
        _goActivity(clazz, null, requestCode, false);
    }

    protected void goForResult(Class<? extends Activity> clazz, Bundle bundle, int requestCode) {
        _goActivity(clazz, bundle, requestCode, false);
    }

    /**
     * Activity 跳轉(zhuǎn)
     *
     * @param clazz  目標(biāo)activity
     * @param bundle 傳遞參數(shù)
     * @param finish 是否結(jié)束當(dāng)前activity
     */
    private void _goActivity(Class<? extends Activity> clazz, Bundle bundle, int requestCode, boolean finish) {
        if (null == clazz) {
            throw new IllegalArgumentException("you must pass a target activity where to go.");
        }
        Intent intent = new Intent(getActivity(), clazz);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        if (null != bundle) {
            intent.putExtras(bundle);
        }
        if (requestCode > NON_CODE) {
            startActivityForResult(intent, requestCode);
        } else {
            startActivity(intent);
        }
        if (finish) {
            getActivity().finish();
        }
    }
}

因?yàn)檫@里我們使用了一個(gè)偽沉浸式狀態(tài)欄鸠澈,所以需要在application的子節(jié)點(diǎn)下添加我們的APP的整體樣式际度,這里直接貼上style

<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

代碼傳送門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吵取,隨后出現(xiàn)的幾起案子皮官,更是在濱河造成了極大的恐慌盔憨,老刑警劉巖婿奔,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異冰木,居然都是意外死亡歇终,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翎碑,“玉大人杈女,你說我怎么就攤上這事ⅲ” “怎么了蝇裤?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵垛孔,是天一觀的道長狭莱。 經(jīng)常有香客問我腋妙,道長匙睹,這世上最難降的妖魔是什么垃僚? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任罕袋,我火速辦了婚禮朵夏,結(jié)果婚禮上仰猖,老公的妹妹穿的比我還像新娘。我一直安慰自己躏升,他們只是感情好膨疏,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布窘俺。 她就那樣靜靜地躺著洒闸,像睡著了一般均芽。 火紅的嫁衣襯著肌膚如雪掀宋。 梳的紋絲不亂的頭發(fā)上劲妙,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音余赢,去河邊找鬼妻柒。 笑死举塔,一個(gè)胖子當(dāng)著我的面吹牛央渣,可吹牛的內(nèi)容都是我干的痹屹。 我是一名探鬼主播志衍,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼惹悄,長吁一口氣:“原來是場噩夢啊……” “哼暂殖!你這毒婦竟也來了呛每?” 一聲冷哼從身側(cè)響起洋腮,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伙狐,沒想到半個(gè)月后鳞骤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年榴嗅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唠粥。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖官份,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情河咽,我是刑警寧澤爬舰,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站垃你,受9級特大地震影響惜颇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锨亏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乾翔。 院中可真熱鬧反浓,春花似錦、人聲如沸巧婶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毅人。三九已至丈莺,卻和暖如春弛秋,著一層夾襖步出監(jiān)牢的瞬間蟹略,已是汗流浹背挖炬。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留空闲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓跌榔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親担平。 傳聞我的和親對象是個(gè)殘疾皇子暂论,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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