1. 程式人生 > >Android基於DataBinding的一個基礎框架

Android基於DataBinding的一個基礎框架

開篇廢話

因公司需求,開發了一個基於DataBinding的基礎框架,以後公司可能寫專案都要按這個框架來寫,規範一些,有利於互相讀程式碼。先附上github連結吧——CFramework
如果不知道什麼是DataBinding,建議先看上一篇文章——Android MVVM框架 DataBinding

CFramework的介紹

基於DataBinding的一個基本框架,網路層使用okHttp。
第一次寫框架,定有不妥之處,望大家留言指出。
框架介紹也寫的一般,比較亂。會慢慢更正。
outlook:[email protected]
gmail:[email protected]

CFramework的依賴

新增依賴

在Project的build.gradle中新增:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

在Module的build.gradle中新增:

dependencies {
        compile 'com.github.super-cc:CFramework:v1.0.3'
}

在Module的build.gradle中android中新增:

dataBinding {
        enabled = true
}

記得新增網路許可權

<!--網路許可權-->
<uses-permission android:name="android.permission.INTERNET"/>

CFramework的使用

基礎框架

先看資料夾的圖片:

資料夾

先簡單的瞭解一下:
- base:基礎的Activity,Adapter,Http等。
- constant:一些常量。
- db:資料庫操作。
- lock:給xml設定的類
- model:DataBinding資料模型
- network:網路的封裝。
- response:網路請求返回的Json解析類
- service:服務類。
- ui:Activity,Fragment,Adapter介面類。
- utils:工具類。
- view:自定義控制元件。

基本使用

  • 在model下新建Demo類:
/**
 * 建立日期:2017/10/31 on 14:46
 * 描述:資料模型Demo,如果需要資料重新整理就繼承BaseObservable
 * 作者:郭士超
 * QQ:1169380200
 */

public class Demo extends BaseObservable{

    private String name;
    private String age;

    public Demo(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
  • 在model下新建DemoItem類:
/**
 * 建立日期:2017/10/31 on 16:47
 * 描述:在ListView或RecyclerView中使用的資料模型
 * 作者:郭士超
 * QQ:1169380200
 */

public class DemoItem {

    private String name;
    private String age;

    public DemoItem(String name, String age) {
        this.name = name;
        this.age = age + "歲";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
  • 在lock下新建DemoLock類:
/**
 * 建立日期:2017/10/31 on 13:54
 * 描述:DemoLock,處理一些網路資料,和一些邏輯
 * 作者:郭士超
 * QQ:1169380200
 */

public class DemoLock extends CBaseLock<ActivityDemoBinding> {

    private Demo mDemo;
    private List<DemoItem> mListDemo;
    private DemoAdapter mDemoAdapter;
    private CBaseRecyclerViewAdapter mAdapter;

    public DemoLock(Context context, ActivityDemoBinding binding) {
        super(context, binding);
    }

    @Override
    protected void init() {
        // 初始化資料
        mDemo = new Demo("郭士超", "22");

        mListDemo = new ArrayList<DemoItem>();
        mListDemo.add(new DemoItem(mDemo.getName(), mDemo.getAge()));
        mDemoAdapter = new DemoAdapter(mContext, mListDemo, R.layout.item_demo, BR.demoItem);
        mBinding.lvDemo.setAdapter(mDemoAdapter); // 這裡或者在xml裡設定adapter
        mDemoAdapter.setOnItemClickListener(new CBaseListViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ViewDataBinding binding, int position) {
                showToast(((ItemDemoBinding) binding).getDemoItem().getName()
                        + mListDemo.get(position).getAge());
            }
        });

        LinearLayoutManager ms = new LinearLayoutManager(mContext);
        mBinding.rvDemo.setLayoutManager(ms);
        mAdapter = new CBaseRecyclerViewAdapter(mContext, mListDemo, R.layout.item_demo, BR.demoItem);
//        mBinding.rvDemo.setAdapter(mAdapter); // 這裡或者在xml裡設定adapter
        mAdapter.setOnItemClickListener(new CBaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ViewDataBinding binding, int position) {
                showToast(((ItemDemoBinding) binding).getDemoItem().getName()
                        + mListDemo.get(position).getAge());
            }
        });

        // 訪問網路的方法
        HashMap hashMap = new HashMap();
        hashMap.put("userId", "1");
        Connection.getInstance().post(DemoResponse.class, UrlConfig.XXX, hashMap, new Connection.ResponseListener() {
            @Override
            public void tryReturn(int id, Object response) {
                switch (id) {
                    case 200:
                        DemoResponse data = (DemoResponse) response;
                        new Demo(data.getData().getName(), String.valueOf(data.getData().getAge()));
                        break;
                    case 100:
                        showToast("使用者不存在");
                        break;
                    default:
                        showToast(((HttpResponse)response).getMsg());
                        break;
                }
            }
        });
    }

    public void update(View view) {
        mDemo.notifyChange(); // 重新整理資料
        mListDemo.add(new DemoItem(mDemo.getName(), mDemo.getAge()));
        mDemoAdapter.notifyDataSetChanged(); // 重新整理資料
        mAdapter.notifyDataSetChanged(); // 重新整理資料
    }

    public Demo getDemo() {
        return mDemo; // 讓xml中可以呼叫到Demo
    }

    public DemoAdapter getDemoAdapter() {
        return mDemoAdapter; // 讓xml中可以呼叫到mAdapter
    }

    public CBaseRecyclerViewAdapter getAdapter() {
        return mAdapter;
    }

}
  • 新建xml檔案activity_demo佈局:
<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="demoLock"
            type="com.superc.framework.lock.DemoLock" />
    </data>

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{demoLock.demo.name}"
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.36"
        android:layout_marginTop="32dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{demoLock.demo.age}"
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.64"
        android:layout_marginTop="32dp"/>

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="@={demoLock.demo.name}"
        android:inputType="textPersonName"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.503"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="72dp"/>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="@={demoLock.demo.age}"
        android:inputType="number"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.503"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@+id/editText"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="更新"
        android:onClick="@{(view)->demoLock.update(view)}"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@+id/editText2"/>

    <ListView
        android:id="@+id/lv_demo"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="16dp"
        android:visibility="visible"
        app:adapter="@{demoLock.demoAdapter}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button"
        app:layout_constraintVertical_bias="0.0"
        app:layout_constraintRight_toLeftOf="@+id/guideline"
        android:layout_marginRight="8dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_demo"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="16dp"
        app:adapter="@{demoLock.adapter}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button"/>

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5"/>

</android.support.constraint.ConstraintLayout>

</layout>
  • 在ui下新建DemoActivity類:
/**
 * 建立日期:2017/10/30 on 13:55
 * 描述:一個Demo
 * 作者:郭士超
 * QQ:1169380200
 */

public class DemoActivity extends BaseActivity {

    @Override
    protected void initBinding() {

        // 資料繫結操作,可以套用程式碼
        ActivityDemoBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_demo);
        DemoLock demoLock = new DemoLock(this, mBinding);
        mBinding.setDemoLock(demoLock);

    }

}

現在已經可以執行程式碼。

  • 如果是在Fragment中使用:
/**
 * 建立日期:2017/10/31 on 14:07
 * 描述:
 * 作者:郭士超
 * QQ:1169380200
 */

public class DemoFragment extends CBaseFragment {

    @Override
    protected View initBinding(LayoutInflater inflater, ViewGroup container) {

        FragmentDemoBinding mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_demo, container, false);
        DemLock demLock = new DemLock(mActivity, mBinding);
        mBinding.setDemLock(demLock);

        return mBinding.getRoot();
    }

}
  • 如果需要自定義Adapter:
/**
 * 建立日期:2017/10/31 on 15:44
 * 描述:繼承BaseListViewAdapter,只需要複寫subTask就可以
 * 作者:郭士超
 * QQ:1169380200
 */

public class DemoAdapter extends CBaseListViewAdapter{

    public DemoAdapter(Context context, List list, int layoutId, int variableId) {
        super(context, list, layoutId, variableId);
    }

    @Override
    protected void subTask(ViewDataBinding binding, int position) {
        super.subTask(binding, position);
        // 這裡可以寫自己一些自己的邏輯,如果不需要,一般直接用BaseListViewAdapter就可以,不需要再構建
        // 寫法大概如下
        ((ItemDemoBinding)binding).tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
    }

}

依賴使用

如果依賴使用的話,最好是自己再寫一個BaseActivity和BaseLock分別繼承與CBaseActivity和CBaseLock,在裡面寫一些自己專案需要的東西。

其它用法

Connection類

這個類是單例模式,呼叫方法就是:

Connection.getInstance().post();

這個類封裝了get,post的方法,主要使用這兩種形式就可以。
還有一些其它的post方法(重點的兩個):
- postLogin:登入時自動儲存userId和token。
- postToken:訪問直接帶userId和token。

裡面還有一個toLogin()方法沒有寫,這個方法用於如果token不對,跳回到LoginActivit。
這個也可以自己仿照自己封裝一個。

RunTime類

這個類是一些執行時的臨時資料。
是使用容器實現單例模式。

UrlConfig類

這個類存放專案的介面url。

工具類

主要工具類有:
- AppUtil:App相關輔助類。
- AtyManager:Activity管理類。
- DensityUtil:螢幕常用單位轉換的輔助類。
- KeyBoardUtil:軟鍵盤相關輔助類。
- LogUtil:Log統一管理類,上線時把isDebug設定為false。
- NetUtil:跟網路相關的工具類。
- ScreenUtil:獲得螢幕相關的輔助類。
- SPUtil:SharePreference儲存工具類。
- ToastUtil:Toast統一管理類。
- UnicodeUtil:utf-8和unicode漢字碼轉換器。

工具類的註釋很詳細,如果需要檢視,在程式碼中import,然後ctrl+滑鼠左擊,進入程式碼中檢視。

寫在後面

自己第一次寫框架,寫自己的教程,寫的很亂,我會慢慢更正。