-
Notifications
You must be signed in to change notification settings - Fork 94
Home
FastLib 是一个整合了常用主流开源项目的 Android 快速搭建UI库, 其中包含 Retrofit、RxJava 、RxAndroid、RxLifecycle等三方库, 并且提供较多的基础Activity与Fragment如快速搭建微信类tab+fragment 的FastMainActivity、快速搭建包含TitleBar的FastTitleActivity及FastTitleFragment、快速搭建列表刷新的FastRefreshLoadActivity及FastRefreshLoadFragment;并提供快速配置Retrofit相关功能的FastRetrofit:解决添加统一请求header及多url等常见功能。
FastLib 只是一个快速搭建UI及网络请求的库,是常用三方库的一个封装集合,本身不具备框架特性。可在此基础上做MVP、MVVM等框架的扩展。
该wiki是基于FastLib 2.2.12 、Android Studio 3.3.1、Gradle 4.10.1版本编写,后期重大变更会同步更新。
- 基于Retrofit2.x及RxJava2.x的网络请求封装、网络请求与生命周期绑定、快速观察者、快速loading观察者、快速返回常用错误
- 常用功能库二次封装方便调用:Glide加载图片封装GlideManager、TabLayout+ViewPager Fragment切换封装TabLayoutManager、Logger日志打印封装LoggerManager
- 多种常用界面布局:标题+多状态+下拉刷新+列表、标题+ViewPager等方便快速创建常用布局增加layout复用
- Fragment 懒加载封装
- 快速实现Activity滑动返回、下拉刷新+自动加载更多、沉浸式状态栏+导航栏等
- 解决一些老大难问题:Tab+Fragment 当Activity回收后Fragment 重叠-FastMainActivity、软键盘无法弹起-KeyboardHelper、状态栏文字转换-StatusBarUtil、不同Fragment切换状态栏文字颜色变换-BasisFragment+StatusBarUtil、Android 7.0 fileprovider-FastFileUtil、Android 9.0 network security policy问题等
- 提供众多常用工具类:ToastUtil-统一样式吐司、FastFormatUtil-快速格式化时间、内存字节单位、double类型小数点保留几位、SizeUtil-尺寸转换屏幕宽高获取、SPUtil-暂存数据等
Retrofit是Square出品的网络请求库,极大的减少了 Http 请求的代码和步骤RxJava提供优雅的响应式 API 解决异步请求以及事件处理RxAndroid为 Android 提供响应式 APIRxlifecycle,在 Android 上使用RxJava都知道的一个坑,就是生命周期的解除订阅,这个框架通过绑定 Activity 和 Fragment 的生命周期完美解决该问题Okhttp同样Square出品,不多介绍,做 Android 的都应该知道Gson是Google官方的 Json Convert 框架Butterknife是JakeWharton大神出品的 View 注入框架AndroidEventBus是一个轻量级的EventBus,提供TAG支持Logger是orhanobut出品的 Log 框架,FastLib提供相关封装类LoggerManagerGlide是Google推荐的图片加载库,FastLib提供相关封装类GlideManagerBaseRecyclerViewAdapterHelper是陈宇明封装的RecyclerView 适配器帮助类SmartRefreshLayout是scwang90封装的刷新库,扩展性很强AgentWeb是Justson封装的原生WebView库,使用方便扩展性很强BGASwipeBackLayout是bingoogolapple-王浩封装的微信效果的Activity滑动返回库StatusLayoutManager是Bakumon封装的多状态控制管理工具,方便实现加载中、加载失败、网络错误等状态TabLayout是AriesHooforked fromFlycoTabLayout并加以优化调整的主界面tab、滑动tab、分段选择器tab功能库UIWidget是AriesHoo封装的常用UI库(TitleBarView、RadiusView、StatusViewHelper、NavigationViewHelper等)
- 1、开发者需要具有一定的 Android 开发能力,以及自我解决问题的能力
- 2、开发者需对 Retrofit2.x 及 RxJava2.x 有一定了解,至少项目中使用过
- 3、本库建议直接使用 Gradle 远程依赖, 框架已经提供了很多用于扩展的接口, 足以满足日常需求
- 4、多看注释
FastLib注释还是很多的,每个类更新记录得也较详细 - 5、注意解决Androidx与support包不能共存问题-建议可以使用Android Studio 带的Refactor->Migrate to AndroidX功能
- 6、本库是笔者业余时间开发、在自己项目中也在使用,会及时的更新和维护。如有使用过程BUG请先参看issus没有解决的提交新issue ,提交中一定要说明使用版本,能提交使用代码最佳
FastLib本身以及FastLib使用的部分三方库是通过JitPack发布打包,故在gradle需进行相关设置,否则无法下载 compileSdkVersion 及androix-原support 版本配置也放在gradle下边,网上也有单独设置config.gradle方式,这里不做限制看个人喜好
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'//以3.3.1为例
//classpath 'com.android.tools.build:gradle:x.y.z'
}
}
allprojects {
repositories {
jcenter()
google() //AndroidStudio v3.0 可以使用 google() 替代 maven { url "https://maven.google.com" }
maven { url "https://jitpack.io" }//FastLib 及部分三方库通过JitPack发布需添加才可依赖
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext{
compileSdkVersion = 28
minSdkVersion = 21
targetSdkVersion = 28
supportVersion = "1.0.0"
versionCode = 239
versionName = "2.2.12"
}
FastLib部分库使用compileOnly模式引入,故项目需根据实际情况implementation 其它库如RxJava、Retrofit、Okhttp、RxLifecycle等FastLib直接以api 模式引入开发者无需再次引入
dependencies {
implementation 'com.github.AriesHoo:FastLib:2.2.12'
//以下库FastLib里使用compileOnly只是编译,使用时需根据项目选择相应版本
implementation 'com.google.android.material:material:'.concat(supportVersion)
implementation 'androidx.appcompat:appcompat:'.concat(supportVersion)
implementation 'androidx.recyclerview:recyclerview:'.concat(supportVersion)
//万能适配器--一般都需要吧
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.45-androidx'
//webView库 继承FastWebActivity需要,不需要内置WebView可以不implementation
implementation 'com.just.agentweb:agentweb:4.0.2'
//webView提供下载功能
implementation 'com.just.agentweb:download:4.0.2'
//下拉刷新库注意刷新头SmartRefreshHeader版本最好对应尤其头版本不要低于SmartRefreshLayout版本
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1'
//Glide图片加载
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
//以上库library里使用compileOnly只是编译,使用时需根据项目选择相应版本
}
因Lambda支持需在 应用的gradle android节点下配置java版本否则使用
Retrofit可能出现异常 Android Studio 3.0 (兼容 Java8, 默认支持 Lambda, 但需手动指定 targetCompatibility)
android {
//其它配置
defaultConfig {
//默认配置
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//其它配置
}
Android Studio 3.0以下版本需要在项目根目录的 build.gradle 中依赖 Lambda插件
buildscript {
dependencies {
//classpath 'com.android.tools.build:gradle:x.y.z'//lambda
classpath 'me.tatarka:gradle-retrolambda:3.7.0'
}
}
app 的 build.gradle 中引入 Lambda 插件
apply plugin: 'me.tatarka.retrolambda'
android {
//其它配置
defaultConfig {
//默认配置
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//其它配置
}
FastLib默认实现了不少初始化工作,包括日志打印 LoggerManager、 GlideManager等,但为了设置app的独特风格还是需要开发者做一些初始化动作
主要提供三个配置参数tag、isDebug、builder,分别设置log的标签、是否打印log、Logger的配置 PrettyFormatStrategy.Builder 一般在应用的Application类onCreate初始化即可
//初始化Logger日志打印
LoggerManager.init(TAG, BuildConfig.DEBUG);
如需更细致配置即可调用传入PrettyFormatStrategy.Builder
//初始化Logger日志打印
LoggerManager.init(TAG, BuildConfig.DEBUG,
PrettyFormatStrategy.newBuilder()
.methodOffset(0)
.showThreadInfo(true)
.methodCount(3));
当然其实开发者也是可以不用初始化的、在调用具体日志打印时会默认初始化,但TAG或设置成当前类名且始终打印日志,实际开发情况多半在debug开发模式时开启日志方便调试、正式打包release时关闭log,故还是建议开发者初始化下
FastManager主要初始化TitleBarView样式 、Toast样式、SwipeBack样式、Glide占位样式、Loading Dialog全局等待样式等UI相关;
//最简单UI配置模式-必须进行初始化
FastManager.init(this);
- 1、开发者最简必须调用以上方法进行初始化,
FastLib会内部实现默认效果、默认效果取自fast_colors.xml、fast_dimens.xml、fast_strings.xml 配置 - 2、开发者可将fast_colors.xml、fast_dimens.xml、fast_strings.xml 复制进app的values下进行部分参数的修改以达到UI自定义效果
如开发者不喜欢修改fast_colors.xml、fast_dimens.xml、fast_strings.xml 参数配置
FastLib提供多个接口回调方法开发者统一处理FastLib提供方式是注册监听、类似观察者模式,当程序执行到具体流程才会回调执行具体代码。故不要说什么 “Application 执行这么多代码,应用得不得卡,得不得ANR” 类似的
//最简单UI配置模式-必须进行初始化
FastManager.init(this);
//以下为更丰富自定义方法
//全局UI配置参数-按需求设置
AppImpl impl = new AppImpl(mContext);
ActivityControlImpl activityControl = new ActivityControlImpl();
FastManager.getInstance()
//设置Adapter加载更多视图--默认设置了FastLoadMoreView
.setLoadMoreFoot(impl)
//全局设置RecyclerView
.setFastRecyclerViewControl(impl)
//设置RecyclerView加载过程多布局属性
.setMultiStatusView(impl)
//设置全局网络请求等待Loading提示框如登录等待loading--观察者必须为FastLoadingObserver及其子类
.setLoadingDialog(impl)
//设置SmartRefreshLayout刷新头-自定加载使用BaseRecyclerViewAdapterHelper
.setDefaultRefreshHeader(impl)
//设置全局TitleBarView相关配置
.setTitleBarViewControl(impl)
//设置Activity滑动返回控制-默认开启滑动返回功能不需要设置透明主题
.setSwipeBackControl(new SwipeBackControlImpl())
//设置Activity/Fragment相关配置(横竖屏+背景+虚拟导航栏+状态栏+生命周期)
.setActivityFragmentControl(activityControl)
//设置BasisActivity 子类按键监听
.setActivityKeyEventControl(activityControl)
//配置BasisActivity 子类事件派发相关
.setActivityDispatchEventControl(activityControl)
//设置http请求结果全局控制
.setHttpRequestControl(new HttpRequestControlImpl())
//设置主页返回键控制-默认效果为2000 毫秒时延退出程序
.setQuitAppControl(impl)
//设置ToastUtil全局控制
.setToastControl(impl);
- 1、该功能依赖
BGASwipeBackLayout-Android,可不用应用主题设置 true ,虽说加上属性效果更佳,但是会引起两个情况 (一)、targetSdk设置成27及以上如果Activity有设置屏幕横竖屏操作会造成应用崩溃 Only fullscreen activities can request orientation (二)、 快速点击跳转页面相关按钮一定概率显示系统桌面 ;开发者自行决定 - 2、
FastLib注册生命周期回调并在onActivityCreated回调进行相关设置,故可以对其它三方库里的Activity实现相同滑动返回效果 - 3、回调中传递Activity对象,开发者也可通过该对象过滤掉你不想执行的操作
- 4、如果整个应用不想使用滑动返回功能isSwipeBackEnable return false即可
/**
* 设置当前Activity是否支持滑动返回(用于控制是否添加一层{@link BGASwipeBackLayout})
* 返回为true {@link #setSwipeBack(Activity, BGASwipeBackHelper)}才有设置的意义
*
* @param activity
* @return
*/
@Override
public boolean isSwipeBackEnable(Activity activity) {
return true;
}
/**
* 设置Activity 全局滑动属性--包括三方库
*
* @param activity
* @param swipeBackHelper BGASwipeBackHelper 控制详见{@link com.aries.library.fast.FastManager}
*/
@Override
public void setSwipeBack(Activity activity, BGASwipeBackHelper swipeBackHelper) {
//以下为默认设置
//需设置activity window背景为透明避免滑动过程中漏出背景也可减少背景层级降低过度绘制
activity.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
swipeBackHelper.setSwipeBackEnable(true)
.setShadowResId(R.color.colorSwipeBackBackground)
//底部导航条是否悬浮在内容上设置过NavigationViewHelper可以不用设置该属性
.setIsNavigationBarOverlap(App.isControlNavigation());
}
/**
* 正在滑动返回
*
* @param activity 滑动的Activity
* @param slideOffset 滑动偏移量 0-1
*/
@Override
public void onSwipeBackLayoutSlide(Activity activity, float slideOffset) {
}
/**
* 没达到滑动返回的阈值,取消滑动返回动作,回到默认状态
*
* @param activity 当前Activity
*/
@Override
public void onSwipeBackLayoutCancel(Activity activity) {
}
/**
* 滑动返回执行完毕,销毁当前 Activity
*
* @param activity 当前activity
*/
@Override
public void onSwipeBackLayoutExecuted(Activity activity) {
}
- 1、该功能依赖
UIWidget:widget-core库,TitleBarView支持左、右文字图标、主副标题 跑马灯、自定义左、中、右View功能,默认支持沉浸式及状态栏文字颜色 - 2、回调了TitleBarView对象及TitleBarView所在Class,可设置统一属性及根据Class做差异化
/**
* 控制全局TitleBarView
*
* @param titleBar
* @return
*/
@Override
public boolean createTitleBarViewControl(TitleBarView titleBar, Class<?> cls) {
//默认的MD风格返回箭头icon如使用该风格可以不用设置
Drawable mDrawable = FastUtil.getTintDrawable(ContextCompat.getDrawable(mContext, R.drawable.fast_ic_back),
ContextCompat.getColor(mContext, R.color.colorTitleText));
//是否支持状态栏白色
boolean isSupport = StatusBarUtil.isSupportStatusBarFontChange();
boolean isActivity = Activity.class.isAssignableFrom(cls);
Activity activity = FastStackUtil.getInstance().getActivity(cls);
//设置TitleBarView 所有TextView颜色
titleBar.setStatusBarLightMode(isSupport)
//不支持黑字的设置白透明
.setStatusAlpha(isSupport ? 0 : 102)
.setLeftTextDrawable(isActivity ? mDrawable : null)
.setDividerHeight(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ? SizeUtil.dp2px(0.5f) : 0);
if (activity != null) {
titleBar.setTitleMainText(activity.getTitle());
}
ViewCompat.setElevation(titleBar, mContext.getResources().getDimension(R.dimen.dp_elevation));
return false;
}
- 1、该功能依赖
SmartRefreshLayout库,回调中携带SmartRefreshLayout对象,可以设置其它丰富属性 - 2、
SmartRefreshLayout库拥有多种官方刷新头,如需特殊定制,参看自定义Header
/**
* 下拉刷新头配置
*
* @param context
* @param layout
* @return
*/
@NonNull
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
layout.setEnableHeaderTranslationContent(false)
.setEnableOverScrollDrag(false);
MaterialHeader materialHeader = new MaterialHeader(mContext);
materialHeader.setColorSchemeColors(ContextCompat.getColor(mContext, R.color.colorTextBlack),
ContextCompat.getColor(mContext, R.color.colorTextBlackLight));
return materialHeader;
}
- 1、该功能依赖
BaseRecyclerViewAdapterHelper库,回调中携带BaseQuickAdapter对象可以设置其它统一属性,如加载动画等 - 2、
FastLib自定义FastLoadMoreView扩展原库LoadMoreView支持属性自定义
/**
* Adapter加载更多配置
*
* @param adapter
* @return
*/
@Nullable
@Override
public LoadMoreView createDefaultLoadMoreView(BaseQuickAdapter adapter) {
if (adapter != null) {
//设置动画是否一直开启
adapter.isFirstOnly(false);
//设置动画
adapter.openLoadAnimation(BaseQuickAdapter.SCALEIN);
}
//方式一:设置FastLoadMoreView--可参考FastLoadMoreView.Builder相应set方法
//默认配置请参考FastLoadMoreView.Builder(mContext)里初始化
return new FastLoadMoreView.Builder(mContext)
.setLoadingTextFakeBold(true)
.setLoadingSize(SizeUtil.dp2px(20))
//.setLoadTextColor(Color.MAGENTA)
//设置Loading 颜色-5.0以上有效
//.setLoadingProgressColor(Color.MAGENTA)
//设置Loading drawable--会使Loading颜色失效
//.setLoadingProgressDrawable(R.drawable.dialog_loading_wei_bo)
//设置全局TextView颜色
//.setLoadTextColor(Color.MAGENTA)
//设置全局TextView文字字号
//.setLoadTextSize(SizeUtil.dp2px(14))
//.setLoadingText("努力加载中...")
//.setLoadingTextColor(Color.GREEN)
//.setLoadingTextSize(SizeUtil.dp2px(14))
//.setLoadEndText("我是有底线的")
//.setLoadEndTextColor(Color.GREEN)
//.setLoadEndTextSize(SizeUtil.dp2px(14))
//.setLoadFailText("哇哦!出错了")
//.setLoadFailTextColor(Color.RED)
//.setLoadFailTextSize(SizeUtil.dp2px(14))
.build();
//方式二:使用adapter自带--其实我默认设置的和这个基本一致只是提供了相应设置方法
// return new SimpleLoadMoreView();
//方式三:参考SimpleLoadMoreView或FastLoadMoreView完全自定义自己的LoadMoreView
//return MyLoadMoreView();
}
该功能主要针对通过FastRefreshLoadDelegate代理RecyclerView的Activity/Fragment,
FastLib为FastRefreshLoadActivity及FastRefreshLoadFragment,为方便统一设置RecyclerView及一些特殊处理;其实在生命周期里通过findViewById或FindViewUtil找到对应RecyclerView 作处理亦可
@Override
public void setRecyclerView(RecyclerView recyclerView, Class<?> cls) {
recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
recyclerView.setNestedScrollingEnabled(false);
}
该功能依赖
StatusLayoutManager库,用于设置多状态各状态layout,如不设置则使用StatusLayoutManager默认布局
/**
* 设置全局多状态布局
*
* @param statusView
* @param iFastRefreshLoadView
*/
@Override
public void setMultiStatusView(StatusLayoutManager.Builder statusView, IFastRefreshLoadView iFastRefreshLoadView) {
statusView.setLoadingLayout(R.layout.layout_multi_loading)
.setEmptyLayout(R.layout.layout_multi_empty)
.setEmptyClickViewID(R.id.rtv_retryMultiEmpty)
.setErrorLayout(R.layout.layout_multi_error)
.setErrorClickViewID(R.id.rtv_retryMultiError)
.setDefaultLayoutsBackgroundColor(Color.TRANSPARENT);
}
- 1、请求成功主要用于实现 IFastRefreshLoadView 接口通过 FastRefreshLoadDelegate 代理的 FastRefreshLoadActivity 及 FastRefreshLoadFragment 用于列表数据加载成功后相关统一逻辑处理,并在成功回调 _onNext 调用 FastManager.getInstance().getHttpRequestControl().httpRequestSuccess(IHttpRequestControl httpRequestControl, List<?> list, OnHttpRequestListener listene); 方可全局处理;目前想到这种全局处理方式
- 2、请求失败需在 RxJava subscribe使用 FastObserver 或 FastLoadingObserver ,如列表请求如 FastRefreshLoadActivity 及 FastRefreshLoadFragment 子类需传递 IHttpRequestControl 可处理多布局等
- 3、如开发者自定自定义 subscribe ,只需参看 FastObserver 或 FastLoadingObserver 将 onError 中 Throwable 调用 FastManager.getInstance().getHttpRequestControl().httpRequestError(mHttpRequestControl, e); 即可全局处理异常信息
@Override
public void httpRequestSuccess(IHttpRequestControl httpRequestControl, List<?> list, OnHttpRequestListener listener) {
if (httpRequestControl == null) {
return;
}
SmartRefreshLayout smartRefreshLayout = httpRequestControl.getRefreshLayout();
BaseQuickAdapter adapter = httpRequestControl.getRecyclerAdapter();
StatusLayoutManager statusLayoutManager = httpRequestControl.getStatusLayoutManager();
int page = httpRequestControl.getCurrentPage();
int size = httpRequestControl.getPageSize();
LoggerManager.i(TAG, "smartRefreshLayout:" + smartRefreshLayout + ";adapter:" + adapter + ";status:" + ";page:" + page + ";class:" + httpRequestControl.getRequestClass());
if (smartRefreshLayout != null) {
smartRefreshLayout.finishRefresh();
}
if (adapter == null) {
return;
}
adapter.loadMoreComplete();
if (list == null || list.size() == 0) {
//第一页没有
if (page == 0) {
adapter.setNewData(new ArrayList());
statusLayoutManager.showEmptyLayout();
if (listener != null) {
listener.onEmpty();
}
} else {
adapter.loadMoreEnd();
if (listener != null) {
listener.onNoMore();
}
}
return;
}
statusLayoutManager.showSuccessLayout();
if (smartRefreshLayout.isRefreshing() || page == 0) {
adapter.setNewData(new ArrayList());
}
adapter.addData(list);
if (listener != null) {
listener.onNext();
}
if (list.size() < size) {
adapter.loadMoreEnd();
if (listener != null) {
listener.onNoMore();
}
}
}
@Override
public void httpRequestError(IHttpRequestControl httpRequestControl, Throwable e) {
int reason = R.string.fast_exception_other_error;
// int code = FastError.EXCEPTION_OTHER_ERROR;
if (!NetworkUtil.isConnected(App.getContext())) {
reason = R.string.fast_exception_network_not_connected;
} else {
//网络异常--继承于AccountsException
if (e instanceof NetworkErrorException) {
reason = R.string.fast_exception_network_error;
//账户异常
} else if (e instanceof AccountsException) {
reason = R.string.fast_exception_accounts;
//连接异常--继承于SocketException
} else if (e instanceof ConnectException) {
reason = R.string.fast_exception_connect;
//socket异常
} else if (e instanceof SocketException) {
reason = R.string.fast_exception_socket;
// http异常
} else if (e instanceof HttpException) {
reason = R.string.fast_exception_http;
//DNS错误
} else if (e instanceof UnknownHostException) {
reason = R.string.fast_exception_unknown_host;
} else if (e instanceof JsonSyntaxException
|| e instanceof JsonIOException
|| e instanceof JsonParseException) {
//数据格式化错误
reason = R.string.fast_exception_json_syntax;
} else if (e instanceof SocketTimeoutException || e instanceof TimeoutException) {
reason = R.string.fast_exception_time_out;
} else if (e instanceof ClassCastException) {
reason = R.string.fast_exception_class_cast;
}
}
if (httpRequestControl == null || httpRequestControl.getStatusLayoutManager() == null) {
ToastUtil.show(reason);
return;
}
SmartRefreshLayout smartRefreshLayout = httpRequestControl.getRefreshLayout();
BaseQuickAdapter adapter = httpRequestControl.getRecyclerAdapter();
StatusLayoutManager statusLayoutManager = httpRequestControl.getStatusLayoutManager();
int page = httpRequestControl.getCurrentPage();
if (smartRefreshLayout != null) {
smartRefreshLayout.finishRefresh(false);
}
if (adapter != null) {
adapter.loadMoreComplete();
if (statusLayoutManager == null) {
return;
}
//初始页
if (page == 0) {
if (!NetworkUtil.isConnected(App.getContext())) {
//可自定义网络错误页面展示
statusLayoutManager.showCustomLayout(R.layout.layout_status_layout_manager_error);
} else {
statusLayoutManager.showErrorLayout();
}
return;
}
//可根据不同错误展示不同错误布局 showCustomLayout(R.layout.xxx);
statusLayoutManager.showErrorLayout();
}
- 列表网络请求示例
@Override
public void loadData(int page) {
//接口最大支持单页100
mDefaultPageSize = 15;
ApiRepository.getInstance().getMovie(mUrl, page * mDefaultPage, mDefaultPageSize)
.compose(bindUntilEvent(FragmentEvent.DESTROY))
.subscribe(new FastObserver<BaseMovieEntity>(getIHttpRequestControl()) {
@Override
public void _onNext(BaseMovieEntity entity) {
LoggerManager.i("url:" + mUrl);
mStatusManager.showSuccessLayout();
FastManager.getInstance().getHttpRequestControl().httpRequestSuccess(getIHttpRequestControl(), entity == null || entity.subjects == null ? new ArrayList<>() : entity.subjects, null);
}
});
}
- 非列表请求示例
AccountRepository.getInstance().getUserInfo()
.compose(bindUntilEvent(FragmentEvent.DESTROY))
.subscribe(new FastObserver<UserEntity>() {
@Override
public void _onNext(UserEntity entity) {
//处理数据
}
});
- 1、需RxJava subscribe使用 FastLoadingObserver方可全局使用统一加载等待Loading Dialog
- 2、在LoadingDialog 返回 FastLoadDialog 并将开发者想要的Dialog设置即可全局使用
- 3、常用效果Dialog 使用
UIWidget:widget-core库中UIProgressDialog进行常用Dialog样式设置,如需个性化自定义即可
@Nullable
@Override
public FastLoadDialog createLoadingDialog(@Nullable Activity activity) {
Dialog dialog = new PictureDialog(activity);
return new FastLoadDialog(activity, dialog)
.setCancelable(true)
.setCanceledOnTouchOutside(true);
}
- 网络请求示例
UserRepository.getInstance().loginPhone(account, password)
.compose(activity.bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new FastLoadingObserver<LoginEntity>(activity, R.string.login_ing) {
@Override
public void _onNext(@NonNull LoginEntity entity) {
//逻辑处理
}
@Override
public void _onError(Throwable e) {
//错误处理
});
FastLib通过Application中registerActivityLifecycleCallbacks监听Activity生命周期,并做一些全局设置如滑动返回-SwipeBack;通过FragmentManager中registerFragmentLifecycleCallbacks监听Fragment生命周期,并通过ActivityFragmentControl回调给开发者处理即可,实现参看FastLifecycleCallbacks;开发者可处理如*友盟统计-这样不需单独设置Base也可对三方库里的Activity及Fragment进行统计
- 全局设置Activity/Fragment背景色可Fragment不设置背景减少过渡重绘
@Override
public void setContentViewBackground(View contentView, Class<?> cls) {
if (contentView == null) {
return;
}
//避免背景色重复
if (!Fragment.class.isAssignableFrom(cls)
&& contentView.getBackground() == null) {
contentView.setBackgroundResource(R.color.colorBackground);
}
}
- 全局控制横竖屏 注意:targetSDK设置27以上不能设置windowIsTranslucent=true,否则直接崩溃,错误: Only fullscreen activities can request orientation
/**
* 设置屏幕方向--注意targetSDK设置27以上不能设置windowIsTranslucent=true属性不然应用直接崩溃
* 错误为 Only fullscreen activities can request orientation
* 默认自动 ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
* 竖屏 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
* 横屏 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
* {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}
*
* @param activity
*/
@Override
public void setRequestedOrientation(Activity activity) {
//全局控制屏幕横竖屏
//先判断xml没有设置屏幕模式避免将开发者本身想设置的覆盖掉
if (activity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
try {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} catch (Exception e) {
e.printStackTrace();
LoggerManager.e(TAG, "setRequestedOrientation:" + e.getMessage());
}
}
}
- 三方库状态栏沉浸设置,
FastLib只进行了简单设置不能满足全部情况,开发者需根据自己引入三方库进行特殊处理以满足需求; 注意如需要设置三方库Activity状态栏控制,返回值必须为true,否则StatusViewHelper不会执行
/**
* 设置非FastLib且未实现Activity 状态栏功能的三方Activity 状态栏沉浸,
*
* @param activity
* @param helper
* @return
*/
@Override
public boolean setStatusBar(Activity activity, StatusViewHelper helper, View topView) {
return true;
}
- 三方库虚拟导航栏控制,
FastLib只进行了简单设置不能满足全部情况,开发者需根据自己引入三方库进行特殊处理以满足需求; 注意如需要设置三方库Activity导航栏控制返回值必须为true,否则NavigationViewHelper不会执行
/**
* {@link FastLifecycleCallbacks#onActivityStarted(Activity)}
*
* @param activity
* @param helper
*/
@Override
public boolean setNavigationBar(Activity activity, NavigationViewHelper helper, View bottomView) {
return true;
}
-
Activity生命周期设置,可进行友盟统计、应用前后台监听、禁用系统截图-银行/金融类App常用功能,可以使用
FastLib提供的FastActivityLifecycleCallbacks重写开发者需要的生命周期监听即可,如不需监听return null即可
/**
* Activity 生命周期监听--可用于三方统计页面数据
* 示例仅为参考如无需添加自己代码可回调null
*
* @return
*/
@Override
public Application.ActivityLifecycleCallbacks getActivityLifecycleCallbacks() {
return new FastActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
super.onActivityCreated(activity, savedInstanceState);
//阻止系统截屏功能-银行金融类App常用功能
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
@Override
public void onActivityStarted(Activity activity) {
super.onActivityStarted(activity);
mActivityStart++;
if (mActivityStart == 1) {
LoggerManager.i(TAG, "XXX正在前台运行");
}
}
@Override
public void onActivityStopped(Activity activity) {
mActivityStart--;
if (mActivityStart == 0) {
LoggerManager.i(TAG, "XXX正在后台运行");
}
}
};
}
- Fragment生命周期设置,Do what you want
/**
* Fragment 生命周期回调
*
* @return
*/
@Override
public FragmentManager.FragmentLifecycleCallbacks getFragmentLifecycleCallbacks() {
return new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentResumed(FragmentManager fm, Fragment f) {
super.onFragmentResumed(fm, f);
//MobclickAgent.onPageStart(f.getClass().getSimpleName());
}
@Override
public void onFragmentPaused(FragmentManager fm, Fragment f) {
super.onFragmentPaused(fm, f);
//MobclickAgent.onPageEnd(f.getClass().getSimpleName());
}
};
}
-
1、
FastLib默认支持BasisActivity,主要对Activity的onKeyXXX事件进行全局控制,可用于音量键监控等 -
2、如自定义Activity也想全局监控,参看BasisActivity代码,执行FastManager.getInstance().getActivityKeyEventControl().onKeyXXX即可
-
按键监听onKeyDown-;可控制音量键不显示系统UI,如抖音,返回值表示是否消费该事件,与系统一致。
@Override
public boolean onKeyDown(Activity activity, int keyCode, KeyEvent event) {
//演示拦截系统音量键控制--类似抖音
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN://音量增加
volume(1, false);
return true;
case KeyEvent.KEYCODE_VOLUME_UP://音量减少
volume(1, true);
return true;
}
return false;
}
- 其它按键监听 onKeyUp、onKeyLongPress、onKeyShortcut、onKeyMultiple等暂未想到使用场景有需要的拦截即可
-
1、
FastLib默认支持BasisActivity,主要对Activity的dispatchXXX事件派发进行全局控制,可用于点击非软键盘区域关闭软键盘功能等 -
2、如自定义Activity也想全局监控,参看BasisActivity代码,执行FastManager.getInstance().getActivityDispatchEventControl().dispatchXXX即可
-
触摸事件派发 dispatchTouchEvent,可通过KeyboardHelper里方法实现点击非输入框区域关闭软键盘功能 注意:目前Android 该方式有个小瑕疵:点击EditTextA再点击EditTextB 会出现软键盘先关闭再弹起的现象,但是目前是相对最优的方式,笔者观察微信/QQ亦是--微信/QQ的账号密码登录页
/**
* @param activity
* @param event
* @return
*/
@Override
public boolean dispatchTouchEvent(Activity activity, MotionEvent event) {
//根据事件派发全局控制点击非EditText 关闭软键盘
if (activity != null) {
KeyboardHelper.handleAutoCloseKeyboard(true, activity.getCurrentFocus(), event, activity);
}
return false;
}
-
1、
FastLib提供的ToastUtil仅提供所有系统统一效果设置及单例模式,并不解决系统权限关闭后Toast不弹出等老大难的问题,如开发者要解决权限问题 推荐DToast、smart-show(SmartToast部分) -
2、笔者发现华为某个系统版本自己实现了单例模式的Toast,如开发者频繁调用show()方法会造成Toast不显示问题。故ToastUtil内部过滤华为Rom,不进行Toast单例并提供回调ToastControl供开发者定义Toast
-
ToastUtil 初始化设置属性
int padding = SizeUtil.dp2px(8);
//初始化toast工具
ToastUtil.init(mContext, true, ToastUtil.newBuilder()
.setBackgroundColor()//设置背景
.setRadius(SizeUtil.dp2px(4))//设置圆角
.setPaddingLeft(padding * 2)//左边距
.setPaddingTop(padding)//上边距
.setPaddingRight(padding * 2)//右边距
.setPaddingBottom(padding)//下边距
.setGravityYOffset(getResources().getDimensionPixelSize(R.dimen.dp_title_height) + StatusBarUtil.getStatusBarHeight())//Y轴偏移量
.setTextSize(SizeUtil.dp2px(14))//文字尺寸
.setDuration(Toast.LENGTH_SHORT)//显示时长
.setGravity(Gravity.TOP)//显示位置
- ToastControl回调设置
@Override
public Toast getToast() {
return null;
}
@Override
public void setToast(Toast toast, RadiusTextView textView) {
}
BasisActivity中 quitApp方法进行了相关操作处理并通过FastManager.getInstance().getQuitAppControl().quipApp(boolean isFirst, Activity activity)方便开发者处理,只需在BasisActivity子类onBackPressed调用quitApp即可,可设置xxx毫秒执行下步操作也可立即进行退出程序或者返回系统桌面等操作。
- 回调设置2s后退出程序/回到系统桌面
/**
* @param isFirst 是否首次提示
* @param activity 操作的Activity
* @return 延迟间隔--如不需要设置两次提示可设置0--最佳方式是直接在回调中执行你想要的操作
*/
@Override
public long quipApp(boolean isFirst, Activity activity) {
//默认配置
if (isFirst) {
ToastUtil.show(R.string.fast_quit_app);
} else {
FastStackUtil.getInstance().exit(false);//退出程序不杀进程-杀进程不会进入Activity onDestroy生命周期
//activity.moveTaskToBack(true);-回到桌面
}
return 2000;
}
-
BasisActivity子类onBackPressed调用quitApp
@Override
public void onBackPressed() {
quitApp();
}
- 1、至少使用 FastRetrofit.getInstance().setBaseUrl(BuildConfig.BASE_URL) 设置全局网络请求BaseUrl
- 2、其它参数如设置超时-setTimeout、添加统一请求头addHeader、设置日志打印-setLogEnable、设置打印json格式化日志-setLogJsonEnable等
- 3、其它配置可通过getOkHttpClientBuilder获取OkHttpClient.Builder进行个性化定制如添加cookie拦截器
FastRetrofit提供方法名-method模式及特定header模式两种模式进行多BaseUrl设置,默认方法名-method模式优先,可通过FastRetrofit.getInstance().setHeaderPriorityEnable(true)设置特定header模式优先,开发者根据项目情况自行选择 原理都是在通过设置OkHttpClient.Builder添加拦截器,重定向请求Url达到效果 其中特定header模式参考文章解决Retrofit多BaseUrl及运行时动态改变BaseUrl?在此感谢
- 方法名-method模式,通过Map 对象进行保存method与BaseUrl对应关系 method作为key
FastRetrofit.getInstance()
.putBaseUrl(method,baseUrl);
- 特定header模式,通过Service 设置特定header 给一类key的方法使用同一BaseUrl 1、Service 配置 @Headers({FastRetrofit.BASE_URL_NAME_HEADER +Key}) 其中 FastRetrofit.BASE_URL_NAME_HEADER 为固定,Key必须与FastRetrofit初始化配置一致,二者缺一不可
/**
* 检查应用更新--同时设置了Method及Header模式重定向请求Url,默认Method优先;
* 可通过{@link FastRetrofit#setHeaderPriorityEnable(boolean)}设置Header模式优先
*
* @param map
* @return
*/
@GET(ApiConstant.API_UPDATE_APP)
@Headers({FastRetrofit.BASE_URL_NAME_HEADER + ApiConstant.API_UPDATE_APP_KEY})
Observable<UpdateEntity> updateApp(@QueryMap Map<String, Object> map);
}
2、FastRetrofit初始化配置
FastRetrofit.getInstance()
//设置Header模式优先-默认Method方式优先
.setHeaderPriorityEnable(true)
.putHeaderBaseUrl(ApiConstant.API_UPDATE_APP_KEY, BuildConfig.BASE__UPDATE_URL);
获取FastRetrofit里的OkHttpClient.Builder对象并添加拦截器,可以实现拦截cookie等功能
- 添加cookie拦截器
//添加登录Cookie拦截器
FastRetrofit.getOkHttpClientBuilder()
.addInterceptor(new CookieInterceptor());
/**
* @Author: AriesHoo on 2018/11/22 17:58
* @E-Mail: AriesHoo@126.com
* @Function: 拦截登录返回的cookie信息
* @Description:
*/
public class CookieInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
List<String> mCookieList = response.headers("Set-Cookie");
//保存Cookie
if (!mCookieList.isEmpty() && request.url().toString().endsWith(ApiConstant.API_USER_LOGIN)) {
StringBuilder sb = new StringBuilder();
for (String cookie : mCookieList) {
//注意Cookie请求头字段中的每个Cookie之间用逗号或分号分隔
sb.append(TextUtils.isEmpty(sb.toString()) ? cookie : "," + cookie);
}
UserHelper.setCookie(sb.toString());//保存cookie
Log.e(CookieInterceptor.class.getSimpleName(), "intercept: url : " + request.url() + ";cookie:" + sb.toString());
}
return response;
}
}
- 添加cookie 到统一header
/**
* 将Cookie添加到网络请求header中
*/
public static void addCookie() {
String cookieStr = UserHelper.getCookie();
if (!TextUtils.isEmpty(cookieStr)) {
FastRetrofit.getInstance().addHeader("Cookie", cookieStr);
}
}
该功能需配合RxJava操作符retryWhen实现,传入FastRetryWhen即可,可设置重试时间ms及重试次数,如果不满足需求可参考自己修改;建议在请求基类设置,这样就不用每个请求都添加
protected <T> Observable<T> transform(Observable<BaseEntity<T>> observable) {
return observable
//其它处理
.retryWhen(new FastRetryWhen())
//其它处理
;
}
该功能配合FastDownloadObserver以实现下载文件路径设置及进度监听; 该功能算是简单示例,仅供参考
mDownloadObserver = new FastDownloadObserver(fileName, finalMProgressDialog, isRangeEnable) {
@Override
public void onSuccess(File file) {
//FastFileUtil.installApk(file);//下载成功
}
@Override
public void onFail(Throwable e) {
//错误
}
@Override
public void onProgress(float progress, long current, long total) {
//下载进度
};
FastRetrofit.getInstance().downloadFile(entity.url, header)
.compose(((RxAppCompatActivity) activity).bindUntilEvent(ActivityEvent.DESTROY))
//可自定义保存路径默认//storage/emulated/0/Android/data/<package-name>/cache/xxx/
.subscribe(mDownloadObserver);
该功能配合FastUploadRequestBody及FastUploadRequestListener实现上传进度监听
private RequestBody getUploadRequestBody(File file, FastUploadRequestListener listener) {
if (listener == null) {
return RequestBody.create(MultipartBody.FORM, file);
}
return new FastUploadRequestBody(RequestBody.create(MultipartBody.FORM, file), listener);
}
private void uploadFile(List<String> listFile) {
if (listFile == null) {
return;
}
//其它设置-如设置上传进度Dialog
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM)
//额外参数
.addFormDataPart("xxKey", "xxValue");
//添加上传实体
for (int i = 0; i < listFile.size(); i++) {
File file = new File(listFile.get(i));
int finalI = i;
builder.addFormDataPart("uploadfiles", file.getName(), getUploadRequestBody(file, new FastUploadRequestListener() {
@Override
public void onProgress(float progress, long current, long total) {
//其它代码-可更新进度Dialog
//进度监听
LoggerManager.i("uploadFile", ":i=" + finalI + ";progress:" + progress + ";current:" + current + ";total:" + total);
}
@Override
public void onFail(Throwable e) {
LoggerManager.i("uploadFile", "error:" + e.getMessage());
}
}));
}
RequestBody requestBody = builder.build();
//上传地址需自行设置-可添加header
FastRetrofit.getInstance().uploadFile("http://XXXX/v1/ftp/upload-files", requestBody)
.compose(FastTransformer.switchSchedulers())
.subscribe(new FastLoadingObserver<ResponseBody>(new FastLoadDialog(mContext, 进度Dialog)) {
@Override
public void _onNext(ResponseBody entity) {
});
}
FastLib提供常用布局layout及Activity与Fragment,开发者可以快速实现部分常用UI效果
通过继承FastMainActivity 快速搭建UI。支持设置支付宝、QQ类似tab+Fragment 也支持 微信类似水平滚动切换Fragment
- 通过修改fast_dimens.xml 默认dimes属性值修改tab 主要尺寸属性
<!--主页tab高度-->
<dimen name="dp_tab_height">48dp</dimen>
<!--主页tab icon宽高-->
<dimen name="dp_tab_icon">24dp</dimen>
<!--主页tab 文字与icon边距-->
<dimen name="dp_tab_margin">0dp</dimen>
<!--主页tab文字字号-->
<dimen name="dp_tab_text_size">11dp</dimen>
<!--主页tab 上划线宽度-->
<dimen name="dp_tab_underline">0.5dp</dimen>
- 通过修改fast_colors.xml默认color值修改tab 主要颜色属性
<!--主页tab背景色-->
<color name="colorTabBackground">#FCFCFC</color>
<!--主页上划线颜色-->
<color name="colorTabUnderline">#d6d6d6</color>
<!--主页tab文字默认颜色-->
<color name="colorTabTextUnSelect">#909090</color>
<!--主页tab文字选中颜色-->
<color name="colorTabTextSelect">@color/colorTitleText</color>
- 通过setTabLayout方法参数修改CommonTabLayout所有属性
@Override
public void setTabLayout(CommonTabLayout tabLayout) {
tabLayout.getDelegate()
.setXXX();
}
- 通过getTabList初始化tab 及Fragment
@Override
public List<FastTabEntity> getTabList() {
ArrayList<FastTabEntity> tabEntities = new ArrayList<>();
tabEntities.add(new FastTabEntity(R.string.home, R.drawable.ic_home_normal, R.drawable.ic_home_selected, HomeFragment.newInstance()));
tabEntities.add(new FastTabEntity(R.string.activity, R.drawable.ic_activity_normal, R.drawable.ic_activity_selected, ActivityFragment.newInstance()));
tabEntities.add(new FastTabEntity(R.string.mine, R.drawable.ic_mine_normal, R.drawable.ic_mine_selected, MineFragment.newInstance()));
return tabEntities;
}
- 通过isSwipeEnable配置是否支持水平滑动切换Fragment,return true表示支持滑动切换
@Override
public boolean isSwipeEnable() {
return false;
}
- 通过重写onTabSelect方法回调tab选中的position
@Override
public void onTabSelect(int position) {
}
- 通过重写onTabReselect回调tab 选中position 又被点击;用于开发者实现刷新列表或回到顶部功能
@Override
public void onTabReselect(int position) {
}
通过继承FastTitleActivity/FastTitleFragment快速实现带TitleBarView的Activity/Fragment
- 继承FastTitleActivity/FastTitleFragment并通过 getContentLayout() 返回layout
@Override
public int getContentLayout() {
return R.layout.activity_xxx;
}
- 复用fast_layout_title_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/fast_layout_title_bar"/>
</LinearLayout>
- 通过setTitleBar设置本Activity/Fragment 特殊处理;如全局TitleBarView 为白色背景,当前Activity/Fragment需要设置渐变色背景、全局返回箭头为深色、当前Activity/Fragment需要设置成白色等。
@Override
public void setTitleBar(TitleBarView titleBar) {
titleBar.setLeftTextDrawable(R.drawable.ic_back_white)
.setStatusBarLightMode(false)
.setTitleMainTextColor(Color.WHITE)
.setBgResource(R.drawable.shape_qq_bg);
}
-
2.2.13版本新增通过实现 IFastTitleBarView接口以实现全局TitleBarView设置功能-其它和继承 FastTitleActivity/FastTitleFragment 效果一致;xml仍需自己设置TitleBarView;按需使用
通过继承FastTitleRefreshLoadFragment/FastRefreshLoadActivity快速搭建相关UI页面;不需TitleBarView 的Fragment继承FastRefreshLoadFragment即可/不需TitleBarView 的Activity layout不添加TitleBarView即可。
-
getContentLayout设置layout; 带TitleBarView可复用fast_layout_title_refresh_recycler.xml不带可复用fast_layout_refresh_recycler.xml
-
getAdapter 返回适配器
@Override
public BaseQuickAdapter<SubjectsEntity, BaseViewHolder> getAdapter() {
mAdapter = new SubjectMovieAdapter(ApiConstant.API_MOVIE_TOP.equals(mUrl));
return mAdapter;
}
- loadData(int page) 用于调用接口请求数据
@Override
public void loadData(int page) {
//接口最大支持单页100
mDefaultPageSize = 15;
ApiRepository.getInstance().getMovie(mUrl, page * mDefaultPage, mDefaultPageSize)
.compose(bindUntilEvent(FragmentEvent.DESTROY))
.subscribe(new FastObserver<BaseMovieEntity>(getIHttpRequestControl()) {
@Override
public void _onNext(BaseMovieEntity entity) {
LoggerManager.i("url:" + mUrl);
mStatusManager.showSuccessLayout();
FastManager.getInstance().getHttpRequestControl().httpRequestSuccess(getIHttpRequestControl(), entity == null || entity.subjects == null ? new ArrayList<>() : entity.subjects, null);
}
});
}
- 默认支持上拉刷新及自动加载下一页,会回调loadData(int page) 可通过isRefreshEnable及isLoadMoreEnable禁用;
@Override
public boolean isRefreshEnable() {
return false;
}
@Override
public boolean isLoadMoreEnable() {
return false;
}
- 列表默认竖直列表,如需更改通过getLayoutManager返回即可
@Override
public RecyclerView.LayoutManager getLayoutManager() {
return new LinearLayoutManager(mContext,RecyclerView.HORIZONTAL,false);
}
- 刷新头和加载更多默认通过全局设置,可通过getRefreshHeader及getLoadMoreView个性化
@Override
public RefreshHeader getRefreshHeader() {
return new ClassicsHeader(mContext);
}
@Override
public LoadMoreView getLoadMoreView() {
return new SimpleLoadMoreView();
}
- 可通过onItemClicked回调Item点击事件;可通过isItemClickEnable禁用 列表Item事件,当然禁用后不会有onItemClicked回调
@Override
public void onItemClicked(BaseQuickAdapter<SubjectsEntity, BaseViewHolder> adapter, View view, int position) {
super.onItemClicked(adapter, view, position);
WebViewActivity.start(mContext, adapter.getItem(position).alt);
}
@Override
public boolean isItemClickEnable() {
return super.isItemClickEnable();
}
通过继承FastWebActivity快速实现应用内通过WebView打开网页Activity
- 建议AndroidManifest添加configChanges如网页有视频横屏时Activity 不会销毁重建
<!-- 应用内浏览器 -->
<activity
android:name=".module.WebViewActivity"
android:configChanges="locale|layoutDirection|mcc|mnc|orientation|screenSize"
android:hardwareAccelerated="true"
android:label="@string/fast_loading"/>
- 通过getProgressColor更改进度条颜色,默认为 R.color.colorTitleText ;通过getProgressHeight进度条高度,默认 3dp
@Override
protected int getProgressColor() {
return super.getProgressColor();
}
@Override
protected int getProgressHeight() {
return super.getProgressHeight();
}
- 通过setAgentWeb(AgentWeb.CommonBuilder mAgentBuilder)设置,支持下载进度监听、权限监听等。具体参考AgentWeb-官方文档 通过setAgentWeb(AgentWeb mAgentWeb),可获取 WebView 做类似 长按图片下载功能 等
@Override
protected void setAgentWeb(AgentWeb.CommonBuilder mAgentBuilder) {
super.setAgentWeb(mAgentBuilder);
}
@Override
protected void setAgentWeb(AgentWeb mAgentWeb) {
super.setAgentWeb(mAgentWeb);
WebView mWebView = mAgentWeb.getWebCreator().getWebView();
mWebView.setOnLongClickListener(v -> {
WebView.HitTestResult hitTestResult = mWebView.getHitTestResult();
if (hitTestResult == null) {
return false;
}
//处理长按事件-可做长按下载图片功能
return true;
});
}
2.2.13 版本 抽离 IFastRefreshView 接口 Activity/Fragment 只需实现接口 IFastRefreshView ,用户只需在 onRefresh 回调进行相关操作即可
/**
* 获取下拉刷新头布局 建议通过{@link #setRefreshLayout(SmartRefreshLayout)} {@link SmartRefreshLayout#setRefreshHeader(RefreshHeader)}修改
*
* @return 下拉刷新头
*/
@Deprecated
default RefreshHeader getRefreshHeader() {
return null;
}
/**
* 需要下拉刷新的布局 --可以是Activity根布局、Fragment 不要传根布局(除非根布局为SmartRefreshLayout)
*
* @return
*/
default View getContentView() {
return null;
}
/**
* 是否支持下拉刷新功能
*
* @return
*/
default boolean isRefreshEnable() {
return true;
}
/**
* 回调设置的SmartRefreshLayout
*
* @param refreshLayout
*/
default void setRefreshLayout(SmartRefreshLayout refreshLayout) {
}
特别提醒 :因FastLib默认以 Activity/Fragment 根布局 进行查找 SmartRefreshLayout ,如查找不到会默认将根布局从通过 getParent() 获取父容器然后根布局移除然后新建 SmartRefreshLayout 作为根布局 将原始根布局作为 SmartRefreshLayout 的唯一子view以达到实现下拉刷新的目的;但是Fragment 根布局 获取不到父容器 getParent() 返回为null,故如在Fragment使用下拉刷新有两种方式 一、Fragment 根布局为 SmartRefreshLayout 二、Fragment 根布局不为 SmartRefreshLayout 需重写 IFastRefreshView View getContentView() 返回需包裹的View 对象,具体可参看 Demo MineFragment ; Activity 无任何限制
此处介绍
FastLib及UIWidget:widget-core中常用工具类,其它少有使用的不做介绍
FastLib提供;系统Toast 工具单例模式封装,仍然存在权限关闭Toast无法弹出问题,如开发者要解决权限问题 推荐DToast、smart-show(SmartToast部分)
- show(int content) 普通
- show(CharSequence content)
- showSuccess(int msg) 成功
- showSuccess(CharSequence msg)
- showFailed(int msg) 失败
- showFailed(CharSequence msg)
- showWarning(int msg) 警告
- showWarning(CharSequence msg)
FastLib提供;SharedPreferences 暂存数据工具类,getSharedPreferences 参数那么 默认为应用包名
- put(Context context, String key, Object object) 存放数据
- Object get(Context context, String key, Object def) 取数据
- boolean remove(Context context, String key) 根据key清除数据
- boolean clearAll(Context context) 清除所有暂存数据
- boolean contains(Context context, String key) 检查是否存有key对应数据
- Map<String, ?> getAll(Context context) 获取所有暂存数据
FastLib提供; 尺寸获取及转换工具,使用Resources.getSystem()无需传入Context
- int getScreenWidth() 获取屏幕宽度
- int getScreenHeight() 获取屏幕高度
- int px2dp(float pxValue) px转dp
- int dp2px(float dpValue) dp转px
- int px2sp(float pxValue) px转sp
- int sp2px(float spValue) sp转px
FastLib提供;快速格式化工具,包括时间格式化、内存单位格式化、double保留几位小数等功能
- String formatTime(long time, String format) 格式化时间 yyyy-MM-dd HH:mm:ss
- String formatTime(Date time, String format) 格式化时间 yyyy-MM-dd HH:mm:ss
- String formatDataSize(long dataSize) 格式化内存单位四舍五入保留两位小数
- String formatDataSize(long dataSize, String pattern) 格式化内存单位四舍五入 pattern格式 "###.00"
- String formatDoubleSize(double value, int maxLength) 四舍五入保留 maxLength位小数
- String formatDoubleSize(double value, int maxLength, int roundingMode) 保留 maxLength位小数 参看RoundingMode
FastLib提供; Snackbar快速设置工具,链式调用
- SnackBarUtil with(@NonNull final View mParent) 依赖View
- setMessage(@NonNull final CharSequence msg) 设置信息
- setMessageColor(@ColorInt final int color) 设置信息颜色
- setBgColor(@ColorInt final int color) 设置背景色
- setDuration(@Duration final int duration) 设置显示时间 Duration#LENGTH_INDEFINITE 一直 Duration#LENGTH_INDEFINITE短时 Duration#LENGTH_LONG 长时
- setAction(@NonNull final CharSequence text, @NonNull final View.OnClickListener listener) 设置按钮、点击事件
- setAction(@NonNull final CharSequence text, @ColorInt final int color, @NonNull final View.OnClickListener listener) 设置按钮、文本颜色、点击事件
- setBottomMargin(@IntRange(from = 1) final int bottomMargin) 设置底边距
- show() 展示Snackbar
- showSuccess() 展示预设成功Snackbar 会改变前面设置的文字、背景、按钮颜色
- showWarning() 展示预设警告Snackbar 会改变前面设置的文字、背景、按钮颜色
- showError() 展示预设错误Snackbar 会改变前面设置的文字、背景、按钮颜色
- dismiss() 主动关闭Snackbar
FastLib提供;包含应用常用功能如:Activity跳转、获取版本号等
- CharSequence getAppName(Context context) 获取应用名称
- int getRandom(int max, int min) 获取 min - max的随机数
- View getRootView(Activity activity) 获取Activity 根布局
- String getVersionName(Context context) 获取版本名
- int getVersionCode(Context context) 获取版本号
- boolean isClassExist(String className) 获取某个Class是否存在 用于判断是否导入某个库
- boolean isRunningForeground(Context context, String packageName) 是否某个应用前台运行
- boolean isTablet(Context context) 是否平板设备
- void jumpMarket(Context mContext, String packageName) 跳转应用市场某个应用详情页-用于评价
- void setActivitySingleFlag(int flag) 设置只启动Activity 一个的flag
- void startActivity(Context context, Class<? extends Activity> activity, Bundle bundle, boolean isSingle) 跳转Activity
- void startShareText(Context context, String text, CharSequence title) 调用系统分享 文本
- void copyToClipboard(Context context, String str) 拷贝到粘贴板
FastLib提供;应用Activity堆栈工具类,通过监听Activity生命周期添加、移除故可管理应用所有Activity包括三方库;单例模式
- Stack getStack() 获取堆栈
- Activity getCurrent() 获取栈顶 Activity
- Activity getPrevious() 获取前一个Activity
- Activity getActivity(Class cls) 根据Class 获取Activity ,如果是
- FastStackUtil push(Activity activity) 入栈
- FastStackUtil pop(Activity activity, boolean isFinish) 出栈 isFinish true 调用finish方法
- FastStackUtil popAll() 清空栈 如退出应用 重新登录
- FastStackUtil popAllExceptCurrent(Class cls) 将堆栈里退回某个Activity为止
- FastStackUtil popAllExceptCurrent() 只留下栈顶一个Activity
- FastStackUtil exit(boolean kill) 退出应用 kill true 杀进程
FastLib提供;常用 Glide 加载图片方式
- setPlaceholderColor(@ColorInt int placeholderColor) 设置默认占位ColorDrawable
- setPlaceholderRoundRadius(float placeholderRoundRadius) 设置圆角弧度
- setCirclePlaceholder(int circlePlaceholder) 设置圆形占位图资源id
- setCirclePlaceholder(Drawable circlePlaceholder) 设置圆形占位图Drawable
- setCommonPlaceholder(int commonPlaceholder) 设置普通占位图资源id
- setCommonPlaceholder(Drawable commonPlaceholder) 设置普通占位图Drawable
- setRoundPlaceholder(int roundPlaceholder) 设圆角占位图资源id
- setRoundPlaceholder(Drawable roundPlaceholder) 设置圆角占位图Drawable
- loadImg(Object obj, ImageView iv, Drawable placeholder) 加载普通图片并设置占位Drawable
- loadImg(Object obj, ImageView iv, int placeholderResource) 加载普通图片并设置占位图资源id
- loadImg(Object obj, ImageView iv) 加载普通图片使用全局设置默认占位图
- loadRoundImg(Object obj, ImageView iv, float dp, Drawable placeholder, boolean isOfficial) 加载圆角图 设置圆角幅度、占位图Drawable 、设置是否官方圆角方式
- loadRoundImg(Object obj, ImageView iv, float dp, boolean isOfficial) 加载圆角图 设置圆角幅度、默认占位图 、设置是否官方圆角方式
- loadRoundImg(Object obj, ImageView iv, float dp) 加载圆角图 设置圆角幅度、默认占位图 、默认官方圆角方式
- loadRoundImg(Object obj, ImageView iv, boolean isOfficial) 加载圆角图 默认幅度、默认占位图 、设置是否官方圆角方式
- loadRoundImg(Object obj, ImageView iv) 加载圆角图 默认幅度、默认占位图、默认官方圆角方式
- loadCircleImg(Object obj, ImageView iv, Drawable placeholder) 加载圆角图 设置占位图
- loadCircleImg(Object obj, ImageView iv) 加载圆形图片、默认占位图
FastLib提供;Logger 常用模式,通过3种init方式设置TAG、是否打印、扩展配置,全局TAG,支持设置单独TAG
- 具体方法同Logger这里不做方法罗列
FastLib提供;TabLayoutManager 支持快速设置TabLayout三种layout SlidingTabLayout、CommonTabLayout、SegmentTabLayout 配合ViewPager实现水平滑动Fragment,减少重复代码量;快速实现主页滑动切换FragmentFastMainActivity亦是使用本工具类实现
- setCommonTabData(FragmentActivity activity, final CommonTabLayout tabLayout, final ViewPager viewPager, ArrayList tabs, List fragments, final OnTabSelectListener listener) 快速设置CommonTabLayout 滑动并支持position变化监听
- setSlidingTabData(FragmentActivity activity, SlidingTabLayout tabLayout, ViewPager viewPager, List tittles, List fragments, OnTabSelectListener listener) 快速设置SlidingTabLayout 滑动并支持position变化监听
- setSegmentTabData(Fragment fragment, final SegmentTabLayout tabLayout, final ViewPager viewPager, String[] titles, List fragments, final OnTabSelectListener listener) 快速设置SegmentTabLayout 滑动支持支持position变化监听
UIWidget:widget-core提供;状态栏文字颜色处理相关工具
- int setStatusBarLightMode(Activity activity) 设置状态栏浅色模式(状态栏文字黑色)返回值 0-不支持;1-MIUI;2-FlyMe ;3-Android M
- int setStatusBarDarkMode(Activity activity) 设置状态栏深色模式(状态栏文字白色)返回值 0-默认值本身就不支持黑白色变化默认白色文字;1-MIUI;2-FlyMe ;3-Android M
- boolean isSupportStatusBarFontChange 判断是否支持状态栏文字颜色变换
- int getStatusBarHeight() 获取状态栏高度
UIWidget:widget-core提供;设置Activity 沉浸状态栏效果帮助类,链式调用;未做撤销方法建议一个Activity只做一次操作
- StatusViewHelper with(Activity activity) 传入目标Activity
- setLogEnable(boolean logEnable) 设置是否打印内部日志
- setControlEnable(boolean controlEnable) 是否控制状态栏沉浸--实际都是沉浸了,如果传入false 即增加一层黑色View 被状态栏遮住
- setTransEnable(boolean transEnable) 是否全透明 半透明效果为5.0 MD效果 增加一个102 透明度的黑色Drawable
- setPlusStatusViewEnable(boolean plusStatusViewEnable) 是否增加一个状态栏高度View 用于状态栏遮住 默认 增加view padding以避免被遮住
- setStatusViewColor(int StatusViewColor) 状态栏View 颜色 用于设置半透明效果 setPlusStatusViewEnable为true才有效果
- setStatusViewDrawable(Drawable drawable) 状态栏View 背景Drawable用于设置半透明效果 setStatusViewColor也是调用该方法设置ColorDrawable
- setStatusLayoutColor(int StatusLayoutColor)状态栏View 父容器 颜色
- setStatusLayoutDrawable(Drawable StatusLayoutDrawable) 状态栏View 父容器背景Drawable setStatusLayoutColor也是调用该方法设置ColorDrawable
- setTopView(View view, boolean enable) 设置顶部View 状态栏下边View,第二个参数 是否设置marginTop 默认通过paddingTop 如地图顶部为EditText 可设置true
- void init() 执行效果 ;以上设置参数最终需要调用init()方法才会支持最终操作
UIWidget:widget-core提供;用于检测ROM厂商 国内ROM 主要通过 android.os.SystemProperties 判断
- boolean isMIUI() 是否MIUI-小米ROM
- String getMIUIVersion() 获取MIUI版本
- int getMIUIVersionCode() 获取MIUI版本号 用于大小判断
- boolean isEMUI() 是否EMUI -华为/荣耀 ROM
- String getEMUIVersion() 获取EMUI版本
- boolean isOPPO() 是否OPPO ROM
- String getOPPOVersion() 获取OPPO版本
- boolean isVIVO() 是否VIVO ROM
- String getVIVOVersion() 获取VIVO 版本
- boolean isSmartisan() 是否smartisanUI-锤子ROM
- String getSmartisanVersion() 获取smartisan版本
- boolean isFlyme() 是否Flyme UI -魅族ROM
- String getFlymeVersion() 获取Flyme版本
- int getFlymeVersionCode 获取Flyme版本号
- boolean isQiKu() 是否奇酷UI-360ROM
- String getQiKuVersion() 获取奇酷UI版本
- String getSystemProperty(String key, String defaultValue) 扩展 通过获取android.os.SystemProperties值判断是否某个ROM
- boolean isRom(String key) 通过getSystemProperty 判断是否为某个ROM
UIWidget:widget-core提供;导航栏相关值获取工具
- boolean isOpenFullScreenGestures(Context context) 是否开启全面屏手势-支持小米 VIVO 华为 三星
- boolean hasNavBar(Activity activity) 是否有导航栏 开启全面屏返回false
- int getNavigationBarHeight(Activity activity) 获取导航栏高度 可设置导航栏不管是否开启都会获取到值'
- boolean isFullScreenDevice(Context context) 通过手机纵横比判断是否全面屏 阈值为1.97f
- float getAspectRatio(Context context) 获取手机纵横比
UIWidget:widget-core提供;虚拟导航栏沉浸帮助类配合NavigationBarUtil、配合KeyboardHelper 控制底部输入框,链式调用;未设置复位方式建议调用一次即可
- NavigationViewHelper with(Activity activity) 传入需要控制的Activity
- setLogEnable(boolean logEnable) 是否打印内部日志
- setControlEnable(boolean controlEnable) 是否控制导航栏 -实际都是沉浸了的,通过设置黑色View 用于导航栏遮住
- setTransEnable(boolean transEnable) 是否全透明 半透明效果为102透明的黑色
- setPlusNavigationViewEnable(boolean plusNavigationViewEnable) 是否增加View 用于导航栏遮住
- setControlBottomEditTextEnable(boolean controlBottomEditTextEnable) 是否控制底部输入框 -通过KeyboardHelper实现
- setOnKeyboardVisibilityChangedListener(KeyboardHelper.OnKeyboardVisibilityChangedListener listener) 设置键盘开启关闭监听 setControlBottomEditTextEnable 为true才会有用
- setNavigationViewColor(int navigationViewColor) 设置导航栏View 颜色 setPlusNavigationViewEnable 为true才有效果
- setNavigationViewDrawableTop(Drawable drawable) 设置导航栏View 背景Drawable setNavigationViewColor 实际调用该方法传入ColorDrawable
- setNavigationLayoutColor(int navigationLayoutColor) 设置导航栏View父容器背景颜色
- setNavigationViewDrawable(Drawable drawable) 设置导航栏View父容器背景Drawable setNavigationLayoutColor实际调用该方法传入ColorDrawable
- setBottomView(View view, boolean enable) 设置底部View 默认Activity根布局 第二参数为 是否设置marginTop 如底部是一个 Button 可设置true
- void init() 执行效果;以上设置参数最终需要调用init()方法才会支持最终操作
UIWidget:widget-core提供;用于控制底部软件盘弹起-链式调用及静态方法操作软键盘等功能帮助类;
- KeyboardHelper with(Activity activity) 传入控制Activity
- setLogEnable(boolean logEnable) 设置是否打印内部日志
- setOnKeyboardVisibilityChangedListener(OnKeyboardVisibilityChangedListener listener) 设置软键盘开启关闭监听
- setEnable() 设置监听 通过 widow.setSoftInputMode WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE 控制软键盘模式--推荐使用
- setEnable(int mode) 自定义传入键盘模式
- setDisable 清除键盘模式并关闭View.getViewTreeObserver.removeOnGlobalLayoutListener监听
以下为静态方法用于软键盘常用操作
- closeKeyboard(View view) 关闭软键盘
- closeKeyboard(Activity activity) 关闭软键盘
- closeKeyboard(Dialog dialog) 关闭软件盘
- openKeyboard(final EditText editText, long delay) 延时打开软键盘
- openKeyboard(EditText editText) 打开软键盘 默认300 ms
- toggleKeyboard(Activity activity) 切换软键盘开启状态
- handleAutoCloseKeyboard(boolean isAutoCloseKeyboard, View currentFocusView, MotionEvent motionEvent, Object dialogOrActivity) 处理点击非EditText 区域关闭软键盘方法一般在Activity dispatchTouchEvent 派发触摸事件中调用
UIWidget:widget-core提供;用于查找某个ViewGroup下View 功能
- T getTargetView(View rootView, Class<? extends View> targetClass, int id) 查询目标View 下某个id的某类View 根据目标Class查询
TitleBarView titleBar = FindViewUtil.getTargetView(rootView, TitleBarView.class, R.id.titleBar_headFastLib);
- T getTargetView(View rootView, Class<? extends View> targetClass) 查询目标View下 第一个目标Class 的View
TitleBarView titleBar = FindViewUtil.getTargetView(rootView, TitleBarView.class);
- T getTargetView(View rootView, int id) 查询目标View 下某个id View
TitleBarView titleBar = FindViewUtil.getTargetView(rootView, R.id.titleBar_headFastLib);
BasisFragment重新定义了对用户可见性回调,无需关心Fragment是否在ViewPager里,只需在onVisibleChanged执行相关代码即可 状态栏文字颜色通过StatusBarUtil对应方法实现切换
@Override
protected void onVisibleChanged(boolean isVisibleToUser) {
super.onVisibleChanged(isVisibleToUser);
if (isVisibleToUser) {
StatusBarUtil.setStatusBarLightMode(activity);
}
}
严格说来该情况并非
FastLib需要解决的问题,实际开发中大多也不会管导航栏问题。不过笔者开发中遇到过在此分享下,开发者按需使用即可
- 将图片设置为Activity根布局背景;该方式适配性差容易出现图片拉伸变形问题
mContentView.setBackgroundResource(R.drawable.img_bg_login);
- 首先给Activity根布局设置纯色布局、给ImageView设置 scaleType一个不会拉伸的模式如fitCenter;然后getWindow().getDecorView().setSystemUiVisibility 最后 设置状态栏及导航全透明即可。建议在onWindowFocusChanged回调当获取焦点时执行
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
}
感谢FastLib所使用到的所有三方库的 Author, 以及所有为 Open Sourece 做无私贡献的 Developer 和 Organizations。
如果您认可 FastLib , 并使用FastLib 在实际开发中切实的提升了您的工作效率和开发能力, 请您点击右上角 Star 支持一下谢谢!
Work Harder,Live Better!
- 概述
- 主要功能
- 包结构
- 三方库一览
- 一 开发准备
- 1.1 Gradle配置
- 1.2 导入FastLib 及三方库
- 1.3 Lambda配置
- 二 初始化
- 2.1 LoggerManager初始化
- 2.2 FastManager初始化
- 2.2.1 最简初始化
- 2.2.2 详细初始化
- 2.2.3 Activity滑动返回SwipeBackLayout设置
- 2.2.4 标题栏TitleBarView设置
- 2.2.5 下拉刷新头SmartRefreshLayout设置
- 2.2.6 Adapter 加载更多BaseQuickAdapter设置
- 2.2.7 RecyclerView 设置
- 2.2.8 多状态布局MultiStatusView设置
- 2.2.9 网络请求成功/失败结果处理
- 2.2.10 加载等待Dialog设置
- 2.2.11 Activity/Fragment 生命周期设置-禁用系统截屏等
- 2.2.12 Activity 按键监听-控制系统音量等
- 2.2.13 Activity事件派发-点击非EditText关闭软键盘等
- 2.2.14 Toast效果设置
- 2.2.15 主页退出程序设置
- 2.3 FastRetrofit初始化
- 2.3.1 多BaseUrl 设置
- 2.3.2 添加拦截器
- 2.3.3 重试机制
- 2.3.4 带进度监听的文件下载-示例
- 2.3.5 带进度监听的文件上传
- 三 快速搭建UI
- 四 工具类
- 4.1 ToastUtil -系统toast工具
- 4.2 SPUtil-SharedPreferences工具
- 4.3 SizeUtil-尺寸转换工具
- 4.4 FastFormatUtil-格式转换工具
- 4.5 SnackBarUtil-Snackbar工具
- 4.6 FastUtil-app常用工具
- 4.7 FastStackUtil-应用Activity堆栈管理工具)
- 4.8 GlideManager-Glide加载工具
- 4.9 LoggerManager-Logger日志打印工具
- 4.10 TabLayoutManager-TabLayout使用工具
- 4.11 StatusBarUtil-状态栏工具
- 4.12 StatusViewHelper-状态栏沉浸帮助类
- 4.13 RomUtil-ROM判断工具
- 4.14 NavigationBarUtil-导航栏工具
- 4.15 NavigationViewHelper-导航栏沉浸帮助类
- 4.16 KeyboardHelper-软键盘帮助类/工具
- 4.17 FindViewUtil-查找子View工具
- 五 特殊情况处理
- 结语

















