BASE_PROJECT
目前开发中,暂未发布
项目介绍
本框架旨在使用最新流行框架,并尽可能的保证稳定性和扩展性的情况下
,搭建一个快速开发的模板代码,方便相关开发人员迅速上手,并有效完成工作。
需要开发者有Kotlin使用经验并了解RxJava相关使用经验。
码云:https://gitee.com/ccdy00/BASE_PROJECT
RxJava的学习资料中,写的比较好的推荐如下:
RxJava详解
软件架构
本框架架构如下:
- 使用Retrofit作为网络请求框架
- 使用GreenDao3.2.2版本作为数据库保存框架
- 使用Rxjava和RxAndroid作为代码框架
- 使用MVP模式作为开发框架
- 使用Kotlin作为开发语言
- 使用ACache作为文件格式缓存工具
- 使用Glide作为图片处理框架
- 使用RxPermissions作为权限管理框架
- 使用Bugly作为异常管理工具和版本更新框架
- 使用umeng作为第三方分享和登录框架
- 集成一些常用第三方功能,如支付,京东和淘宝跳转等
- 使用shell脚本进行dimens的px的适配处理使用介绍
- 集成美团walle的多渠道打包,使用pack.sh脚本即可,具体使用见tinker/README.md
- 集成阿里百川和京东sdk,用作app跳转,不需要的可以取消集成,具体使用见WebFragment使用范例
使用说明
以下为简要使用说明,如果不清楚的可以联系我或者看示例模板代码
本框架的思想是让参与者能快速完成相关业务,所以相关功能方法的使用尽量的直接有效。
使用本框架建议非必要情况,所有窗口均使用Fragment即可,相关跳转均已做好内部封装,极大简化相关开发步骤。
- ===MVP模板使用===:
如果是使用MVP模式,Activity需要继承MVPActivity,Fragment需要继承MVPFragment.
如果不需要使用MVP模式,继承BaseNoPresenterActivity或者BaseNoPresenterFragment即可。
两种情况下都做了模板代码,实现对应方法即可。
举个例子:
现在有个界面A,类结构如下:
1531968050586.jpg
一般一个业务界面需要三个类:
AFragment:主界面,用于处理界面显示
package com.congdy.baseproject.bisa
import com.congdy.baseproject.R
import com.congdy.baseproject.module.WeatherModule
import com.congdy.common.anko.onSingleClick
import com.congdy.common.annotation.BindLayout
import com.congdy.common.annotation.StatusbarFullMode
import com.congdy.common.base.MvpFragment
import kotlinx.android.synthetic.main.fragment_main.*
import org.jetbrains.anko.support.v4.toast
@BindLayout(R.layout.fragment_main)
@StatusbarFullMode(true)
class AFragment :MvpFragment<Template.AView,APresenterImp>(),Template.AView {
override fun getMainDataBack(data: WeatherModule?) {
sample_text?.text = data.toString()
}
override fun getPresenterView(): Template.AView {
return this
}
override fun initView() {
toolbar()?.title = "afragment"
}
override fun initListener() {
sample_text?.onSingleClick {
mPresenter?.getMainData(mapOf("_" to "1381891660081"))
}
}
override fun initData() {
// mPresenter?.getMainData(mapOf("id" to "000"))
}
override fun onRequestStart() {
}
override fun onRequestError(e: String?) {
}
override fun onRequestComplete() {
}
override fun toastTo(e: String) {
toast(e)
}
override fun onBackPressed(): Boolean {
toast("onBackPressed")
return super.onBackPressed()
}
}
AFragmentImp:用于相关数据处理,如网络请求
package com.congdy.baseproject.bisa
import com.congdy.baseproject.module.WeatherModule
import com.congdy.baseproject.service.APIConfig
import com.congdy.common.http.HttpConfig
import com.congdy.common.http.RetrofitFactory
import com.trello.rxlifecycle2.android.ActivityEvent
class APresenterImp : Template.APresenter() {
override fun getMainData(maps: Map<String, String>?) {
/**
* 网络请求时需要知道以下数据
* 解析对象,请求api,相关参数,绑定窗口生命周期
*/
RetrofitFactory.doRequestOther<WeatherModule>(HttpConfig.GET,
APIConfig.MAIN_URL,
maps,
bindLifecycle(ActivityEvent.DESTROY), {
view?.onRequestStart()
view?.toastTo("onRequestStart")
}, {
view?.getMainDataBack(it)
view?.toastTo("getMainDataBack")
}, { c, m ->
view?.onRequestError(m)
view?.toastTo("$c $m")
}, {
view?.onRequestComplete()
view?.toastTo("onRequestComplete")
})
}
}
Template:用于MVP的接口模板
package com.congdy.baseproject.bisa
import com.congdy.baseproject.module.WeatherModule
import com.congdy.common.base.BasePresenter
import com.congdy.common.base.BaseView
/**
* MVP模式模板
* 用于配置相关功能模块的业务处理接口
*
* @author 陈聪 QQ617909447
* 简书:https://www.jianshu.com/u/e3a39f0af864
* @time 2018/6/29:下午2:22
*/
class Template {
interface AView : BaseView {
fun getMainDataBack(data: WeatherModule?)
fun toastTo(e:String)
}
abstract class APresenter : BasePresenter<AView>() {
abstract fun getMainData(maps: Map<String,String>?)
}
}
- ===网络请求的使用===:
网络请求使用的是Retrofit+Rxjava进行的封装,相关使用范例如下:
package com.congdy.baseproject.main
import com.congdy.baseproject.R
import com.congdy.baseproject.module.WeatherModule
import com.congdy.baseproject.service.APIConfig
import com.congdy.common.http.HttpConfig
import com.congdy.common.http.RetrofitFactory
import com.congdy.common.http.RetrofitFactory.doRequestObject
import com.congdy.common.http.RetrofitFactory.doRequestOther
import com.trello.rxlifecycle2.android.ActivityEvent
/**
* 网络请求示例
*
* @author 陈聪 QQ617909447
* 简书:https://www.jianshu.com/u/e3a39f0af864
* @time 2018/7/3:下午2:29
*/
class MainPresenterImp : Template.MainPresenter() {
override fun getMainData(maps: Map<String, String>?) {
//=================自定义请求情况下需要指定请求config参数=========================
RetrofitFactory.mHttpConfig = HttpConfig.Builder()
.setRootUrl("http://mobile.weather.com.cn")//设置请求域名
.setHeader(HashMap())//设置header数据
.isNeedSSL(false)//设置是否使用ssl
.setCertificate(R.raw.jhx)//设置这个必须先设置isNeedSSL(true),否则没有作用
.build()
doRequestOther<WeatherModule>(HttpConfig.GET, //请求方式
APIConfig.MAIN_URL,//请求api
maps, //请求数据
bindLifecycle(ActivityEvent.DESTROY), //绑定页面生命周期
{
view?.onRequestStart()
view?.toastTo("onRequestStart")
}, {
view?.getMainDataBack(it)
view?.toastTo("getMainDataBack")
}, { c, m ->
view?.onRequestError(m)
view?.toastTo("$c $m")
}, {
view?.onRequestComplete()
view?.toastTo("onRequestComplete")
})
//===================非自定义请求情况下直接请求即可======================
/**
* 网络请求时需要知道以下数据
* 解析对象,请求api,相关参数,绑定窗口生命周期
* 此方式需要与服务器订好相关协议,以BaseResponse进行封装
* 如果返回为单个数据使用doRequestObject方法
* 如果返回为集合数据使用doRequestArray方法
*/
//get请求方式
doRequestObject<WeatherModule>(HttpConfig.GET,//请求方式
APIConfig.MAIN_URL,//请求api
maps,//请求数据
bindLifecycle(ActivityEvent.DESTROY), //绑定页面生命周期
{
view?.onRequestStart()
view?.toastTo("onRequestStart")
}, {
view?.getMainDataBack(it?.data)
view?.toastTo("getMainDataBack")
}, { c, m ->
view?.onRequestError(m)
view?.toastTo("$c $m")
}, {
view?.onRequestComplete()
view?.toastTo("onRequestComplete")
})
}
}
- 列表展示的使用:
列表控件用的RecyclerView
刷新控件用的是SwipeRefreshLayout
加载更多功能用的是
集成于
compile "com.github.CymChad:BaseRecyclerViewAdapterHelper:$rootProject.ext.baseRecyclerViewAdapterHelperVersion"
完整使用流程如下:
ListShowFragment:
package com.congdy.baseproject.list
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.congdy.baseproject.R
import com.congdy.baseproject.module.ShopStore
import com.congdy.baseproject.utils.*
import com.congdy.common.anko.onSingleClick
import com.congdy.common.annotation.BindLayout
import com.congdy.common.base.MvpFragment
import com.congdy.common.widget.ItemDecoration
import kotlinx.android.synthetic.main.fragment_list.*
import org.jetbrains.anko.support.v4.dip
import org.jetbrains.anko.toast
/**
* 列表功能使用模板
*
* @author 陈聪 QQ617909447
* 简书:https://www.jianshu.com/u/e3a39f0af864
* @time 2018/7/19:上午11:01
*/
@BindLayout(R.layout.fragment_list)
class ListShowFragment : MvpFragment<Template.ListView, ListPresenterImp>(), Template.ListView {
private var showData: ArrayList<ShopStore>? = ArrayList()
private var mAdapter: BaseQuickAdapter<ShopStore, BaseViewHolder>? = null
private var pageIndex: Int = 1//当前数据页数
private val pageSize: Int = 20//默认每页显示数量
private var isfreshing = false
private var isloadmoreimg = false
override fun initView() {
toolbar()?.title = "列表数据加载示例"
initRecyclerView()
}
/**
*初始化列表
*/
private fun initRecyclerView() {
recycler_list.isNestedScrollingEnabled = false
recycler_list.layoutManager = LinearLayoutManager(context)
recycler_list.addItemDecoration(ItemDecoration(dip(2), ItemDecoration.HORIZONTAL_LIST))
refresh_layout.setOnRefreshListener {
goRefresh()
}
mAdapter = getAdapter()
mAdapter?.openLoadAnimation(BaseQuickAdapter.SLIDEIN_BOTTOM)
recycler_list.adapter = mAdapter
mAdapter?.setOnLoadMoreListener({
isloadmoreimg = true
getData()
}, recycler_list)
}
/**
* 进页面之后的加载数据操作
*/
override fun initData() {
goRefresh()
}
override fun getPresenterView(): Template.ListView {
return this
}
/**
* 获取到数据之后的返回显示
*/
override fun setListData(data: ArrayList<ShopStore>?, code: Int) {
when (code) {
REFRESH_DATA_SUCCESS -> {
refresh_layout.isRefreshing = false
if (!isfreshing) return
if (isloadmoreimg) isloadmoreimg = false
if (data != null && data?.size != 0) {
showData?.clear()
showData?.addAll(data)
mAdapter?.notifyDataSetChanged()
pageIndex++
} else if (showData != null && showData?.size!! > 0) {
pageIndex++
}
isfreshing = false
recycler_list?.visibility = if (showData == null || showData != null && showData?.size == 0) {
txt_empty_show?.text = "没有相关数据"
txt_empty_show?.onSingleClick { }
txt_empty_show?.visibility = View.VISIBLE
View.GONE
} else {
txt_empty_show?.visibility = View.GONE
View.VISIBLE
}
}
LOADMORE_DATA_SUCCESS -> {
mAdapter?.loadMoreComplete()
if (!isloadmoreimg) return
if (isfreshing) isfreshing = false
isloadmoreimg = false
if (data == null || data?.size == 0) {
mAdapter?.loadMoreEnd()
return
}
mAdapter?.loadMoreComplete()
mAdapter?.data?.addAll(data!!)
mAdapter?.notifyDataSetChanged()
pageIndex++
}
REFRESH_DATA_FAIL -> {
isfreshing = false
refresh_layout?.isRefreshing = false
if (showData == null || showData != null && showData?.size == 0) {
txt_empty_show?.visibility = View.VISIBLE
txt_empty_show?.text = "获取数据失败,请点击重试"
txt_empty_show?.onSingleClick {
txt_empty_show?.visibility = View.GONE
refresh_layout?.isRefreshing = true
goRefresh()
}
} else {
pageIndex++
context?.toast("获取数据失败,请稍后再试")
}
}
LOADMORE_DATA_FAIL -> {
isloadmoreimg = false
mAdapter?.loadMoreFail()
}
GET_DATA_COMPELET -> {
dismissLoadingDialog()
}
}
}
/**
* 刷新操作
*/
private fun goRefresh() {
if (isfreshing) return
isfreshing = true
pageIndex = 1
mAdapter?.loadMoreComplete()
getData()
}
/**
* 请求数据
*/
private fun getData() {
mPresenter?.getListData(mapOf(
"userLatitude" to "113.919779",
"userLongitude" to "22.560317",
"nowPage" to pageIndex.toString(),
"pageSize" to pageSize.toString()
)
)
}
override fun initListener() {
}
/**
* 店铺相关列表展示抽取
*/
private fun getAdapter(): BaseQuickAdapter<ShopStore, BaseViewHolder> {
return object : BaseQuickAdapter<ShopStore, BaseViewHolder>(R.layout.item_list_demo, showData) {
override fun convert(helper: BaseViewHolder, item: ShopStore) {
helper.setText(R.id.txt_list, item.businessName)
}
}
}
override fun onRequestStart() {
showLoadingDialog()
}
override fun onRequestError(e: String?) {
}
override fun onRequestComplete() {
dismissLoadingDialog()
}
}
ListPresenterImp:
package com.congdy.baseproject.list
import com.congdy.baseproject.module.ShopStore
import com.congdy.baseproject.service.APIConfig
import com.congdy.baseproject.utils.*
import com.congdy.common.http.HttpConfig
import com.congdy.common.http.RetrofitFactory.doRequestArray
import com.trello.rxlifecycle2.android.FragmentEvent
class ListPresenterImp : Template.ListPresenter() {
override fun getListData(maps: Map<String, String>?) {
/**
* 网络请求时需要知道以下数据
* 解析对象,请求api,相关参数,绑定窗口生命周期
*/
doRequestArray<ShopStore>(HttpConfig.GET, APIConfig.LIST_URL, maps, bindLifecycle(FragmentEvent.DESTROY), {
view?.onRequestStart()
}, {
if (maps?.get("nowPage") == "1") {
view?.setListData(it?.data, REFRESH_DATA_SUCCESS)
} else {
view?.setListData(it?.data, LOADMORE_DATA_SUCCESS)
}
}, { c, m ->
if (maps?.get("nowPage") == "1") {
view?.setListData(null, REFRESH_DATA_FAIL)
} else {
view?.setListData(null, LOADMORE_DATA_FAIL)
}
view?.onRequestError(m)
}, {
view?.setListData(null, GET_DATA_COMPELET)
view?.onRequestComplete()
})
}
}
Template:
package com.congdy.baseproject.list
import com.congdy.baseproject.module.ShopStore
import com.congdy.baseproject.module.WeatherModule
import com.congdy.common.base.BasePresenter
import com.congdy.common.base.BaseView
/**
* MVP模式模板
* 用于配置相关功能模块的业务处理接口
*
* @author 陈聪 QQ617909447
* 简书:https://www.jianshu.com/u/e3a39f0af864
* @time 2018/6/29:下午2:22
*/
class Template {
interface ListView : BaseView {
fun setListData(data: ArrayList<ShopStore>?, code:Int)
}
abstract class ListPresenter : BasePresenter<ListView>() {
abstract fun getListData(maps: Map<String,String>?)
}
}
- 图片加载的使用:
图片加载工具类为ImageLoaderUtil。
使用示例如下:
ImageLoaderUtil.loadImageByUrl(context,"图片链接", ImageView,圆角大小,默认图片)
有多种方法,可以根据需要选择使用。
- 智能控件的使用:
SmartButton:
- 缓存功能的使用:
用的CCache,可以保存String,Object,Bitmap,Drawable等。
使用方式如下:
CCache.get(CommonConfig.appContext).put(CURRENT_USER_ID, id)
- 数据库的使用:
数据库使用的是Greendao。
===build.gradle中的集成如下===
需要在build.gradle中集成库:implementation 'org.greenrobot:greendao:3.2.2'
另外需要指定相关数据库版本:
//此配置用来指定greendao数据库的相关配置
greendao{
schemaVersion 1
daoPackage 'com.congdy.common.greendao'//数据库操作类放置地址
targetGenDir 'src/main/java'
// schemaVersion: 数据库schema版本,也可以理解为数据库版本号
// daoPackage:设置DaoMaster 、DaoSession、Dao包名
// targetGenDir:设置DaoMaster 、DaoSession、Dao目录
}
===如何添加数据库表===
在自己的module包下正常创建要使用数据库保存的module(也称为bean)
如下:
对应成员变量需要添加相关注解,不用写对应的get和set方法,后续操作中会自动生成。
/**
* 用户信息保存类
* 使用了Greendao作为数据库框架
* 注意:保存对象必须使用java类,GreenDao目前不支持Kotlin
*
* @author 陈聪 2018-06-28 18:13
*/
@Entity
public class User {
@Id(autoincrement = true)
private long id = 0;
@Property
String dmid = "";
@Property
private String token = "";
@Property
private String loginAppid = "";
}
设置完成之后在Build下make project即可。之后在设置的数据库操作类放置地址下面会生成相关操作类。
===如何使用===
相关使用可以参照我的UserManager的使用方式,相关操作我封装到了GreenDBManager里面。
篇幅有限,相关增删改查可查看UserManager里面方法。
示例使用方式如下:
获取token:val token = UserManager.getUser()?.token
-
常用工具类介绍:
关于格式化:
关于字符串:
关于金额显示: -
页面跳转的使用介绍:
因为本框架致力于减少开发者工作量,所以采用了Fragment作为基础显示控件,原理是通过一个Activity作为一个容器进行跳转。
跳转示例如下:
pushToFragmentWithActivity(AFragment::class,isfullscreen = false,isfullstatus=true)
isfullscreen为设置跳转过去的界面是否全屏显示
isfullstatus为设置跳转过去的界面是否为沉浸式显示
如果不需要以Activity为容器跳转,则使用push(AFragment::class)即可。
如果是需要携带数据,示例如下:(key和value为键值对)
pushToFragmentWithActivity(AFragment::class,key to value)
关于Fragment中的返回事件的处理:
重写onBackPress()即可,注意要return true,否则依然会走一遍Activity的返回方法。
关于标题栏的使用:
如果希望显示ToolBar,则在类名上面加上注解@ToolbarSetting(displayNavigationIcon = false,title = "main")
或者使用toolbar()方法,设置标题方法如下:toolbar()?.title = "main"
如果不想用ToolBar,在类名上使用注解@Toolbar(mode = ToolbarMode.NONE)即可。
关于布局的绑定:
使用注解即可绑定视图布局:@BindLayout(R.layout.activity_main)。
控件的使用直接用布局里面的控件id即可。
- 关于脚本:
dimens.sh 用于适配多尺寸的文件生成脚本工具。
dimens适配方式:根据相关shell脚本进行copy操作。
需要在工程根目录创建一个dmconfig.txt的配置文件,内容如下:
第一行指定源文件,就是基本文件,需要里面的dimens的单位是px。
第二行是拷贝的目录地址。
第三行及以下是相关的分辨率,根据需要指定,个数不限。
格式如下:
frompath:/app/src/main/res/values/dimens.xml
topath:/app/src/main/res
320
480
720
960
1080
需要在根目录下创建dimens.sh的文件,内容的话直接拷贝上面的内容即可。
配置好了之后在Terminal中输入:./dimens.sh
按回车之后会执行相关操作。
pack.sh 用于多渠道打包和bugly补丁生成工具。
具体使用请查看tinker/README.md文件
集成的其他扩展功能:
- 地图页面:
注意要先确定是否有相关权限
pushToFragmentWithActivity(FragmentMap::class, FragmentMap.MAP_CONFIG to FragmentMap.AMapConfig(true, true, false, false, null, null, true))
- 定位功能:
var locationGetter: LocationGetter? = null
if (locationGetter == null) {
locationGetter = LocationGetter(this, object : OnLocationReceivedListener {
override fun onLocationReceived(locationDetails: LocationDetails?,
isOverAgagin: Boolean,
locationGetter: LocationGetter?,
amapLocation: AMapLocation?) {
locationGetter?.stopLocation()
if (locationDetails == null
|| !locationDetails.errorMessage.isNullOrEmpty()) {
CLog.e("地理位置信息获取失败:")
return
}
CLog.e("地理位置信息获取成功 : $locationDetails")
}
})
locationGetter?.getLocation()
} else {
locationGetter?.stopLocation()
locationGetter?.getLocation()
}
- 二维码扫描:
pushToFragmentWithActivity(QRScanFragment::class)
- 二维码展示:
//二维码展示
try {
val barcodeEncoder = BarcodeEncoder()
val bitmap = barcodeEncoder.encodeBitmap("content", BarcodeFormat.QR_CODE, 400, 400)
val imageViewQrCode = ImageView(this)
imageViewQrCode.setImageBitmap(bitmap)
} catch (e: Exception) {
}
- H5页面展示:
pushToFragmentWithActivity(WebFragment::class, WebFragment.KEY_URL to "https://www.baidu.com")
- 支付功能使用:
支付宝支付:
AlipayHelper.alipay(this,"支付数据",object :AlipayHelper.AlipayBack{
override fun backSuccess(msg: String?) {
}
override fun backFail(msg: String?, errorCode: String?) {
}
})
- 请求权限的使用:
RxPermissions(this)
.requestEach(Manifest.permission.ACCESS_COARSE_LOCATION)
.subscribe({
if (it.granted) {
// 用户已经同意该权限
toast("用户已经同意该权限");
} else if (it.shouldShowRequestPermissionRationale) {
// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框
toast("用户拒绝了该权限");
} else {
// 用户拒绝了该权限,并且选中『不再询问』,提醒用户手动打开权限
toast("权限被拒绝,请在设置里面开启相应权限,若无相应权限会影响使用");
}
})
RxPermissions(this)
.request(Manifest.permission.ACCESS_COARSE_LOCATION)
.subscribe({
if (it) {
//所有权限都开启aBoolean才为true,否则为false
toast("权限已开启");
} else {
toast("权限被拒绝,请在设置里面开启相应权限,若无相应权限会影响使用");
}
})
- umeng分享功能:
分享到小程序:
UmengShare.with(activity as BaseActivity)
.title(title)
.description(description)
.webpageUrl(actionUrl)
.imageUrl(imgUrl)
.setGoodsId(goodsId)
.storeId(storeId)
.path(CommonConstant.createDetail(goodsId, cat, storeId, platform))
.umengShareListener(object : UMShareListener {
override fun onResult(p0: SHARE_MEDIA?) {
}
override fun onCancel(p0: SHARE_MEDIA?) {
toast("分享取消")
}
override fun onError(p0: SHARE_MEDIA?, p1: Throwable?) {
CrashReport.postException(p1)
}
override fun onStart(p0: SHARE_MEDIA?) {
}
}).shareMiniApp()
分享图片到其他平台:
UmengShare.with(mFragment?.activity as BaseActivity)
.description(share.title)
.bitmapImg(it)
.umengShareListener(object : UMShareListener {
override fun onResult(p0: SHARE_MEDIA?) {
}
override fun onCancel(p0: SHARE_MEDIA?) {
mFragment?.context?.toast("分享取消")
}
override fun onError(p0: SHARE_MEDIA?, p1: Throwable?) {
CrashReport.postException(p1)
}
override fun onStart(p0: SHARE_MEDIA?) {
}
}).open()
- 京东淘宝app跳转:
使用商品id:
/**
* 进行京东跳转
* 注意:此方式仅限通过京东商品id进行跳转
* 如果是通过转链方式跳转,请使用本框架提供的京东联盟的sdk进行跳转
*/
fun goJD(context: Context?, gid: String) {
var intent = Intent(Intent.ACTION_VIEW)
var uri = Uri.parse("openapp.jdmobile://virtual?params=%7B%22sourceValue%22:%220_productDetail_97%22,%22des%22:%22productDetail%22,%22skuId%22:%22" + gid + "%22,%22category%22:%22jump%22,%22sourceType%22:%22PCUBE_CHANNEL%22%7D ")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.data = uri
context?.startActivity(intent)
}
使用链接或者转链链接:
if (mKeplerAttachParameter == null)
mKeplerAttachParameter = KeplerAttachParameter()
val mOpenAppAction = OpenAppAction { status, url ->
if (status == OpenAppAction.OpenAppAction_start) {//开始状态未必一定执行,
showLoadingDialog()
} else {
dismissLoadingDialog()
}
if (status == OpenAppAction.OpenAppAction_result_NoJDAPP) {
//未安装京东
(mFragment as? WebFragment)?.loadUrl("$url")
} else if (status == OpenAppAction.OpenAppAction_result_BlackUrl) {
//不在白名单
CLog.e("KeplerApiManager-京东-不在白名单")
} else if (status == OpenAppAction.OpenAppAction_result_ErrorScheme) {
//协议错误
CLog.e("KeplerApiManager-京东-协议错误")
} else if (status == OpenAppAction.OpenAppAction_result_APP) {
//呼京东成功
CLog.e("KeplerApiManager-京东-呼京东成功")
} else if (status == OpenAppAction.OpenAppAction_result_NetError) {
//网络异常
CLog.e("KeplerApiManager-京东-网络异常")
Toast.makeText(this, "网络异常", Toast.LENGTH_SHORT).show()
}
}
// 通过url呼京东主站
// url 通过url呼京东主站的地址
// mKeplerAttachParameter 存储第三方传入参数
// mOpenAppAction 呼京东主站回调
KeplerApiManager.getWebViewService().openAppWebViewPage(mFragment?.context,
url,
mKeplerAttachParameter,
mOpenAppAction)
===淘宝的跳转:
//OpenType.Auto 默认
//OpenType.H5 H5
//OpenType.Native alibcShowParams.setClientType("taobao_scheme"); 手淘
//OpenType.Native libcShowParams.setClientType("tmall_scheme"); 天猫
var alibcShowParams = AlibcShowParams(OpenType.Native, false)
alibcShowParams.clientType = "taobao_scheme"
var exParams = HashMap<String, String>()
exParams.put("isv_code", "appisvcode")
exParams.put("alibaba", "阿里巴巴")//自定义参数部分,可任意增删改
AlibcTrade.show(mFragment?.activity, AlibcPage(url), alibcShowParams, null, exParams, TradeCallback())
- 蒙板功能的使用:
ShowcaseView.Builder(this)
.setOnlyOneTag(MainActivity::class.java.name)//用于指定tag只显示一次
.setDuration(300L, 300L)//设置显示时间和消失时间
.setMaskColor("#77000000")//设置背景颜色
.setDismissOnTouch(true)//设置触摸消失
.addTarget(sample_text, ShowcaseView.CIRCLE_SHAPE)//设置显示位置形状
//下面设置提示信息显示相对窗口位置和显示的提示信息
.addShowView(CoverView(this, "点击右上方可分享\n保存视频等", "我知道了"), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 3f, 1f)
.addShowcaseQueue()//添加到显示队列依次显示
.setDuration(300L, 300L)
.setMaskColor("#77000000")
.setDismissOnTouch(true)
.addTarget(sample_text, ShowcaseView.CIRCLE_SHAPE)
.setTargetPadding(8)
.addShowView(CoverView(this, "可以对你喜欢的视频\n进行打赏哦", "我知道了"), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 3f, 7f)
.addShowcaseQueue()
.build()?.showQueue()
注意事项:
- GreenDao的表数据类必须使用java类,目前该框架不支持其他语言。
- greendao的使用
- RxPermission的使用
参与贡献
- 本框架为独立开发,借鉴了以往的开发经验和其他框架使用经验。
- 框架开发完成之后由同事进行使用,进行了迭代优化。
网友评论