# picture_dx #欢迎能来到这里
客服机器人美洽第三方完美接入魔窗
该demo用了组件化
为什么要组件化
近年来,为什么这么多团队要进行组件化实践呢?组件化究竟能给我们的工程、代码带来什么好处?我们认为组件化能够带来两个最大的好处:
提高组件复用性
可能有些人会觉得,提高复用性很简单,直接把需要复用的代码做成Android Module,打包AAR并上传代码仓库,那么这部分功能就能被方便地引入和使用。但是我们觉得仅仅这样是不够的,上传仓库的AAR库是否方便被复用,需要组件化的规则来约束,这样才能提高复用的便捷性。
降低组件间的耦合
我们需要通过组件化的规则把代码拆分成不同的模块,模块要做到高内聚、低耦合。模块间也不能直接调用,这需要组件化通信框架的支持。降低了组件间的耦合性可以带来两点直接的好处:第一,代码更便于维护;第二,降低了模块的Bug率。
应用
追求的理念;
APK包大小越小越好
应用打开耗费资源少
UI不是图产品越炫酷越好还要考虑性能及对应的影响
如以前加了个功能打开PDF加了个控件APK直接加大了6M(上一版本12M,增加50%相当于一个应用程序,对用户什么感觉直接就不下载了)
一个提示可以解决的就别整个弹框(开发写出来就分分钟的事),但是代码量增加,代码是一个字母一个字母,一个字节字节堆起来的,会让APK无端端的增大,知道而不原因
关系着重点搞清楚:应用这个是为了什么,功能还是UI还是效果为了UI效果耗时耗力耗财功能影响了
##该项目演示原本计划,及产生过程:
##本来我是用来练习kotlin的语法
- **写了几个类练练手。
- 然后是分模块(1个主工程6个依赖模块)来写的,后面慢慢加了好多功能。所以提交上来了,以便记录和学习。**
##加入recycleview列表数据,
包含下拉刷新,上拉加载更多,
网络访问是OKGO,(该功能已经封装好了,零虫,本计划单另一个模块,由于需要引用一个罐子包所以放在了扫一扫目录下,recycleview文件夹下,拉出来就可以直接使用)
列表加载,刷新,加载更多
![图像](https://github.com/1136346879/picture_dx/blob/master/image_flod/loadingview_refresh_loadmore.gif)
- ## RecycleView列表带吸附的标题纯手工打造源码可见原理是在定义StickyItemDecoration继承RecyclerView.ItemDecoration
- ##数据库引用操作,生成表格后增留改查(GreenDao)
如何引入,如何使用,在代码中已经写得很清楚了,可下载代码查看。
上方标号与下方一至:
##分模块(多模块)编写的项目目录,解耦性大,任意一模块都可以随意拆卸,安装不影响其他模块内容
- > * 1,主工程:App(**包含zxing扫一扫功能,查看拖拽,**)
- > * 2,基础类库:BaseLibrary
- > * 3,测试类练市搭建:myInstalledPkg
- > * 4,附属类库:提供商
- > * 5,扫一扫功能:qrode-module(直接可以引入该模块)
[^代码]
- 实现'com.google.zxing:核心:3.3.0'
- 实现'com.google.zxing:android-core:3.3.0'
- > * 7,个人中心:usercenter
- > * 6,图片裁剪
:用户头像展示裁剪,图片搜索功能(如淘宝,京东,百度等搜索)
[^代码]
/ **
*去裁剪直接写这个方法即可
* @param originalPath
* /
protected fun startCrop(originalPath:String){
val options = UCrop.Options()
val toolbarColor = AttrsUtils.getTypeValueColor(this,-1)
val statusColor = AttrsUtils.getTypeValueColor(this,-1)
val titleColor = AttrsUtils.getTypeValueColor(this,-1)
options.setToolbarColor(toolbarColor)//状态栏背景
options.setStatusBarColor(statusColor)
options.setToolbarWidgetColor(titleColor)
options.setCircleDimmedLayer(false)
options.setShowCropFrame(真)//显示裁剪框
options.setShowCropGrid(真)//显示裁剪框网格
options.setDragFrameEnabled(true)//裁剪框拖拖
options.setScaleEnabled(true)//图片缩放
options.setRotateEnabled(true)//图片旋转
options.setCompressionQuality(70)//图片质量
options.setHideBottomControls(true)
选项。 setFreeStyleCropEnabled(true)//裁剪
val isHttp = false
val imgType = PictureMimeType.getLastImgType(originalPath)
val uri = if(isHttp)Uri.parse(originalPath)else Uri.fromFile(File(originalPath))
UCrop.of(uri,Uri .fromFile(File(getDiskCacheDir(this),System.currentTimeMillis()。toString()+“”+ imgType)))。
withAspectRatio(0F,0F)
.withMaxResultSize(0,0)
.withOptions(options).start(
this)
// finish()
}
##小心看图
CropImageActivity按正方形裁切图片
用于app头像裁剪,用户图像裁剪
(参照该类即可)
# #图片上传
##网络访问用的是
[^ code]
com.squareup.retrofit2:
retrofit:$ retrofitVersion “ com.squareup.retrofit2:adapter-rxjava2:$ retrofitVersion”)
/ **
*图片路径传过来
*
* /
private fun loadUpImg(path:String){
val httpManger = HttpManager。 instance()
// val file = File(BitmapUtils.compressImageUpload(path))
val file = File(path)
val requestFile = RequestBody.create(MediaType.parse(“multipart / form-data”),file)
val body = MultipartBody .Part.createFormData(“file”,file.name,requestFile)
httpManger.doHttpDeal(this,httpManger.createService(OrderService :: class.java)!!。pictureSearch(body),
object:HttpOnNextListener(){
覆盖fun onNext(json:String){
ToastUtilKt.showCustomToast(“Image upload sucessed:$ json”)
}
覆盖fun onError(statusCode:Int,apiErrorModel:ApiErrorModel?){
super.onError(statusCode,apiErrorModel) )
ToastUtilKt.showCustomToast(“图片上传失败”)
}
},false)
}
#//内存泄漏检测((ThirdPartBannerZxingAcitivity)打开扫一扫即可观察到现象,因类中包含了多个静态变量)
扫一扫(自定义仿照微信界面)
实现'com.google.zxing:core:3.3.0'
实现'com.google.zxing:android-core:3.3.0'
[
^代码]
debugImplementation 'com.squareup.leakcanary:leakcanary-机器人:1.6.1'
releaseImplementation“COM .squareup.leakcanary:leakcanary-android-no-op:1.6.1'
点击到相应的页面之后,如存在内存泄漏,该帮助类就会显示出来
##会首先显示在通知栏中
##通知栏可以点击显示详情
##最后在泄漏这个app里面可以看到相应的内存泄漏详情
##图片相关问题(显示裁剪压缩轮播上传等)
##系统裁剪图片调用
- ###(1)进入相册
[^ code]
(权限rxpremission com.github.tbruyelle:rxpermissions
val intent = Intent(Intent.ACTION_PICK,null)
//如果朋友们要限制上传到服务器的图片类型时可以直接写如:image / jpeg,image / png等的类型
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,“image / *”)
startActivityForResult(intent,UCROP_SELECT_PHOTO)
- ###(2)在页面onActivityResult回调中,系统-调用裁剪
优点:稳定性高,无BUG,利于应用
缺点:裁剪页面的UI不可以修改是固定的
调用系统裁剪
[^ code]
private fun startPhotoZoom(data:Uri?,picWith:Int,picHeight:Int){
val intent = Intent(“com.android.camera.action.CROP”)
intent.setDataAndType(data,“image / *“)
// crop为true是设置在开启的intent中设置显示的视图可以剪裁
intent.putExtra(”crop“,”true“)
// aspectX aspectY是宽高的比例
intent.putExtra(”aspectX“ ,1)
intent.putExtra(“aspectY”,1.4)
// outputX,outputY是剪裁图片的宽高
intent.putExtra(“outputX”,picWith)
intent.putExtra(“outputY”,picHeight)
intent.putExtra(“scale” ”true)
photoUri = getImageUri()
intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri)
intent.putExtra(“return-data”,false)
intent.putExtra(“outputFormat”,Bitmap.CompressFormat.JPEG)
intent.putExtra(“noFaceDetection”,true)//没有脸检测
Log.e(“TAKE_PHOTO”,“TAKE_PHOTO-zoom-CROP_PHOTO”)
startActivityForResult(intent,CROP_PHOTO)
}
###(3)再在回调onActivityResult中处理裁剪后的逻辑
如上传,保存等。
##图片轮播用了两种写法:(第三方和自定义)
###(ThirdPartBannerZxingAcitivity)第三方//轮播图(新闻列表头部展示)
设置数据就可以
[^ code]
实现'com.youth.banner:banner:1.4.10'
使用也很简单:homeBanner //设置banner
样式.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE)
//设置图片加载器
.setImageLoader(GlideImageLoader())
//设置图片集合
.setImages(list_path)
//设置banner动画效果
.setBannerAnimation(Transformer.Default)
//设置标题集合(当banner样式有显示标题时)
.setBannerTitles(list_title)
//设置轮播时间
.setDelayTime(1500)
//设置指示器位置(当banner模式中有指示器时)
.setIndicatorGravity(BannerConfig.CENTER)
// banner设置方法全部调用完毕时最后调用.start
()
###(CustomerBannerActivityJava)自定义的ImageBanner(图片加载用的picasso)直接
[^ code]
imageBanner.setList(imageArray,imageTitle);
CustomerBannerActivityJava该类中加入自定义loadingview **动画及图案纯手动打造**
自定义视图拖拽功能,(DragView)悬浮在页面之上,自动吸附在两侧,可以点击
日历(完全自定义,可以编写相应日期,添加日程)
该页面用半透明风格可以模糊看到后面的页面
[^ code]
类集成活动风格风格(日历页面应用)
<style name =“Transparent”>
<item name =“android:windowBackground”> @ color / transparent_background </ item>
<item name =“android:windowNoTitle”> true </ item>
<item name =“android:windowIsTranslucent”> true </ item>
</ style>
类集成RxAppCompatActivity style风格(
样式名称=“TranslucentActivityTheme”parent =“Theme.AppCompat.Light。 NoActionBar“>
<item name =”android:windowBackground“> @ android:color / transparent </ item>
<item name =”android:colorBackgroundCacheHint“> @ null </ item>
<item name =“android:windowIsTranslucent”> true </ item>
<item name =“android:windowAnimationStyle”> @ android:style / Animation </ item>
<item name =“android:windowContentOverlay”> @ null </ item>
</ style>
##添加数据库GreenDao页面,包含完整逻辑,增加改查。相应的数据可以在日志日志页面查看
##多种状态切换的视图(loadingview,错误,空,内容)
[^ code]
在布局文件中引入
<com.classic.common.MultipleStatusView
android:id =“@ + id / multipleStatusView”
android:layout_width =“match_parent”
android:layout_height =“match_parent”
app:emptyView =“@ layout / layout_empty_view”(传入相应布局)
app:errorView =“@ layout / layout_error_view”(传入相应布局)
app:loadingView =“@ layout / layout_loading_view”(传入相应布局)
app:noNetworkView =“@ layout / layout_network_view”>(传入相应布局)
<LinearLayout
android:focusable =“true”
android:focusableInTouchMode =“true”
android:layout_width =“match_parent”
android:layout_height =“match_parent”
android:orientation =“vertical”>
</ LinearLayout>
</com.classic.common.MultipleStatusView>
在代码中
//展示内容
mLayoutStatusView?.showContent()
//展示空内容
mLayoutStatusView?。 showEmpty()
//展示错误页面
mLayoutStatusView?.showError()
//错误页面点击重新加载
mLayoutStatusView?.setOnClickListener {ToastUtilKt.showToast(“点击重新加载”)}
## **安卓高级开发交流群:qq 335042824 **
kotlin demo(源码)地址:https: //github.com/1136346879/picture_dx