Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Jetpackmvvm | 2,550 | 9 months ago | 11 | apache-2.0 | Kotlin | |||||
:chicken::basketball:一个Jetpack结合MVVM的快速开发框架,基于MVVM模式集成谷歌官方推荐的JetPack组件库:LiveData、ViewModel、Lifecycle、Navigation组件 使用Kotlin语言,添加大量拓展函数,简化代码 加入Retrofit网络请求,协程,帮你简化各种操作,让你快速开发项目 | ||||||||||
Chromeliketabswitcher | 1,137 | 2 | 3 years ago | 33 | February 12, 2020 | 5 | apache-2.0 | Java | ||
Provides a tab switcher similar to the one, which is used in Google Chrome on Android | ||||||||||
Jetpack Mvvm Scaffold | 898 | 4 days ago | 2 | Java | ||||||
人生苦短,让脚手架为你节省时间。(目前作为《最佳实践》项目的 Dev 版优先更新) | ||||||||||
Ribbonmenu | 491 | 7 years ago | 9 | apache-2.0 | Java | |||||
Navigation menu for Android (based off Google+ app) | ||||||||||
Sidenavigation | 327 | 10 years ago | 5 | apache-2.0 | Java | |||||
Implementation of "Side Navigation" or "Fly-in app menu" pattern for Android (based on Google+ app) | ||||||||||
Bottomnavigation | 320 | 7 years ago | 1 | |||||||
底部导航栏(Bottom navigation)设计规范指南 | ||||||||||
Sherlocknavigationdrawer | 251 | 8 years ago | 2 | Java | ||||||
SherlockNavigationDrawer is the implementation of the latest Google UX component, Navigation Drawer. It should work exactly as Google Drive plus!! It works with ActionBarSherlock and devices with pre HC. | ||||||||||
Googlenavigationdrawer | 154 | 1 | 8 years ago | 1 | December 19, 2014 | 7 | apache-2.0 | Java | ||
Navigation Drawer Activity with Google design style and simplified methods | ||||||||||
Googlenewsstandanimation Android | 121 | 3 years ago | 1 | September 26, 2018 | 2 | apache-2.0 | Java | |||
Navigation pattern like in Google News Stand app with transitions | ||||||||||
Lollipop Appcompat Widgets Skeleton | 100 | 8 years ago | 1 | apache-2.0 | Java | |||||
A skeleton of google's appcompat android navigation drawer with material design. |
NavigationActivity+FragmentmvpMVP hegaojian/WanAndroid
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
...
implementation 'com.github.hegaojian:JetpackMvvm:1.2.7'
}
AndroidStudio 4.0 ------>
android {
...
dataBinding {
enabled = true
}
viewBinding {
enabled = true
}
}
AndroidStudio 4.0 ------>
android {
...
buildFeatures {
dataBinding = true
viewBinding = true
}
}
BaseActivity/BaseFragmentBase
Activity
abstract class BaseActivity<VM : BaseViewModel, DB : ViewDataBinding> : BaseVmDbActivity<VM, DB>() {
/**
* ActivityId abstract
*/
abstract override fun layoutId(): Int
/**
* Activityc abstract
*/
abstract override fun initView(savedInstanceState: Bundle?)
/**
* liveData
*/
override override fun createObserver()
/**
*
*/
override fun showLoading(message: String) {
...
}
/**
*
*/
override fun dismissLoading() {
...
}
}
Fragment
abstract class BaseFragment<VM : BaseViewModel,DB:ViewDataBinding> : BaseVmDbFragment<VM,DB>() {
abstract override fun initView(savedInstanceState: Bundle?)
/**
* fragment abstract
*/
abstract override fun lazyLoadData()
/**
* liveData
*/
override override fun createObserver()
/**
* FragmentonViewCreated
*/
override fun initData() {
}
/**
*
*/
override fun showLoading(message: String) {
...
}
/**
*
*/
override fun dismissLoading() {
...
}
}
class LoginViewModel : BaseViewModel() {
}
class LoginFragment : BaseFragment<LoginViewModel, FragmentLoginBinding>() {
/**
*
*/
override fun initView(savedInstanceState: Bundle?) {
...
}
/**
* fragment
*/
override fun lazyLoadData() {
...
}
}
class NetworkApi : BaseNetworkApi() {
companion object {
val instance: NetworkApi by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { NetworkApi() }
//- NetApiService
val service: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
instance.getApi(ApiService::class.java, ApiService.SERVER_URL)
}
}
/**
* setHttpClientBuilder
* OkHttpClient.Builder
*/
override fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder {
builder.apply {
//headstoken Loghead
addInterceptor(MyHeadInterceptor())
//
addInterceptor(LogInterceptor())
//
connectTimeout(10, TimeUnit.SECONDS)
readTimeout(5, TimeUnit.SECONDS)
writeTimeout(5, TimeUnit.SECONDS)
}
return builder
}
/**
* setRetrofitBuilder
* Retrofit.BuilderGSONprotobuf
*/
override fun setRetrofitBuilder(builder: Retrofit.Builder): Retrofit.Builder {
return builder.apply {
addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
addCallAdapterFactory(CoroutineCallAdapterFactory())
}
}
}
{
"data": ...,
"errorCode": 0,
"errorMsg": ""
}
Android ApierrorCode0 -dataerrorCode==0 BaseResponse
data class ApiResponse<T>(var errorCode: Int, var errorMsg: String, var data: T) : BaseResponse<T>() {
// wanandroid 0
override fun isSucces() = errorCode == 0
override fun getResponseCode() = errorCode
override fun getResponseData() = data
override fun getResponseMsg() = errorMsg
}
1ResultStateActivity/FragmentResultState
class RequestLoginViewModel: BaseViewModel {
//
var loginResult = MutableLiveData<ResultState<UserInfo>>()
//
var loginResult2 = MutableLiveData<ResultState<ApiResponse<UserInfo>>>()
fun login(username: String, password: String){
//1. Activity/Fragment
request(
{ HttpRequestCoroutine.login(username, password) }, //
loginResult,//ActivityfragmentloginActivity
true,//false
"..."//...
)
//2.Activity/Fragmentcode
requestNoCheck(
{HttpRequestCoroutine.login(username,password)},
loginResult2,
true,
"...")
}
class LoginFragment : BaseFragment<LoginViewModel, FragmentLoginBinding>() {
private val requestLoginRegisterViewModel: RequestLoginRegisterViewModel by viewModels()
/**
*
*/
override fun initView(savedInstanceState: Bundle?) {
...
}
/**
* fragment
*/
override fun lazyLoadData() {
...
}
override fun createObserver(){
//
requestLoginRegisterViewModel.loginResult.observe(viewLifecycleOwner,
Observer { resultState ->
parseState(resultState, {
//
it.username.logd()
}, {
//(...)
showMessage(it.errorMsg)
})
})
//
requestLoginRegisterViewModel.loginResult2.observe(viewLifecycleOwner, Observer {resultState ->
parseState(resultState,{
if(it.errorCode==0){
//
it.data.username.logd()
}else{
//
showMessage(it.errorMsg)
}
},{
//
showMessage(it.errorMsg)
})
})
}
}
2 ViewModel
class RequestLoginViewModel : BaseViewModel() {
fun login(username: String, password: String){
//1.
request({HttpRequestCoroutine.login(username,password)},{
//
it.username.logd()
},{
//
it.errorMsg.logd()
},true,"...")
//2.code
requestNoCheck({HttpRequestCoroutine.login(username,password)},{
//
if(it.errorCode==0){
//
it.data.username.logd()
}else{
//
it.errorMsg.logd()
}
},{
//
it.errorMsg.logd()
},true,"...")
}
val mainViewModel:MainViewModel by viewModels()
val mainViewModelMainViewModel by activityViewModels()
loadingActivity | Fragment
jetpackMvvmLog false true
val mainViewModel = ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory(application)).get(MainViewModel::class.java)
**Ktx
//activityActivityViewModel
private val mainViewModel:MainViewModel by viewModels()
//activityApplicationViewModelApplicationBaseApp
private val mainViewModel by lazy { getAppViewModel<MainViewModel>()}
//fragmentFragmentViewModel
private val mainViewModel:MainViewModel by viewModels()
//fragmentActivityViewModel
private val mainViewModelMainViewModel by activityViewModels()
//fragmentApplicationViewModelApplicationBaseApp
private val mainViewModel by lazy { getAppViewModel<MainViewModel>()}
me.hgj.jetpackmvvm.ext.util
me.hgj.jetpackmvvm.ext.view
-keep class me.hgj.jetpackmvvm.**{*;}
################ ViewBinding & DataBinding ###############
-keepclassmembers class * implements androidx.viewbinding.ViewBinding {
public static * inflate(android.view.LayoutInflater);
public static * inflate(android.view.LayoutInflater, android.view.ViewGroup, boolean);
public static * bind(android.view.View);
}
Copyright 2019, hegaojian()
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.