Collection aggregates some basic modules of project construction to save developers’ time and assist the rapid construction of projects. RecyclerView+Adapter+Retrofit+RxJava+MVP+DataManager+ basic Base can meet the basic realization of a project.

Recommended file

Previous versions of the Android X library are available using collection-Android: juejin.cn/post/684490…

The Collection – iOS library: juejin. Cn/post / 684490…

Collection-kotlin, as an update to Collection-Android, aims to solve some of the problems caused by using Android X libraries and module optimization

Making address:Github.com/usernameyan…
Letter Address:www.jianshu.com/p/a6cb49532…

Updated instructions

v1.7.5

1. Upload and download Added progress bar 2.Fragment Added layout and data initialization lazy loading 3

v1.5.3

1. Replace AlertDialog with DialogFragment. 2. Increase the fragments of jump 4. DataManager. DataForHttp increase file downloads

v1.1.0

2. Add conditional query List 3 to SQLite. Add PopupWindow display position 4. Troubleshoot an error when SQLit content is null

v1.0.1

Status bar modification: Added setting status bar transparent + black font

v1.0.0

1. Adapt Android X library 2 based on Collection-Android. Remove Relam data module, reduce the size of the installation package 3. Encapsulate the native SQLite database, making it more convenient to use 4. Update DataManager usage 5. Add AutoLineLayout/TagView 6. Add LinkedMultiValueMap 7. Add RxJavaUtils to switch data processing between subthreads and mainthreads

Introduction of frameworks

Implementation ‘com. Youngman: collection_kotlin: 1.7.5’

First, the overall framework module

Second, the use of PullToRefreshRecyclerView

attribute role
addHeaderView Add header layout. For now, only one header layout can be added
setEmptyView Set custom load layouts and empty layouts
setRefreshView Customize refresh View
setDefaultLoadingMoreNoDataMessage Set content that has no data by default
setLoadMoreView Customize loading more views
setNoMoreDate It shows no more data
setAutoRefresh Automatically refresh
refreshComplete Refreshing data completed
loadMoreComplete Loading more data is complete
setPullRefreshEnabled Whether refresh is allowed
setLoadMoreEnabled Whether to allow more loading
setRefreshTimeVisible The update loading time is displayed
isLoading Whether data is loading
isRefreshing Ongoing refreshing data
setRefreshAndLoadMoreListener Refresh and load more callbacks
destroy Memory recovery

1. The framework defaults to pull-down refresh and pull-up loading with more style

(1) Layout file
 <com.youngmanster.collection_kotlin.recyclerview.PullToRefreshRecyclerView
	android:id="@+id/recycler_rv"
	android:layout_width="match_parent"
	android:layout_height="match_parent" />
Copy the code
(2) Code setting
 recycler_rv.setPullRefreshEnabled(true)
 recycler_rv.setLoadMoreEnabled(true)
Copy the code

2, custom pull refresh, pull up loading more style

Refresh several states:
attribute role
STATE_PULL_DOWN The state of being pulled (before being pulled to a fixed height)
STATE_RELEASE_REFRESH Drop down to a fixed height to release the refreshed state
STATE_REFRESHING Flushing state
STATE_DONE Refresh to complete
Load several more states:
attribute role
STATE_LOADING Being loaded
STATE_COMPLETE Add load to complete
STATE_NODATA There is no data
(1) Code setting
recycler_rv.setPullRefreshEnabled(true)
recycler_rv.setLoadMoreEnabled(true)
recycler_rv.setRefreshAndLoadMoreListener(this)
recycler_rv.setRefreshView(DefinitionAnimationRefreshHeaderView(activity))
recycler_rv.setLoadMoreView(DefinitionAnimationLoadMoreView(activity))
Copy the code
Steps for customizing the refresh:
InitView () setRefreshTimeVisible(Boolean show) destroy();

1. Initialize the custom layout and related animation in initView(), and finally add the following code to the end of 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
Copy the code

2. SetRefreshTimeVisible (Boolean show) is used to set whether the display refresh time controls, in the style of a default refresh by mRecyclerView. SetRefreshTimeVisible (false) can hide the refresh time, This method can be ignored if it is not present in a custom layout.

3. Destroy () is used to close the page and release some animation such as refresh View to prevent memory leaks.

(2) implement BasePullToRefreshView. OnStateChangeListener monitoring (key, is mainly the related operations after state switch logic)

1. Set onStateChangeListener=this in the constructor. 2

override fun onStateChange(state: Int) {if(isDestroy){return} // If (state == mState) return // Animate when (state) { STATE_PULL_DOWN -> { clearAnim() startAnim() } STATE_RELEASE_REFRESH -> { } STATE_REFRESHING -> { clearAnim() startAnim() scrollTo(mMeasuredHeight) } STATE_DONE -> { } } mState = state }Copy the code
Custom load more steps (including operations without more data to display) :
InitView (), setState(), destroy()

1. Initialize the custom layout and related animation in initView(), and finally add the following code to the end of initView()

    mContainer = LayoutInflater.from(context)
        .inflate(R.layout.layout_definition_animation_loading_more, null)
    addView(mContainer)
    gravity = Gravity.CENTER
Copy the code

2. Destroy () is used to close the page and release some animation that refreshes the View to prevent memory leaks. 3. Related operation logic after state switch in setState(), template style

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 }Copy the code

4. Note: for more style of custom loading, if you need to have more loading and more data hints, you also need to write them in the layout, and then show and hide them in onSatae according to the state of loading and no more display hints.

3. More pull-up loading with SwipeRefreshLayout

(1) Layout file
<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>
Copy the code
(2) Code setting
recycler_rv.setLoadMoreEnabled(true)
recycler_rv.setRefreshAndLoadMoreListener(this)
recycler_rv.setLoadMoreView(DefinitionAnimationLoadMoreView(activity))
swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent)
swipeRefreshLayout.setOnRefreshListener(this)
Copy the code
(3) The problem of attention

Because of PullToRefreshRecyclerView drop-down refresh and drop-down load more complete automatically refresh the Adapter, and SwipeRefreshLayout need to manually refresh the completed notifyDataSetChanged refreshes the Adapter.

4, RecyclerView add head, empty layout

(1) Code setting
// Add the header layout val header = layoutinflater.from (activity).inflate(r.layout.layout_main_header, Null) recycler_rv. AddHeaderView (header) // Add an empty layout 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() }Copy the code

5, pull up load more implementation of NoMoreData, automatic refresh

LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadingMoreView: LoadMore
mRecyclerView.setNoMoreDate(true)
Copy the code
(2) Automatic refresh takes effect only after the list has been filled with data:
mRecyclerView.setAutoRefresh()
Copy the code

6. The refresh loading text of the Collection library has been adapted to Chinese, English and traditional characters. If the default refresh loading display text is modified, the LoadingTextConfig setting can be set globally in Application

Val textConfig = LoadingTextConfig. GetInstance (applicationContext) textConfig. SetCollectionLoadingMore (" load more ") SetCollectionLastRefreshTimeTip (" update time: "). SetCollectionNoMoreData (" no more data "). SetCollectionPullReleaseText (" release refresh "). SetCollectionRefreshing (" setting ") SetCollectionPullDownRefreshText (" drop-down refresh ") setCollectionRefreshDone (" loaded ") PullToRefreshRecyclerViewUtils.loadingTextConfig = textConfigCopy the code

7, PullToRefreshRecyclerView other use, and pay attention to the problem

1. Here are some action templates for pull-down refresh and pull-up load more

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() } } } }Copy the code

2. Pay attention to problems

① In the setting of RecyclerView is to set LayoutManager
(2) if you use PullToRefreshRecyclerView Activty/fragments in the onDestroy () call mRecyclerView. Destroy () to prevent a memory leak.
@Override public void onDestroy() { super.onDestroy(); mRecyclerView? .destroy() }Copy the code
. (3) set refreshRv setLoadMoreEnabled (true), when filling the list of data size is zero at the same time also by RecyclerView Settings will appear at the bottom of the line a blank item, this item is loaded more display item.
Solution: do not set up a RecyclerView sectionline, directly in the layout custom sectionline.

BaseRecyclerViewAdapter

1. BaseRecyclerViewAdapter reduce the amount of code than the original Adapter

The BaseViewHolder in the BaseRecyclerViewAdapter performs layout transformation and defines some basic View operations that are simple to use.

(1) Use code:
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)
    }
}
Copy the code
① The user needs to pass in a data entity type when inheriting the BaseRecyclerViewAdapter in the convert() method.
(2) BaseViewHolder provides some basic operations for common views. You can use BaseViewholder.getView () to get controls in the layout.
(2) BaseRecyclerViewAdapter provides two constructors
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;
}
Copy the code
Mainly for PullToRefreshRecyclerView and RecyclerView adaptation, when using the adapter according to the need to use the corresponding constructor.

2. Add click and hold events for Item

(1) Item is implemented by long press event
itemClickAdapter.setOnItemLongClickListener(object : BaseRecyclerViewAdapter.onItemLongClickListener { override fun onItemLongClick(view: View, position: Int): Boolean {showToast(" long press ") return true}})Copy the code

3. Use of multiple layouts

BaseRecyclerViewAdapter multiple layout implementation needs to note the four steps:
1) custom Adapter need BaseRecyclerViewMultiItemAdapter inheritance.
The data entity class needs to inherit from BaseMultiItemEntity and return the layout type in getItemViewType().
③ In the constructor of the custom Adapter, pass in addItemType() for the layout of different types.
④ Determine the type of convert in the customized Adapter and perform the corresponding operation.
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)
        }
    }
  }

}
Copy the code

4. Add, drag, and slide to delete

Limitations: only for RecyclerView, this frame encapsulation PullToRefreshRecyclerView will be chaos.
1) BaseRecyclerViewAdapter and BaseRecyclerViewMultiItemAdapter are encapsulated support drag and drop, sliding, adapter you just need to inherit one based on the requirements.
(2) framework provides a BaseRecycleItemTouchHelper, sliding around for ordinary delete, drag and drop is implemented, if you want to custom can inherit BaseRecycleItemTouchHelper class, then rewrite the corresponding methods for implementation.
④ Implement the following code in the Activity/Fragment:
dragAndDeleteAdapter? .setDragAndDeleteListener(this) recycler_rv.adapter = dragAndDeleteAdapter val callback = BaseRecycleItemTouchHelper(dragAndDeleteAdapter) val itemTouchHelper = ItemTouchHelper(callback) itemTouchHelper.attachToRecyclerView(recycler_rv)Copy the code
(5) BaseRecyclerViewAdapter. OnDragAndDeleteListener callback operating action is completed.
override fun onMoveComplete() { ToastUtils.showToast(this, Override fun onDeleteComplete() {toastutils.showtoast (this, "delete fun onDeleteComplete ")}Copy the code

MVP+RxJava+Retrofit packaging use

1. Configuration is required before using Retrofit to request a network. The Config configuration class is provided in the framework

attribute role
DEBUG Whether it is buildconfig.debug, required for log output
CONTEXT Setting Context is mandatory
URL_DOMAIN The domain name requested by the network must end with a slash (/)
URL_CACHE Network cache address, need to set the cache to succeed
MAX_CACHE_SECONDS Set the maximum cache time for OkHttp. The default is one day
MAX_MEMORY_SIZE Maximum cache memory, default is 10 MB
MClASS Set the network request JSON generic parsing class
EXPOSEPARAM Json data Some fields will not be returned without data, can be filtered through this property setting
USER_CONFIG SharePreference Specifies the saved name
CONNECT_TIMEOUT_SECONDS Request interface timeout setting
READ_TIMEOUT_SECONDS Request interface timeout setting
HEADERS Sets the Http global request header
SQLITE_DB_NAME Database name
SQLITE_DB_VERSION Database version name
It needs to be configured in the project according to the needs of the project and set in the Application
Private fun config(){// Basic 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 }Copy the code
Define a generic data entity class based on your project needs. This is the generic entity class for this example that needs to be set up in Applicatin
class HttpResult<T> : Serializable {
  var code: Int = 0
  var message: String? = null
  var result: T? = null
}
Copy the code
Note: Because the json data format returned by each item is different, if the field represented by Result such as newslist is returned with no content, it needs to be controlled by the background not to be returned. Otherwise, parsing errors will be reported. You can filter the field by setting the config. EXPOSEPARAM attribute.

2.RxJava+Retrofit+OkHttp

(1) Setup of RequestBuilder (network request configuration)

attribute role
ReqType The way data is handled, DEFAULT_CACHE_LIST, is set to config.url_cache if the OkHttp cache is used
NO_CACHE_MODEL Return Model without setting cache
NO_CACHE_LIST Return list without setting cache
DEFAULT_CACHE_MODEL Using the Okttp default cache, return model
DEFAULT_CACHE_LIST Using the Okttp default cache, return the list
DISK_CACHE_LIST_LIMIT_TIME Use custom disk cache for limited time, return List
DISK_CACHE_MODEL_LIMIT_TIME Use custom disk cache for limited time, return Model
DISK_CACHE_NO_NETWORK_LIST Custom disk cache, no network return disk cache, return List
DISK_CACHE_NO_NETWORK_MODEL / Custom disk cache, no network return disk cache, return Model
DOWNLOAD_FILE_MODEL File download mode, return to Model
HttpType Network request, DEFAULT_GET by default
DEFAULT_GET A GET request
DEFAULT_POST A POST request
FIELDMAP_POST Select this option if Chinese garbled characters appear in the requested URL
JSON_PARAM_POST Request parameters in JSON format
MULTIPLE_MULTIPART_POST Uploading Multiple Files
DOWNLOAD_FILE_GET The download file
ReqMode Request mode, default ASYNCHRONOUS
ASYNCHRONOUS An asynchronous request
SYNCHRONIZATION A synchronous request
Other parameters
setTransformClass Set the request conversion Class
setUrl Set the request URL. If full connection is not set, config.url_domin is used for concatenation
setFilePathAndFileName Set the path and file name for the custom cache
setLimtHours Set the validity period of the custom cache
setHeader Set the request header
setHeaders Sets the request header collection
setHttpTypeAndReqType Sets the request data type and request mode
setFilePaths Set multiple file paths
isUserCommonClass Sets whether to use public class conversions
setReqMode Setting Asynchronous Synchronization

(2) Use modules

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))Copy the code
Note:
RxObservableListener has four callback methods
 fun onNext(T result);
 fun onError(NetWorkCodeException.ResponseThrowable e);
 fun onDownloadProgress(total:Long,progress:Float)
 fun onUploadProgress(total: Long, progress: Float)
Copy the code
Only the onNext method is overridden; the other two methods are optional.
(2) RxObservableListener provides two constructors
protected RxObservableListener(BaseView view){
    this.mView = view;
}

protected RxObservableListener(BaseView view, String errorMsg){
     this.mView = view;
     this.mErrorMsg = errorMsg;
}
Copy the code
These two constructors are primarily designed to handle onError in a unified manner, and if you want to customize error alerts, you can choose the second constructor.
(3) A DisposableObserver will be returned to the Network request via DataManager, which must be added to the CompositeDisposable via rxManager.addobServer () to facilitate the destruction management of network requests.
(4) If the project does not have a uniform resolution of the Been class, then the common class of Config is not set, and a resolution class is specified directly by setTransformClass when a Retrofit request is made
(5) If the project wants both methods to coexist, the request will need to be set to setUserCommonClass (false) to resolve without using the uniform resolution class

3.MVP

<T:BaseView> <T:BaseView> <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)
  }
}
Copy the code

2. Write a concrete Presenter class implements WeChatChinaNewsContract. The Presenter, inside do specific logic processing, processing is completed through the mView again the processing of the View

3. The Activity/fragments IBaseActivity < T: BasePresenter > / IBaseFragment < T: BasePresenter > and defined WeChatChinaNewsContract. View

4. Drawback: The View needs to be converted to a specific subclass before it can call the related method.

5. For specific use, please refer to Demo

5. Use DataManager (Http, Sharepreference, SQLite)

(1) DataManager basic attributes

attribute role
DataForSqlite Database module
insert Insert bean data
insertList Insert List data
insertListBySync Insert List data asynchronously
queryByFirstByWhere Query by condition
queryAll Query all data for a bean class
queryAllBySync Asynchronously query all data for a bean class
queryByFirst Query the first data of a bean class
delete Delete data based on conditions
deleteAll Delete all data for a bean class
deleteTable Delete table
update Update of a bean class
queryOfPageByWhere Based on conditional paging queries, the entity class must contain PrimaryKey
queryOfPage Paging query, entity class must contain PrimaryKey
updateTable Update the data table to add fields
execQuerySQL Sql statement query
DataForHttp The Http module
httpRequest Network request, passed in to the RequestBuilder
DataForSharePreferences SharePreference module
saveObject Save basic type data
getObject Get basic type data

(2) DataForSqlite

1. Insert a data entry

Var user = user (). The user id = 0 user. Age = 24. The user name = "* *" var isSuccess = DataManager. DataForSqlite. Insert (user) if (isSuccess! !). ToastUtils. ShowToast (activity," save successfully ") else{ToastUtils. ShowToast (activity," save successfully ")}Copy the code

2. Query data

Val user = DataManager. DataForSqlite. QueryByFirst (user (). The javaClass) ToastUtils. ShowToast (activity, "name:" + user? .name+" "+" age: "+user?.age)Copy the code

3. Batch insert data (synchronous or asynchronous)

var list=ArrayList<User>() for (i in 0.. 100){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!!) Else {ToastUtils. ShowToast (activity," save successfully ")}}})Copy the code

4. Definition of the bean class

class User{ @Column(isPrimaryKey = true) var id:Int=0 var name:String? Var age:Int? = 0}Copy the code

Where annotations can be defined by Column (isPrimaryKey, isNull, isUnique)

5. Data table changes (only support to add fields)

  • Change the database version number config. SQLITE_DB_VERSION and increment it upward

  • Listen for the version number in the Application and update the data table

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

    }}})Copy the code

(3) the 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))Copy the code

(4) DataForSharePreferences

1. Insert basic data

DataManager. DataForSharePreferences. SaveObject (" user ", "this is a test of content") ToastUtils. ShowToast (activity, "successfully saved")Copy the code

2. Query basic type data

val con=DataManager.DataForSharePreferences.getObject("user","")
ToastUtils.showToast(activity,con!!)
Copy the code

The use of Base

1. In order to facilitate the Activity/fragments set the top menu bar, inherit IBaseActivity/IBaseFragment can display a simple at the top of the menu, IBaseFragment hidden by default, the top of the menu The top menu of IBaseActivity is used as an example
attribute role
isShowSystemActionBar Override this method to set up the display system ActionBar
isShowCustomActionBar Override this method to set the display of custom bars
setCustomActionBar Override this method to set custom bars
  • If you use the default custom Bar can be related by DefaultDefineActionBarConfig Settings
attribute role
hideBackBtn Hide the back button
setBarBackgroundColor Sets the background color of Bar
setBarHeight Set the height of Bar
setTitleColor Set the title color
setTitle Set the title
setBackClick Set back button listening
  • Code using

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

2.StateView (Data loading page)

attribute role
STATE_NO_DATA No loading box status code is displayed
STATE_LOADING Load data display status code
STATE_EMPTY No data to display the status code
STATE_DISCONNECT No network status code
setOnDisConnectViewListener Click no network icon callback
setOnEmptyViewListener Click no no data icon callback
showViewByState Setting display status
getmEmptyView Get no data status View
Layout parameters can be set
loadingViewAnimation Sets the drawable animation to load
loadingText Text at load time
emptyImage Empty layout shows the picture
emptyText Empty layout text
emptyViewRes Set a custom empty layout
disConnectImage Set the picture displayed when the network is disconnected
disConnectText Set the text displayed when the network is disconnected
tipTextSize Text font size
tipTextColor Text font color
(1) Define a general layout
<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 >
Copy the code
(2) Add it to the LAYOUT of Ui page
<include layout="@layout/layout_state"/>
Copy the code
Note: The above statement preferably adds the outermost LinearLayout and sets it to Android: Orientation =”vertical”
(3) Switch the state through the following statements
stateView.showViewByState(StateView.STATE_LOADING)
stateView.showViewByState(StateView.STATE_EMPTY)
stateView.showViewByState(StateView.STATE_NO_DATA)
stateView.showViewByState(StateView.STATE_DISCONNECT)
Copy the code

3. Implement Permission Settings in three steps

(1) Set the permission to request
// The required permissions of the project, Without these PERMISSIONS will affect the normal operation of the project private val PERMISSIONS = arrayOf (Manifest. Permission. READ_SMS, Manifest. Permission. RECEIVE_WAP_PUSH, Manifest.permission.READ_CONTACTS )Copy the code
(2) Permissions are managed through PermissionManager
permissionManager = PermissionManager .with(this) .setNecessaryPermissions(PERMISSIONS) permissionManager? .requestPermissions()Copy the code
(3) rewrite onRequestPermissionsResult page
/ / rewrite override fun onRequestPermissionsResult (requestCode: Int, @ NonNull permissions: Array<String>, @NonNull grantResults: IntArray) {if (requestCode = = PermissionManager PERMISSION_REQUEST_CODE) {/ / PERMISSION_REQUEST_CODE to request permissions // If (permissionManager? .shouldShowRequestPermissionsCode == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED) { Toastutils.showtoast (this, "can be set here to re-pop permission request prompt box ")} else if (permissionManager? .shouldShowRequestPermissionsCode == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND) { Toastutils.showtoast (this, "can pop up here prompt to apply Settings page to enable permissions ") permissionManager? .startAppSettings() } } }Copy the code
Note: if there is demand to determine whether again after all permissions have been allowed to enter the main page via permissionManager. IsLackPermission (), requests for permission if returns true if the return false to enter the main page.
  • If one of multiple permission requests is forbidden to alert, the permission that is not forbidden to alert will be processed first.
  • If the necessary permission is prohibited and the prohibition reminder is not selected, the permission will be requested again next time.
  • If necessary permissions have been banned and chose the ban in onRequestPermissionsResult will remind back into the page callback methods.
  • Users can according to onRequestPermissionsResult () method returns to sign PermissionManager EXIST_NECESSARY_PERMISSIONS_PROHIBTED and PermissionManager. EX IST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND To perform the necessary display and operation, such as switching to the setting page or TOAT prompt.

4. Provide several commonly used Dialog boxes

(1) Commonly used CommonDialog provided
attribute role
DIALOG_TEXT_TWO_BUTTON_DEFAULT Default pop-up button prompt
DIALOG_TEXT_TWO_BUTTON_CUSTOMIZE Custom eject button prompt
DIALOG_LOADING_PROGRASSBAR The default loading frame
DIALOG_CHOICE_ITEM No data to display the status code

Set different parameters for different constructors

(2) Customize the Dialog style
  • BaseDialogFragment
attribute role
setContentView Set the layout style of the pop-up box
onViewCreated After the initialization callback, you can do some initialization here
show(…) Show bounced
dismiss Bounced destroyed
setAllCancelable Clicking the Back key and external cannot be cancelled
setOnlyBackPressDialogCancel Click the back key to cancel
setDialogInterval Set the spacing between the popbox and the screen
setDialogHeight Set the height of the subrack
setOnDismissListener Popbox destruction callback
  • Inherit BaseDialogFragment and set the popover layout with setContentView(r.layout.dialog_list).
  • The corresponding logic is set in the provided onViewCreated method

5. Customize the PopupWindow

  • BasePopupWindow
attribute role
BasePopupWindow(Context context) Calling this constructor defaults to a pop-up box that fills the full screen
BasePopupWindow(Context context, int w, int h) Customize the height and width of the pop-up box
showPopup The dialog box is displayed in the center of the screen
showPopupAsDropDown Displays a pop-up box at the bottom of the specified control
showPopup The dialog box is displayed in the center of the screen
showPopupAsDropDown Displays a pop-up box at the bottom of the specified control
setShowMaskView Sets whether to display masks
dismiss Destroy popup
getPopupLayoutRes Customize the layout file of the pop-up box
getPopupAnimationStyleRes Custom pop-up box animation file, do not set the animation return 0
  • BasePopupWindow inheritance.
  • Set the popover layout with getPopupLayoutRes(r.layout.xxx).
  • Through getPopupAnimationStyleRes (R.s tyle. XXX) animation set play a window, don’t need the animation can be set to 0.
  • If a mask is required, set it in the constructor by setShowMaskView(true).

Vii. Use of CustomView

The use of 1. com monTabLayout

attribute role
tab_tabIndicatorWidth Set the length of the glide line
tab_tabIndicatorHeight Set the height of the glide line
tab_tabIndicatorColor Glide line color
tab_indicator_marginLeft Set the glide margin
tab_indicator_marginRight Set the glide margin
tab_indicator_marginTop Set the glide margin
tab_indicator_marginBottom Set the glide margin
tab_tabTextColor Font color is not selected
tab_tabTextSize The font size
tab_tabSelectedTextColor Select the font color
tab_padding The distance inside the slide line. This property can be used to set the distance in block style
tab_tabBackground The background color of Tab
tab_indicator_corner The size of the rounded corner of the glide line
Tab_indicator_gravity (bottom, top Set the slide line display position for Line and Triangle only
Tab_tabMode (scrollable, fixed) Tab display mode
Tab_indicator_style (Line, Triangle, Block) Slide line style
Specific examples can be used.

2. The use of OutSideFrameTabLayout

attribute role
tab_tabIndicatorColor Set Tab color
tab_indicator_corner The rounded size
tab_indicator_marginLeft Slip line margin
tab_indicator_marginRight Slip line margin
tab_indicator_marginTop Slip line margin
tab_indicator_marginBottom Slip line margin
tab_tabTextColor Font color is not selected
tab_tabSelectedTextColor Select the font color
tab_tabTextSize The font size
tab_tabSelectedTextColor Select the font color
tab_padding padding
tab_bar_color The background color of bar
tab_bar_stroke_color The color of the outer frame
tab_bar_stroke_width The size of the outer frame
tab_width The length of the bar
Specific examples can be used.

3. The use of AutoLineLayout

  • Use AutoLineLayout for the outer layout

    <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>
    Copy the code

4. The use of TagView

TagViewConfigBuilder
attribute role
setTitles Set the TagItem content
setTextSize Sets the TagItem font size
setTextColor Sets the TagItem font color
setTextSelectColor Set TagItem to select font color
setPaddingLeftAndRight Sets the TagIttem left and right inner margins
setPaddingTopAndBottom Sets the TagIttem upper and lower inner margins
setMarginAndTopBottom Sets the upper and lower TagItem margins
setMarginLeftAndRight Sets the left and right TagItem margins
setackgroudRes Set the background Drawable
setTagViewAlign Set the Align of the entire TagItem (LEFT,RIGHT,CENTER)
1. The layout
<com.youngmanster.collection_kotlin.base.customview.tagview.TagView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tagView" />
Copy the code
2. Code Settings
tagView.create(builder,object :TagView.TagViewPressListener{
        override fun onPress(view: View, title: String, position: Int) {
            ToastUtils.showToast(this@TagViewActivity,title)
        }
 })
Copy the code

8. Jump between fragments

Fragments of the jump

attribute role
fragmentLayoutId Set the root layout ID to display the Fragment, set in the Activity
startFragmentForResult(…) And the callback result jumps
onFragmentResult(….) Fragment result callback
setResult(…) OnFragmentResult Result setting for the callback
startFragment(…) Common jump, specific use to view IBaseActivity
IsRootFragment () Check whether it is a root Fragment
OnCreateViewAndInitLazy () Set lazy loading. If true, init and layout are not initialized until the page is displayed

Use of tool classes

1.Density (suitable for different mobile phone pixels)
  • SetDensity. SetDensity (this, 375f) in Applicaton onCreate
  • 375F represents the width of the design draft, in unit dp, followed by F (floating point type).
2.DisplayUtils

attribute role
px2dip Convert the PX value to dip or DP value to keep the size unchanged (loss of accuracy)
px2dipByFloat The px value is converted to dip or DP value to keep the size unchanged (no loss of accuracy
dip2px Dip or dp value converted to the px, guarantee the size remains the same (precision loss), similar to the Context. GetDimensionPixelSize method (rounded
dip2pxByFloat Dip or DP values are converted to px values, keeping the dimensions unchanged (without loss of precision), similar to the context.getDimension method
px2sp Convert the px value to sp, keeping the text size unchanged
sp2px Convert the sp value to the px value, keeping the text size unchanged
getScreenWidthPixels The width of the screen
getScreenHeightPixels The screen height
getDisplayInfo Obtaining Device Information
setStatusBarBlackFontBgColor Sets the background color for the black font state
setStatusBarColor Sets the status bar background color
setStatusBarFullTranslucent Make the status bar transparent
getStatusBarHeight Gets the status bar height
getActionBarHeight Gets the ActionBar height
3.ColorUtils
attribute role
createColorStateList Get ColorStateList
4.FileUtils
attribute role
WriterTxtFile Write file, where append can be set to be added after the original content
ReadTxtFile Read the contents of a text file. StrFilePath represents the detailed path of the file
isCacheDataFailure Determine whether the cache is invalid
checkFileExists Check whether the file exists
checkSaveLocationExists Check whether an SD card is installed
deleteDirectory Delete a directory (including all files in the directory)
deleteFile Delete the file
getFileOrFilesSize SizeType Specifies the size of a file. 1 is B, 2 is KB, 3 is MB, and 4 is GB
getFileSize Gets the specified file size
5.GetPermissionsUtils
attribute role
getAllPermissons Get all permissions used by the application
6.GlideUtils
attribute role
loadImg Loading pictures
loadImgBlur Glide implements Gaussian blur
loadImgBlur Glide to achieve Gaussian blur, can set the degree of blur
7.ThreadPoolManager: Thread pool management class
8.LogUtils: Diary tool class
9.NetworkUtils: Network utility class
10.SoftInputUtils: Keyboard tools
11.ToastUtils: Toast utility class
12.RxJavaUtil: Master/child thread switch

This article will be updated according to the need, suggest to like favorites, easy to view. More suggestions are also welcome.