Android開發框架Collection-kotlin(更新篇)

YoungManSter發表於2020-02-29

Collection聚合了專案搭建的一些基本模組,節約開發者時間,協助專案的快速搭建,RecyclerView+Adapter+Retrofit+RxJava+MVP+DataManager+基本Base,能夠滿足一個專案的基本實現。

推薦檔案

Android X庫之前版本可使用Collection-Android:juejin.im/post/5ab998…

Collection-iOS庫:juejin.im/post/5e423d…

Collection-kotlin作為Collection-Android的更新篇,主要是為了解決使用Android X庫帶來的一些問題以及模組的優化

github地址:github.com/usernameyan…
簡書地址:www.jianshu.com/p/a6cb49532…

更新說明

v1.1.0

1.修復SQLite沒有建立表查詢異常 2.SQLite增加按條件查詢List 3.增加PopupWindow顯示位置設定 4.解決SQLit內容為null報錯

v1.0.1

狀態列修改:增加設定狀態列透明+黑色字型

v1.0.0

1.在Collection-Android的基礎上適配Android X庫
2.去掉Relam資料模組,安裝包大小減少
3.對原生SQLite資料庫進行封裝,使用更加方便 4.對DataManager的使用進行修整 5.增加AutoLineLayout/TagView 6.增加LinkedMultiValueMap
7.增加RxJavaUtils,可進行子/主執行緒資料處理切換

框架的引入

implementation 'com.youngman:collection_kotlin:1.1.0'

一、框架整體模組

效果圖

二、PullToRefreshRecyclerView的使用

屬性 作用
addHeaderView 增加頭部佈局, 暫時只能新增一個頭佈局
setEmptyView 設定自定義的載入佈局和空佈局
setRefreshView 自定義重新整理View
setDefaultLoadingMoreNoDataMessage 設定預設沒有資料的內容
setLoadMoreView 自定義載入更多View
setNoMoreDate 顯示沒有更多資料
setAutoRefresh 自動重新整理
refreshComplete 重新整理資料完成
loadMoreComplete 載入更多資料完成
setPullRefreshEnabled 是否允許重新整理
setLoadMoreEnabled 是否允許載入更多
setRefreshTimeVisible 顯示載入更新時間
isLoading 是否正在loading資料
isRefreshing 正在refreshing資料
setRefreshAndLoadMoreListener 重新整理和載入更多回撥
destroy 記憶體回收

1.框架預設下拉重新整理、上拉載入更多樣式

效果圖

(1)佈局檔案
 <com.youngmanster.collection_kotlin.recyclerview.PullToRefreshRecyclerView
	android:id="@+id/recycler_rv"
	android:layout_width="match_parent"
	android:layout_height="match_parent" />
複製程式碼
(2)程式碼設定
 recycler_rv.setPullRefreshEnabled(true)
 recycler_rv.setLoadMoreEnabled(true)
複製程式碼

2、自定義下拉重新整理、上拉載入更多樣式

效果圖

重新整理幾種狀態:
屬性 作用
STATE_PULL_DOWN 拉的狀態(還沒到下拉到固定的高度時)
STATE_RELEASE_REFRESH 下拉到固定高度提示釋放重新整理的狀態
STATE_REFRESHING 正在重新整理狀態
STATE_DONE 重新整理完成
載入更多幾種狀態:
屬性 作用
STATE_LOADING 正在載入
STATE_COMPLETE 加 載完成
STATE_NODATA 沒有資料
(1)程式碼設定
recycler_rv.setPullRefreshEnabled(true)
recycler_rv.setLoadMoreEnabled(true)
recycler_rv.setRefreshAndLoadMoreListener(this)
recycler_rv.setRefreshView(DefinitionAnimationRefreshHeaderView(activity))
recycler_rv.setLoadMoreView(DefinitionAnimationLoadMoreView(activity))
複製程式碼
自定義重新整理的步驟:
①自定義View繼承BasePullToRefreshView,重寫initView()、setRefreshTimeVisible(boolean show)、destroy()方法:

1.在initView()做自定義佈局、相關動畫的初始化,最後在initView()方法的最後面新增以下程式碼即可。

     mContainer =
        LayoutInflater.from(context).inflate(R.layout.layout_definition_animation_refresh, null)
    //把重新整理頭部的高度初始化為0
    val lp = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
    lp.setMargins(0, 0, 0, 0)
    this.layoutParams = lp
    this.setPadding(0, 0, 0, 0)
    addView(mContainer, LayoutParams(LayoutParams.MATCH_PARENT, 0))
    gravity = Gravity.BOTTOM

    //測量高度
    measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
    mMeasuredHeight = measuredHeight
複製程式碼

2.setRefreshTimeVisible(boolean show)是用來設定是否顯示重新整理時間控制元件,在預設重新整理樣式中通過mRecyclerView.setRefreshTimeVisible(false)即可隱藏重新整理時間,如果在自定義的佈局中沒有這項這個方法就可以忽略。

3.destroy()是用來關掉改頁面時把重新整理View的一些動畫等釋放,防止記憶體洩漏。

②實現BasePullToRefreshView.OnStateChangeListener監聽(重點,主要是進行狀態切換後的相關操作邏輯)

1.在建構函式中設定 onStateChangeListener=this 2.onStateChange的模板樣式

override fun onStateChange(state: Int) {

    if(isDestroy){
        return
    }
    //下拉時狀態相同不做繼續保持原有的狀態
    if (state == mState) return
    //根據狀態進行動畫顯示
    when (state) {
        STATE_PULL_DOWN -> {
            clearAnim()
            startAnim()
        }
        STATE_RELEASE_REFRESH -> {
        }
        STATE_REFRESHING -> {
            clearAnim()
            startAnim()
            scrollTo(mMeasuredHeight)
        }
        STATE_DONE -> {
        }
    }
    mState = state
}
複製程式碼
自定義載入更多的步驟(包括沒有更多資料顯示的操作):
①自定義View繼承BaseLoadMoreView,重寫initView()、setState()、destroy()方法:

1.在initView()做自定義佈局、相關動畫的初始化,最後在initView()方法的最後面新增以下程式碼即可

    mContainer = LayoutInflater.from(context)
        .inflate(R.layout.layout_definition_animation_loading_more, null)
    addView(mContainer)
    gravity = Gravity.CENTER
複製程式碼

2.destroy()是用來關掉改頁面時把重新整理View的一些動畫等釋放,防止記憶體洩漏。 3.在setState()進行狀態切換後的相關操作邏輯,模板樣式

override fun setState(state: Int) {

    if(isDestroy){
        return
    }

    when (state) {
        STATE_LOADING -> {
            loadMore_Ll?.visibility = VISIBLE
            noDataTv?.visibility = INVISIBLE
            animationDrawable = loadingIv?.drawable as AnimationDrawable
            animationDrawable?.start()
            this.visibility = VISIBLE
        }
        STATE_COMPLETE -> {
            animationDrawable?.stop()
            this.visibility = GONE
        }
        STATE_NODATA -> {
            loadMore_Ll?.visibility = INVISIBLE
            noDataTv?.visibility = VISIBLE
            animationDrawable = loadingIv?.drawable as AnimationDrawable
            animationDrawable?.start()
            this.visibility = VISIBLE
        }
    }

    mState = state
}
複製程式碼

4.注意:在自定義載入更多樣式時,如果需要有沒有更多載入更多資料提示同樣需要在佈局中寫好,然後在onSatae中根據狀態對載入和沒有跟多顯示提示進行顯示隱藏操作。

3、上拉載入更多配合SwipeRefreshLayout使用

效果圖

(1)佈局檔案
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

     <com.youngmanster.collection_kotlin.recyclerview.PullToRefreshRecyclerView
        android:id="@+id/recycler_rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
複製程式碼
(2)程式碼設定
recycler_rv.setLoadMoreEnabled(true)
recycler_rv.setRefreshAndLoadMoreListener(this)
recycler_rv.setLoadMoreView(DefinitionAnimationLoadMoreView(activity))
swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent)
swipeRefreshLayout.setOnRefreshListener(this)
複製程式碼
(3)注意的問題

由於PullToRefreshRecyclerView的下拉重新整理和下拉載入更多完成時會自動重新整理Adapter,而SwipeRefreshLayout重新整理完成時需要手動進行notifyDataSetChanged重新整理介面卡。

4、RecyclerView新增頭部、空佈局

效果圖

(1)程式碼設定
    //增加頭佈局
    val header = LayoutInflater.from(activity).inflate(R.layout.layout_main_header, null)
    recycler_rv.addHeaderView(header)

    //增加空佈局
    val emptyView = LayoutInflater.from(activity).inflate(R.layout.layout_empty, null)
    recycler_rv.emptyView = emptyView
    emptyView.setOnClickListener {
        for (i in 0..9) {
            mDatas.add("item$i")
        }
        definitionRefreshAdapter?.notifyDataSetChanged()
    }
複製程式碼

5、上拉載入更多實現NoMoreData、自動重新整理

效果圖

(1)上拉載入更多資料的佈局設定在上面的自定義LoadingMoreView中有介紹,如果要顯示沒有更多資料提示只需要在LoadMore返回資料之後設定:
mRecyclerView.setNoMoreDate(true)
複製程式碼
(2)自動重新整理需要列表已經填充了資料之後再做自動重新整理操作才會生效:
mRecyclerView.setAutoRefresh()
複製程式碼

6.Collection庫的重新整理載入文字已經適配了中文、英文、繁體,如果對預設重新整理載入顯示文字進行修改,通過LoadingTextConfig設定,可在Application全域性設定

val textConfig = LoadingTextConfig.getInstance(applicationContext)
textConfig
     .setCollectionLoadingMore("載入更多")
     .setCollectionLastRefreshTimeTip("更新時間:")
     .setCollectionNoMoreData("沒有更多資料")
     .setCollectionPullReleaseText("釋放重新整理")
     .setCollectionRefreshing("正在重新整理")
     .setCollectionPullDownRefreshText("下拉重新整理")
     .setCollectionRefreshDone("載入完成")
 PullToRefreshRecyclerViewUtils.loadingTextConfig = textConfig
複製程式碼

7、PullToRefreshRecyclerView的其他使用以及注意問題

1.下面是下拉重新整理上拉載入更多的一些操作模板

private fun refreshUI() {
    if (defaultRefreshAdapter == null) {
        defaultRefreshAdapter =
            DefaultRecyclerAdapter(
                activity!!,
                R.layout.item_pull_refresh,
                mDatas,
                recycler_rv
            )
        recycler_rv.adapter = defaultRefreshAdapter
    } else {
        if (recycler_rv != null) {
            if (recycler_rv.isLoading) {
                recycler_rv.loadMoreComplete()
            } else if (recycler_rv.isRefreshing) {
                recycler_rv.refreshComplete()
            }
        }
    }
}
複製程式碼

2.注意問題

①在設定RecyclerView是要設LayoutManager
②如果使用PullToRefreshRecyclerView在Activty/Fragment中的onDestroy()呼叫mRecyclerView.destroy()防止記憶體洩漏。
@Override
public void onDestroy() {
	super.onDestroy();
	mRecyclerView?.destroy()
}
複製程式碼
③設定refreshRv.setLoadMoreEnabled(true),當填充的資料的列表size為0的同時還通過RecyclerView設定分割線底部就會出現一個空白的item,這個item就是載入更多顯示的Item。
解決辦法:不通過RecyclerView設定分割線,直接在佈局自定義分割線。

三、BaseRecyclerViewAdapter的使用

1.BaseRecyclerViewAdapter的比原始Adapter的程式碼量減小

在BaseRecyclerViewAdapter中的BaseViewHolder進行佈局轉化,同時定義了一些比較基本的View操作,使用簡單。

(1)使用程式碼:
class DefinitionRecyclerAdapter(
      mContext: Context,
      mLayoutResId: Int,
      mDatas: ArrayList<String>,
      pullToRefreshRecyclerView: PullToRefreshRecyclerView
) : BaseRecyclerViewAdapter<String>(mContext, mLayoutResId, mDatas, pullToRefreshRecyclerView) {

    override fun convert(baseViewHolder: BaseViewHolder, t: String) {
          baseViewHolder.setText(R.id.title, t)
    }
}
複製程式碼
①使用者需要在繼承BaseRecyclerViewAdapter時傳入一個資料實體型別,具體的操作在convert()方法中操作。
②BaseViewHolder提供了一些常用View的基本操作,通過baseViewHolder.getView()可得到佈局中的控制元件。
(2)BaseRecyclerViewAdapter提供了兩個建構函式
public BaseRecyclerViewAdapter(Context mContext, int mLayoutResId, List<T> mDatas, PullToRefreshRecyclerView pullToRefreshRecyclerView) {
	this.mContext = mContext;
	this.mLayoutResId = mLayoutResId;
	this.mDatas = mDatas;
	this.mRecyclerView=pullToRefreshRecyclerView;
}

public BaseRecyclerViewAdapter(Context mContext, int mLayoutResId, List<T> mDatas) {
	this.mContext = mContext;
	this.mLayoutResId = mLayoutResId;
	this.mDatas = mDatas;
}
複製程式碼
主要是對PullToRefreshRecyclerView和RecyclerView的適配,使用時介面卡根據需要使用對應的建構函式。

2.新增Item的點選和長按事件

效果圖

(1)Item長按事件實現
 itemClickAdapter.setOnItemLongClickListener(object :
        BaseRecyclerViewAdapter.onItemLongClickListener {
        override fun onItemLongClick(view: View, position: Int): Boolean {
            showToast("進行長按操作")
            return true
        }
    })
複製程式碼

3.多佈局的使用

效果圖

BaseRecyclerViewAdapter的多佈局實現需要注意的四步:
①自定義Adapter需要繼承BaseRecyclerViewMultiItemAdapter。
② 資料實體類需要繼承BaseMultiItemEntity,在getItemViewType()返回佈局型別。
③ 在自定義Adapter中的建構函式中通過addItemType()傳入不同型別對應的佈局。
④在自定義Adapter中的convert進行型別判斷,做相對應的操作。
class MultipleAdapter(mContext: Context, mDatas: ArrayList<MultiItem>) :
BaseRecyclerViewMultiItemAdapter<MultiItem>(mContext, mDatas) {

    private var mHeight: Int=0

    init {
        mHeight = DisplayUtils.dip2px(mContext, 100f)
        addItemType(MultiItem.TYPE_TEXT, R.layout.item_main)
        addItemType(MultiItem.TYPE_IMG, R.layout.item_img)
        addItemType(MultiItem.TYPE_TEXT_IMG, R.layout.item_click)
  }

override fun convert(baseViewHolder: BaseViewHolder, t: MultiItem) {

    when (baseViewHolder.itemViewType) {
        MultiItem.TYPE_TEXT -> {
            baseViewHolder.getView<CardView>(R.id.card_view).layoutParams.height = mHeight
            baseViewHolder.setText(R.id.title, t.title)
        }
        MultiItem.TYPE_IMG -> baseViewHolder.setImageResource(R.id.ivImg, t.res)
        MultiItem.TYPE_TEXT_IMG -> {
            baseViewHolder.setImageResource(R.id.ivImg, t.res)
            baseViewHolder.setText(R.id.titleTv, t.title)
        }
    }
  }

}
複製程式碼

4.新增拖拽、滑動刪除

效果圖

侷限:只針對RecyclerView,對本框架封裝的PullToRefreshRecyclerView會出現混亂。
①BaseRecyclerViewAdapter和BaseRecyclerViewMultiItemAdapter都已經封裝支援拖拽、滑動,介面卡只需要根據需求繼承其中一個即可。
②框架提供了一個BaseRecycleItemTouchHelper,對於普通的左右滑動刪除、拖拽已經實現,如果想自定義可以繼承BaseRecycleItemTouchHelper類,再重寫相對應的方法進行實現。
④在Activity/Fragment中需要實現以下程式碼:
    dragAndDeleteAdapter?.setDragAndDeleteListener(this)
    recycler_rv.adapter = dragAndDeleteAdapter

    val callback = BaseRecycleItemTouchHelper(dragAndDeleteAdapter)
    val itemTouchHelper = ItemTouchHelper(callback)
    itemTouchHelper.attachToRecyclerView(recycler_rv)
複製程式碼
⑤BaseRecyclerViewAdapter.OnDragAndDeleteListener進行操作動作完成之後的回撥。
override fun onMoveComplete() {
    ToastUtils.showToast(this, "移動操作完成")

}

override fun onDeleteComplete() {
    ToastUtils.showToast(this, "刪除操作完成")
}
複製程式碼

四、MVP+RxJava+Retrofit的封裝使用

效果圖

1.在使用Retrofit請求網路之前需要進行配置,在框架中提供了了Config配置類

屬性 作用
DEBUG 是否為BuildConfig.DEBUG,日誌輸出需要
CONTEXT 設定Context,必填項
URL_DOMAIN 網路請求的域名,需要以“/”結尾
URL_CACHE 網路快取地址,需要設定快取才可以成功
MAX_CACHE_SECONDS 設定OkHttp的快取機制的最大快取時間,預設為一天
MAX_MEMORY_SIZE 快取最大的記憶體,預設為10M
MClASS 設定網路請求json通用解析類
EXPOSEPARAM Json資料某些欄位在沒有資料是會不返回來,可通過這個屬性設定過濾
USER_CONFIG SharePreference儲存的名稱
CONNECT_TIMEOUT_SECONDS 請求介面超時設定
READ_TIMEOUT_SECONDS 請求介面超時設定
HEADERS 設定Http全域性請求頭
SQLITE_DB_NAME 資料庫名稱
SQLITE_DB_VERSION 資料庫版本名
在專案中需要根據專案需要進行配置,在Application中設定
private fun config(){
    //基本配置
    Config.DEBUG = BuildConfig.DEBUG
    Config.CONTEXT = this
    Config.URL_CACHE = AppConfig.getURLCacheDir(this)
    Config.MClASS=HttpResult::class.java
    Config.USER_CONFIG = "Collection_User"
    Config.URL_DOMAIN = "https://api.apiopen.top/"
    Config.SQLITE_DB_VERSION=0
}
複製程式碼
根據專案需要定義一個通用的資料實體類,這是本例通用實體類,這個類需要設定到Applicatin中
class HttpResult<T> : Serializable {
  var code: Int = 0
  var message: String? = null
  var result: T? = null
}
複製程式碼
注意:由於每個專案返回來的json資料格式有所不同,如果Result中代表的欄位例如newslist沒有內容返回來的時候這個欄位需要後臺控制不返回,如果不做處理會報解析錯誤,可以通過設定Config.EXPOSEPARAM屬性過濾欄位。

2.RxJava+Retrofit+OkHttp

(1)RequestBuilder的設定(網路請求的配置)

屬性 作用
ReqType 資料處理的方式,預設DEFAULT_CACHE_LIST,使用到OkHttp快取的需要需要設定Config.URL_CACHE
NO_CACHE_MODEL 不設定快取,返回model
NO_CACHE_LIST 不設定快取,返回list
DEFAULT_CACHE_MODEL 使用Okttp預設快取,返回model
DEFAULT_CACHE_LIST 使用Okttp預設快取,返回list
DISK_CACHE_LIST_LIMIT_TIME 限時使用自定義磁碟快取,返回List
DISK_CACHE_MODEL_LIMIT_TIME 限時使用自定義磁碟快取,返回model
DISK_CACHE_NO_NETWORK_LIST 自定義磁碟快取,沒有網路返回磁碟快取,返回List
DISK_CACHE_NO_NETWORK_MODEL /自定義磁碟快取,沒有網路返回磁碟快取,返回Model
HttpType 網路請求方式,預設DEFAULT_GET
DEFAULT_GET GET請求
DEFAULT_POST POST請求
FIELDMAP_POST 如果請求URL出現中文亂碼,可選擇這個
JSON_PARAM_POST json格式請求引數
ONE_MULTIPART_POST 上傳一張圖片
MULTIPLE_MULTIPART_POST 上傳多張圖片
ReqMode 請求模式,預設ASYNCHRONOUS
ASYNCHRONOUS 非同步請求
SYNCHRONIZATION 同步請求
其它引數
setTransformClass 設定請求轉化Class
setUrl 設定請求url,如果不設定完全連線則會使用Config.URL_DOMIN進行拼接
setFilePathAndFileName 設定自定義快取時的路徑和檔名
setLimtHours 設定自定義快取的有效時間
setHeader 設定請求頭
setHeaders 設定請求頭集合
setHttpTypeAndReqType 設定請求資料型別和請求方式
setImagePath 設定上傳圖片路徑
setImagePaths 設定多張圖片路徑
isUserCommonClass 設定是否使用公用類轉化
setReqMode 設定同步非同步

(2)使用模組

     val requestBuilder=RequestBuilder(object :RxObservableListener<HttpResult<List<WeChatNews>>>(mView){
        override fun onNext(result: HttpResult<List<WeChatNews>>) {
            mView?.refreshUI(result.result)
        }
    })

    requestBuilder
        .setUrl(ApiUrl.URL_WETCHAT_FEATURED)
        .setTransformClass(WeChatNews().javaClass)
        .setHttpTypeAndReqType(RequestBuilder.HttpType.DEFAULT_GET,RequestBuilder.ReqType.NO_CACHE_LIST)
        .setParam("page",page)
        .setParam("type","video")
        .setParam("count",num)

    rxManager.addObserver(DataManager.DataForHttp.httpRequest(requestBuilder))
複製程式碼
注意:
(1)RxObservableListener有三個回撥方法
void onNext(T result);
void onComplete();
void onError(NetWorkCodeException.ResponseThrowable e);
複製程式碼
只會重寫onNext方法,其它兩個方法可以自行選擇重寫。
(2)RxObservableListener提供兩個建構函式
protected RxObservableListener(BaseView view){
    this.mView = view;
}

protected RxObservableListener(BaseView view, String errorMsg){
     this.mView = view;
     this.mErrorMsg = errorMsg;
}
複製程式碼
這兩個建構函式主要主要是為了統一處理onError的,如果要自定義錯誤提醒,則可以選擇第二個建構函式。
(3)通過DataManager的網路請求方式會返回來一個DisposableObserver,需要把它通過rxManager.addObserver()新增進CompositeDisposable才能正常執行,方便對網路請求的銷燬管理。
(4)如果專案沒有統一的解析been類,那麼Config的公用類就不用設定了,在Retrofit請求的時候直接setTransformClass指定一個解析類就可以了
(5)如果專案想兩種方式共存,那麼在請求的時候需要通過setUserCommonClass(false)設定才能不使用統一解析類進行解析

3.MVP

1.寫一個Contract類對Presenter和View進行統一管理(View需要實現BaseView,Presenter需要實現BasePresenter<T:BaseView>)

interface WeChatChinaNewsContract {
  interface View : BaseView {
    fun refreshUI(weChatNews: List<WeChatNews>?)
  }

  abstract class Presenter : BasePresenter<View>() {
      abstract fun requestChinaNews(context: Context, page: Int, num: Int)
  }
}
複製程式碼

2.寫一個具體的Presenter類實現WeChatChinaNewsContract.Presenter,在裡面做具體的邏輯處理,處理完成再通過mView進行View的處理

3.Activity/Fragment實現IBaseActivity<T:BasePresenter>/IBaseFragment<T:BasePresenter>以及定義好的WeChatChinaNewsContract.View

4.缺陷:View在使用時需要轉化成在具體的子類才能呼叫相關方法。

5.具體使用可以參照demo

五、DataManager的使用(Http、Sharepreference、SQLite)

效果圖

(1)DataManager基本屬性

屬性 作用
DataForSqlite 資料庫模組
insert 插入bean資料
insertList 插入List資料
insertListBySync 非同步插入List資料
queryByFirstByWhere 根據條件查詢
queryAll 查詢某個bean類的全部資料
queryAllBySync 非同步查詢某個bean類的全部資料
queryByFirst 查詢某個bean類的第一條資料
delete 根據條件刪除資料
deleteAll 刪除某個bean類的所有資料
deleteTable 刪除資料表
update 更新某個bean類的
queryOfPageByWhere 根據條件分頁查詢,實體類必須包含PrimaryKey
queryOfPage 分頁查詢,實體類必須包含PrimaryKey
updateTable 更新資料表,用於增加欄位
execQuerySQL Sql語句查詢
DataForHttp Http模組
httpRequest 網路請求,傳入RequestBuilder
DataForSharePreferences SharePreference模組
saveObject 儲存基本型別資料
getObject 獲取基本型別資料

(2)DataForSqlite

1.插入一條資料

 var user= User()
  user.id=0
  user.age=24
  user.name="張三"
  var isSuccess=DataManager.DataForSqlite.insert(user)
  if(isSuccess!!){
     ToastUtils.showToast(activity,"儲存成功")
   }else{
     ToastUtils.showToast(activity,"儲存失敗")
   }
複製程式碼

2.查詢資料

val user=DataManager.DataForSqlite.queryByFirst(User().javaClass)
ToastUtils.showToast(activity,"姓名:"+user?.name+"  "+"年齡:"+user?.age)
複製程式碼

3.批量插入資料(可同步可非同步)

var list=ArrayList<User>()
for (i in 0..10000){
     var user= User()
     user.id=i
     user.age=i
     user.name="張$i"
     list.add(user)
 }

 DataManager.DataForSqlite.insertListBySync(User().javaClass,list,object :SQLiteDataBase.InsertDataCompleteListener{
    override fun onInsertDataComplete(isInsert: Boolean?) {
         if(isInsert!!){
               ToastUtils.showToast(activity,"儲存成功")
          }else{
              ToastUtils.showToast(activity,"儲存失敗")
          }
      }
  })
複製程式碼

4.bean類的定義

class User{
  @Column(isPrimaryKey = true)
  var id:Int=0
  var name:String?="你好"
  var age:Int?=0
}
複製程式碼

其中可以通過Column進行註解定義(isPrimaryKey、isNull、isUnique)

5.資料表格變化(只支援增加欄位)

  • 修改資料庫版本號Config.SQLITE_DB_VERSION,往上遞增

  • 在Application中對版本號進行監聽,並對資料表進行更新

    SQLiteVersionMigrate().setMigrateListener(object :SQLiteVersionMigrate.MigrateListener{ override fun onMigrate(oldVersion: Int, newVersion: Int) { for (i in oldVersion..newVersion){ if(i==2){ }

              }
          }
    
    })
    複製程式碼

(3)DataForHttp

val requestBuilder=RequestBuilder(object :RxObservableListener<HttpResult<List<WeChatNews>>>(mView){
        override fun onNext(result: HttpResult<List<WeChatNews>>) {
            mView?.refreshUI(result.result)
        }
 })

requestBuilder
        .setUrl(ApiUrl.URL_WETCHAT_FEATURED)
        .setTransformClass(WeChatNews().javaClass)
        .setHttpTypeAndReqType(RequestBuilder.HttpType.DEFAULT_GET,RequestBuilder.ReqType.NO_CACHE_LIST)
        .setParam("page",page)
        .setParam("type","video")
        .setParam("count",num)

rxManager.addObserver(DataManager.DataForHttp.httpRequest(requestBuilder))
複製程式碼

(4)DataForSharePreferences

1.插入基本資料

DataManager.DataForSharePreferences.saveObject("user","這是一條測試的內容")
ToastUtils.showToast(activity,"儲存成功")
複製程式碼

2.查詢基本型別資料

val con=DataManager.DataForSharePreferences.getObject("user","")
ToastUtils.showToast(activity,con!!)
複製程式碼

六.Base的使用

1.為了方便Activity/Fragment設定頂部選單欄,繼承IBaseActivity/IBaseFragment即可顯示一個簡單的頂部選單,IBaseFragment的頂部選單預設隱藏,下面以IBaseActivity的頂部選單作為例子
屬性 作用
isShowSystemActionBar 重寫該方法設定實現顯示系統ActionBar
isShowCustomActionBar 重寫該方法設定顯示自定義Bar
setCustomActionBar 重寫該方法設定自定義Bar
  • 如果使用預設自定義Bar可通過DefaultDefineActionBarConfig進行相關設定
屬性 作用
hideBackBtn 隱藏返回按鈕
setBarBackgroundColor 設定Bar的背景顏色
setBarHeight 設定Bar的高度
setTitleColor 設定標題顏色
setTitle 設定標題
setBackClick 設定返回按鈕監聽
  • 程式碼使用

    defineActionBarConfig .setTitleSize(20f) .setBarHeight(DisplayUtils.dip2px(this,60f)) .setBarBackgroundColor(this,R.color.driver_font) .setTitle(getString(R.string.tab_Indicator_title))

2.StateView(資料載入頁面)

效果圖

屬性 作用
STATE_NO_DATA 不顯示載入框狀態碼
STATE_LOADING 載入資料顯示狀態碼
STATE_EMPTY 沒有資料顯示狀態碼
STATE_DISCONNECT 沒有網路狀態碼
setOnDisConnectViewListener 點選沒有網路圖示回撥
setOnEmptyViewListener 點選沒有沒有資料圖示回撥
showViewByState 設定顯示狀態
getmEmptyView 獲取無資料狀態View
佈局可設定引數
loadingViewAnimation 設定載入的drawable動畫
loadingText 載入時的文字
emptyImage 空佈局顯示的圖片
emptyText 空佈局文字
emptyViewRes 設定自定義空佈局
disConnectImage 設定斷網顯示的圖片
disConnectText 設定斷網顯示的文字
tipTextSize 文字字型大小
tipTextColor 文字字型顏色
(1)定義一個通用佈局
<com.youngmanster.collection_kotlin.base.stateview.StateView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:id="@+id/state_view">

</com.youngmanster.collection_kotlin.base.stateview.StateView >
複製程式碼
(2)新增到Ui頁面的layout中
<include layout="@layout/layout_state"/>
複製程式碼
注意:上面的語句新增的layout最外層最好是LinearLayout以及設定為android:orientation="vertical"
(3)通過以下語句進行狀態切換
stateView.showViewByState(StateView.STATE_LOADING)
stateView.showViewByState(StateView.STATE_EMPTY)
stateView.showViewByState(StateView.STATE_NO_DATA)
stateView.showViewByState(StateView.STATE_DISCONNECT)
複製程式碼

3.三步實現Permission(許可權)設定

效果圖

(1)設定好要請求的許可權
// 專案的必須許可權,沒有這些許可權會影響專案的正常執行
private val PERMISSIONS = arrayOf(
    Manifest.permission.READ_SMS,
    Manifest.permission.RECEIVE_WAP_PUSH,
    Manifest.permission.READ_CONTACTS
)
複製程式碼
(2)許可權通過PermissionManager管理
 permissionManager = PermissionManager
    .with(this)
    .setNecessaryPermissions(PERMISSIONS)

permissionManager?.requestPermissions()
複製程式碼
(3)頁面重寫onRequestPermissionsResult
//重寫
override fun onRequestPermissionsResult(requestCode: Int, @NonNull permissions: Array<String>, @NonNull grantResults: IntArray) {
    if (requestCode == PermissionManager.PERMISSION_REQUEST_CODE) {//PERMISSION_REQUEST_CODE為請求許可權的請求值
        //有必須許可權選擇了禁止
        if (permissionManager?.shouldShowRequestPermissionsCode == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED) {
            ToastUtils.showToast(this, "可以在這裡設定重新跳出許可權請求提示框")
        } //有必須許可權選擇了禁止不提醒
        else if (permissionManager?.shouldShowRequestPermissionsCode == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND) {
            ToastUtils.showToast(this, "可以在這裡彈出提示框提示去應用設定頁開啟許可權")
            permissionManager?.startAppSettings()
        }
    }
}
複製程式碼
注意:如果有需求先判斷是否所有許可權都已經允許之後再進入主頁面可以通過permissionManager.isLackPermission()進行判斷,如果返回true則進行許可權請求,如果返回false則進入主頁面。
  • 多個許可權請求如果其中某一個被禁止提醒,會先把沒有禁止提醒的許可權處理完之後再進行處理。
  • 如果是必要許可權被禁止而沒有選擇禁止提醒退出之後下次會重新請求許可權。
  • 如果必要許可權被禁止和選擇了禁止提醒重新進入頁面在onRequestPermissionsResult會重新回撥方法。
  • 使用者可以根據onRequestPermissionsResult()方法中返回來的標誌PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED和PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND做出對應的顯示和操作(例如彈框提示跳轉到設定頁面或者toat提示)。

4.提供幾種比較常用的Dialog彈框

效果圖

(1)提供的常用的CommonDialog
屬性 作用
DIALOG_TEXT_TWO_BUTTON_DEFAULT 預設彈出按鈕提示
DIALOG_TEXT_TWO_BUTTON_CUSTOMIZE 自定義彈出按鈕提示
DIALOG_LOADING_PROGRASSBAR 預設載入彈框
DIALOG_CHOICE_ITEM 沒有資料顯示狀態碼

根據不同的建構函式設定不同的引數

(2)自定義Dialog樣式
  • BaseDialog
屬性 作用
setContentView 設定彈框佈局樣式
show 顯示彈框
isShowing 判斷彈框是否顯示
dismiss 彈框銷燬
setCancelable 點選返回鍵和外部是否可以取消
setOnBackPressDialogCancel 設定為false時,點選彈框外部不可消失,點選返回按鈕可以消失
setDialogInterval 設定彈框和螢幕兩邊的間距
setDialogHeight 設定彈框高度
  • 繼承BaseDialog,通過setContentView(R.layout.dialog_list)設定彈窗佈局。
  • 在提供的onViewCreated方法中進行相應的邏輯設定

5.自定義PopupWindow彈框

效果圖

  • BasePopupWindow
屬性 作用
BasePopupWindow(Context context) 呼叫該建構函式預設彈出框鋪滿全屏
BasePopupWindow(Context context, int w, int h) 自定義彈出框高寬
showPopup 在螢幕中央顯示彈框
showPopupAsDropDown 在指定控制元件底部顯示彈框
showPopup 在螢幕中央顯示彈框
showPopupAsDropDown 在指定控制元件底部顯示彈框
setShowMaskView 設定是否顯示遮層
dismiss 銷燬彈出框
getPopupLayoutRes 自定義彈出框的佈局檔案
getPopupAnimationStyleRes 自定義彈出框的動畫檔案,不設定動畫返回0
  • 繼承BasePopupWindow。
  • 通過getPopupLayoutRes(R.layout.xxx)設定彈窗佈局。
  • 通過getPopupAnimationStyleRes(R.style.xxx)設定彈窗動畫,不需要動畫可以設定為0。
  • 如果需要顯示遮層,在建構函式通過setShowMaskView(true)設定。

七、CustomView的使用

1.CommonTabLayout的使用

效果圖

屬性 作用
tab_tabIndicatorWidth 設定下滑線的長度
tab_tabIndicatorHeight 設定下滑線的高度
tab_tabIndicatorColor 下滑線顏色
tab_indicator_marginLeft 設定下滑線外邊距
tab_indicator_marginRight 設定下滑線外邊距
tab_indicator_marginTop 設定下滑線外邊距
tab_indicator_marginBottom 設定下滑線外邊距
tab_tabTextColor 沒選中字型顏色
tab_tabTextSize 字型大小
tab_tabSelectedTextColor 選中字型顏色
tab_padding 下滑線內邊距,block樣式時可以通過該屬性設定距離
tab_tabBackground Tab 的背景顏色
tab_indicator_corner 下滑線的圓角大小
tab_indicator_gravity(bottom、top 設定下滑線顯示的位置,只針對line和triangle
tab_tabMode(scrollable、fixed) Tab的顯示模式
tab_indicator_style(line、triangle、block) 下滑線的樣式
具體可參照例子使用。

2.OutSideFrameTabLayout的使用

效果圖

屬性 作用
tab_tabIndicatorColor 設定Tab顏色
tab_indicator_corner 圓角大小
tab_indicator_marginLeft 下滑線外邊距
tab_indicator_marginRight 下滑線外邊距
tab_indicator_marginTop 下滑線外邊距
tab_indicator_marginBottom 下滑線外邊距
tab_tabTextColor 沒選中字型顏色
tab_tabSelectedTextColor 選中字型顏色
tab_tabTextSize 字型大小
tab_tabSelectedTextColor 選中字型顏色
tab_padding 內邊距
tab_bar_color bar的背景顏色
tab_bar_stroke_color 外框的顏色
tab_bar_stroke_width 外框的大小
tab_width bar的長度
具體可參照例子使用。

3.AutoLineLayout的使用

效果圖

  • 在外層佈局使用AutoLineLayout

    <com.youngmanster.collection_kotlin.base.customview.wraplayout.AutoLineLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
    
    </com.youngmanster.collection_kotlin.base.customview.wraplayout.AutoLineLayout>
    複製程式碼

4.TagView的使用

效果圖

TagViewConfigBuilder
屬性 作用
setTitles 設定TagItem內容
setTextSize 設定TagItem字型大小
setTextColor 設定TagItem字型顏色
setTextSelectColor 設定TagItem選擇字型顏色
setPaddingLeftAndRight 設定TagIttem左右內邊距
setPaddingTopAndBottom 設定TagIttem上下內邊距
setMarginAndTopBottom 設定TagItem上下外邊距
setMarginLeftAndRight 設定TagItem左右外邊距
setackgroudRes 設定background Drawable
setTagViewAlign 設定整體TagItem的Align(LEFT,RIGHT,CENTER)
1.佈局
<com.youngmanster.collection_kotlin.base.customview.tagview.TagView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tagView" />
複製程式碼
2.程式碼設定
tagView.create(builder,object :TagView.TagViewPressListener{
        override fun onPress(view: View, title: String, position: Int) {
            ToastUtils.showToast(this@TagViewActivity,title)
        }
 })
複製程式碼

八、工具類的使用

1.Density(適配不同手機畫素)
  • 在Applicaton的onCreate中設定 Density.setDensity(this, 375f)
  • 375f代表設計稿的寬度,以dp為單位,後面需要以f(浮點型)
2.DisplayUtils

效果圖

屬性 作用
px2dip px值轉換為dip或dp值,保證尺寸大小不變(有精度損失)
px2dipByFloat px值轉換為dip或dp值,保證尺寸大小不變(無精度損失
dip2px dip或dp值轉換為px值,保證尺寸大小不變(有精度損失),類似Context.getDimensionPixelSize方法(四捨五入
dip2pxByFloat dip或dp值轉換為px值,保證尺寸大小不變(無精度損失),類似Context.getDimension方法
px2sp px值轉換為sp值,保證文字大小不變
sp2px sp值轉換為px值,保證文字大小不變
getScreenWidthPixels 螢幕寬度
getScreenHeightPixels 螢幕高度
getDisplayInfo 獲取裝置資訊
setStatusBarBlackFontBgColor 設定黑色字型狀態的背景顏色
setStatusBarColor 設定狀態列背景顏色
setStatusBarFullTranslucent 設定狀態列透明
getStatusBarHeight 獲取狀態列高度
getActionBarHeight 獲取ActionBar高度
3.ColorUtils
屬性 作用
createColorStateList 獲取ColorStateList
4.FileUtils
屬性 作用
WriterTxtFile 寫檔案,其中append可設定是否新增在原內容的後邊
ReadTxtFile 讀取文字檔案中的內容,strFilePath代表檔案詳細路徑
isCacheDataFailure 判斷快取是否失效
checkFileExists 檢查檔案是否存在
checkSaveLocationExists 檢查是否安裝SD卡
deleteDirectory 刪除目錄(包括:目錄裡的所有檔案)
deleteFile 刪除檔案
getFileOrFilesSize 獲取檔案指定檔案的指定單位的大小,其中sizeType 獲取大小的型別1為B、2為KB、3為MB、4為GB
getFileSize 獲取指定檔案大小
5.GetPermissionsUtils
屬性 作用
getAllPermissons 獲取應用用到的所有許可權
6.GlideUtils
屬性 作用
loadImg 載入圖片
loadImgBlur Glide實現高斯模糊
loadImgBlur Glide實現高斯模糊,可設定模糊的程度
7.ThreadPoolManager:執行緒池管理類
8.LogUtils:日記工具類
9.NetworkUtils:網路工具類
10.SoftInputUtils:鍵盤工具類
11.ToastUtils:Toast工具類
12.RxJavaUtil:主/子執行緒的切換

本文章會根據需要持續更新,建議點贊收藏,便於檢視。也歡迎大家提出更多建議。

Android開發框架Collection-kotlin(更新篇)

相關文章