# sgb-android **Repository Path**: hybyy/sgb-android ## Basic Information - **Project Name**: sgb-android - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: dev_shangpin_1.7.0 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-04-30 - **Last Updated**: 2024-04-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 更新日志 ## 2022-2-16 - 封装大首页选首模块(快捷跳转弹框),方便统一调用 ``` 调用方法(发送通知调起全局快捷跳转弹框): 方法一: //当前界面处于首页界面模块下跳转使用 //@param binding.ivQuickEntry 当前模块界面选首图标View EventBus.getDefault().postSticky(new QuickEntryEvent(binding.ivQuickEntry,null)); 方法二: //当前界面处于有多个跳转模块的界面(例如招标大厅界面等) //放开给当前界面本身的监听回调,用户处理Activity的关闭以及当前界面的跳转 //@param binding.ivQuickEntry 当前模块界面选首图标View EventBus.getDefault().postSticky(new QuickEntryEvent(binding.ivQuickEntry, new BackResultContentListener() { @Override public boolean backResult(com.swgk.core.event.bean.QuickEntryEntity entity) { //do Something ~ entity 收到点击事件的回调体,根据界面所对应的ID(entity.getId()具体对应的界面ID可前往MainActivity界面下查看)可自行处理当前界面的切换 返回值事件 true 拦截其它地方处理点击事件,自己处理 返回值事件 false PopWindow本身监听事件处理 return false; } })); ``` ## 2021-8-26 优化ICallBack的功能使用,1.增加了统一处理token失效问题(这个现在还再测试环境,代码尚未推送) 增加两个方法: 1.public ICallBack(boolean isAutoDismissDialog) 使用此方法的时候,isAutoDismissDialog 默认值为true,当为true时自动关闭并销毁 Dialog转圈 2.public ICallBack(boolean isAutoDialog,boolean isAutoDismissDialog) 使用此方法的时候,isAutoDialog 默认值为true,当为true时自动创建 Dialog转圈并且显示,当 isAutoDismissDialog 为true时才可自动销毁,否则不销毁 ## 2021-7-27 - 新增个人中心菜单权限判断工具类PermissionCheckUtil ``` //可在此工具类统一配置权限key,方便修改,权限判断方法可调用 /** * 检查是否有公司某权限 */ public static boolean hasCompanyPermission(String checkPermission) { String permission = ""; if (UserOperating.getInstance().isCompany()) { permission = SharedPreferenceUtil.getInstance().getSaveStringData(SharedPreferenceUtil.IS_DATA, ""); } return !TextUtils.isEmpty(permission) && permission.contains(checkPermission); } ``` ## 2021-6-7 - 统一封装获取相册图片调用和回调 ``` //可调用此方法获取本地相册照片 //AppActivity和AppFragment的子类可直接调用(其它类可以直接照搬方法实现回调数据在onActivityResult内获取) //@param isCompress 是否压缩图片 //@param size 最小压缩图片的的大小 //@param number 还能选择图片的数量 protected void pictureSelector(boolean isCompress, int size, int number) { PictureSelector.create(this) .openGallery(PictureMimeType.ofImage()) .imageEngine(GlideEngine.createGlideEngine()) .theme(R.style.picture_default_style) .selectionMode(PictureConfig.MULTIPLE) .isCompress(isCompress) .minimumCompressSize(size) .maxSelectNum(number) .forResult(PictureConfig.CHOOSE_REQUEST); } //实现该方法获取相册返回的已选择图片集合 protected void onPictureSelectorResult(List selectList) { } ``` - 统一封装IM单聊的实现调用 ``` //进入IM单聊界面(用户的登录状态下)直接调用IMUtils工具类下的buildSingleTalking(String toAccount)方法 //@param toAccount 对方用户(单聊)的IM账号 格式例如:202006111701212 public void buildSingleTalking(String toAccount) {} ``` ## 2021-4-28 - 新增ArrayUtil数组工具类,主要判空与非空 ``` //判空 ArrayUtil.isNullOrEmpty() //判非空 ArrayUtil.isNotNullAndEmpty() ``` ## 2021-4-14 - 新增KeepLifecycle工具类,保活服务,防止部分手机拍照时杀死app,比如红米k30 ``` //使用 KeepLifecycle.attach(this); ``` ## 2021-5-10 - 新增资金中心sdk ``` // 使用方法 一: 集成 1.在app gradle文件中添加 dependencies { ... implementation(name: 'capitalModule-debug', ext: 'aar') implementation 'com.gitee.bupa:capital:1.0.4' } repositories { flatDir { dirs '../app/libs' } } 2.在项目的gradle 文件中添加 dependencies { ... classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' } 3.在Application中初始化onCreate方法中添加 Utils.init(this); SPreferenceUtil.init(this); 二:使用 1.AndroidManifest.xml配置相应的页面 2.在更新用户信息的时候必须更新PcToken SPreferenceUtil.getInstance().saveData(SPreferenceUtil.resourcePCToken,"pcToken"); 3.启动资金中心首页 isUser判断是否是个人 CapitalActivity.start(Context context, boolean isUser); ``` ## 2021-3-25 - 新增NullableUtil空值判断工具类 ``` //简单使用 //判空取目标值,当bean为null时取设置的other默认值 NullableUtil.ofNullable(bean).orElse(other) //判断目标值不为空 NullableUtil.ofNullable(bean).isPresent() //判断目标值不为空的后续操作 NullableUtil.ofNullable(bean).ifPresent(new IConsumer() { @Override public void accept(String s) { } }); //其他使用具体查看NullableUtil方法注释 ``` #### 2021-01-21 新增新城市三级筛选框 ThreeLevelAreaWindow 使用:1.ThreeLevelAreaWindow areaWindow=new ThreeLevelAreaWindow(getActivity()) { @Override protected void resultContent(String name, String simpleName) {//选择中获取回显的文字 name全称 simpleName 简称 } }; areaWindow.setOnResultClick(new BasePopWindow.OnResultClick() { @Override public void result(Object proId, Object cityId, Object areaId) {//点击确认回调方法,都是单选返回的BaseAreaEntity实体,多选返回的集合 } }); 2. areaWindow.setProvinceSingle(); areaWindow.setCitySingle(); areaWindow.setAreaSingle();//设置省市区是否单选 areaWindow.setShowSimpleName(true);//设置是否显示简称 areaWindow.setAllSingleSelect(true);//是否都是设置成单选 areaWindow.setOnlyShowProAndCity(true);//选择中回显是否只显示省份城市 3. //设置数据 areaWindow.setDataAndPosition(datas, true);//参数二是否都添加不限 areaWindow.setDataAndPosition(datas, proName,cityName,areaName,true,true);//传指定的省市区名显示指定的位置,参数二是否都添加不限,参数三是第一级添加不限 ## 2020-12-29 - 添加NumberUtil工具类,用于格式化数字精度 - 增加列表刷新/加载更多库,有效防止滑动冲突,可配合BaseQuickAdapter使用 [SmartRefreshLayout](https://github.com/scwang90/SmartRefreshLayout) - 增加recyclerview分割线 [recycler-view-divider](https://github.com/fondesa/recycler-view-divider/wiki/Usage) ``` //使用 DividerDecoration.builder(getActivity()) .color(Color.TRANSPARENT) .size(10, TypedValue.COMPLEX_UNIT_DIP) .build() .addTo(binding.rvCargoManage); ``` - 增加AMapDialog地图选址,回调结果在onActivityResult中获取 ``` //启动 AMapDialog.launch(activity); //回调 @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) return; //地图选择 if (requestCode == RequestCode.CODE_MAP) { AMapAddressEntity entity = AMapDialog.get(data); //todo doing something } } ``` -增加简易提示弹窗RoundDialog ``` //使用例子 new RoundDialog.Builder(activity) .title("服务协议和隐私政策") .content(spannable) .cancel("暂不使用") .confirm("同意") .cancelable(false) .cancelCallback(v -> {}) .confirmCallback(v -> {}) .build(); ``` #### 2020-12-24 --- #### SoftKeyBoardUtil 软键盘处理 1.addOnSoftKeyBoardListener方法(软键盘显示及隐藏监听事件)会实现下面2个方法: void keyBoardShow(); void keyBoardHide(); 2.hideKeyboard方法(弹出的隐藏,隐藏的弹出) 3.showSoftInputFromWindow方法(EditText获取焦点并显示软键盘) #### 单个视频阿里云播放类抽取 1. VideoPalyerView(在布局中直接引用) 2. void onPrepared();(此方法中处理视频播放之前的操作,后调用start即可) 3. VideoPlayUrl(String url,boolean loop)(loop为是否循环播放) #### 列表视频阿里云播放类抽取 1.AlivcVideoPlayView(在布局中直接引用) 2.setShowUser(页面是否显示用户操作按钮) 3.VideoInfo(正在播放的视频信息和位置) 4.setOnRefreshDataListener(实现此方法下拉刷新和加载更多) ####为指定播放某个视频方法 5. refreshVideoList(List datas, int position)(刷新视频列表的数据信息,指定视频播放位置) ## 2020-12-28 新增 自定义控件CountMenuView(统一的模块菜单自定义控件,可以根据数据长度来自定义计算当前将要显示的页数和行数) 使用:1.在Xml中: // 设置行数 (默认3行) - 2.在View层代码: // datalist 为 List 类型的 menu数据 binding.calendarMenuView.initData(getChildFragmentManager(), datalist, new CountMenuView.OnItemClick() { @Override public void onItemClick(MenuEntity entity, int position,int num) { //TODO 您的点击事件 } }); #### 2020-12-22 --- #### mob sharesdk社会化分享集采替换 - 集成配置 1. 屏蔽之前build配置选项 2. AppApplication加入 ``` MobSDK.init(this, "", ""); ``` 3. 从原配置缓存去找到对应分享需要用到的jar或者aar放置libs 4. assets下ShareSDK.xml配置对应平台账号 5. 原集成方式为侵入式方式,影响编译速度,替换后很大程度上提高编译速度 ## 2020-12-1 新增 BaseQuickAdapter - 使用 BaseQuickAdapter为最基础的类型,直接使用BaseQuickAdapter即可简单快速实现一个Adapter: public class DemoAdapter extends BaseQuickAdapter { /** * 构造方法,此示例中,在实例化Adapter时就传入了一个List。 * 如果后期设置数据,不需要传入初始List,直接调用 super(layoutResId); 即可 */ public DemoAdapter(list List) { super(R.layout.layout_demo, list); } /** * 在此方法中设置item数据 */ @Override protected void convert(@NotNull BaseViewHolder helper, @NotNull String item) { helper.setText(R.id.tweetName, "This is an Item, pos: " + (helper.getAdapterPosition() - getHeaderLayoutCount())); } } Activity中设置: DemoAdapter adapter = new DemoAdapter(new ArrayList()); mRecyclerView.setAdapter(adapter); // 设置新的数据方法 adapter.setNewData(list) Item 点击事件 代码如下: DemoAdapter adapter = new DemoAdapter(); // 设置点击事件 adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { Tips.show("onItemClick " + position); } }); Item 长按事件 代码如下: adapter.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { Tips.show("onItemLongClick " + position); return true; } }); Item 内子View的点击事件: 注意,请不要在convert方法里注册控件id // 先注册需要点击的子控件id(注意,请不要写在convert方法里) adapter.addChildClickViewIds(R.id.btn, R.id.iv_num_add, R.id.item_click); // 设置子控件点击监听 adapter.setOnItemChildClickListener(new OnItemChildClickListener() { @Override public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { if (view.getId() == R.id.btn) { Tips.show("onItemChildClick " + position); } } }); Item 内子View的长按事件: 注意,请不要在convert方法里注册控件id // 先注册需要长按的子控件id(注意,请不要写在convert方法里) adapter.addChildLongClickViewIds(R.id.btn, R.id.iv_num_add, R.id.item_click); // 设置子控件长按监听 adapter.setOnItemChildLongClickListener(new OnItemChildLongClickListener() { @Override public boolean onItemChildLongClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { if (view.getId() == R.id.btn) { Tips.show("onItemChildLongClick " + position); } return true; } }); BaseQuickAdapter主要属性、方法说明 Java Kotlin 说明 获取Context getContext() context 数据相关 获取Adapter中数据 getData() data 只能get 设置新的数据实例 setNewData() 将会替换List指针引用 添加数据 addData() 移除数据 remove() remove() 改变某一位置的数据 setData() 替换整个数据 replaceData() 不会更改原数据的引用 设置Diff数据(异步,推荐) setDiffCallback() 配置数据差异化比较的Callback setDiffConfig() 更高程度的自定义化配置 setDiffNewData(List) 必须先设置setDiffCallback() 或者 setDiffConfig(),否则不生效 设置Diff数据 setDiffNewData(DiffResult, List) setDiffNewData(DiffResult, List?) 通过DiffResult设置数据,Adapter内部不关心Diff过程,只要结果。 空布局 设置空布局视图 setEmptyView() 仅当 data 为空时,才会显示 是否有空视图 hasEmptyView() 获取空视图 getEmptyLayout() 是否使用空布局 setUseEmpty() isUseEmpty 头布局 添加头布局 addHeaderView() 设置头布局 setHeaderView() 是否有头布局 hasHeaderLayout() 移除头布局 removeHeaderView() 移除所有头布局 removeAllHeaderView() 脚布局 添加脚布局 addFooterView() 设置脚布局 setFooterView() 是否有脚布局 hasFooterLayout() 移除脚布局 removeFooterView() 移除所有脚布局 removeAllFooterView() 布局其他属性 当显示空布局时,是否显示 头布局 setHeaderWithEmptyEnable() 当显示空布局时,是否显示 脚布局 setFooterWithEmptyEnable() 点击事件 item点击事件 setOnItemClickListener() 同java item长按事件 setOnItemLongClickListener 同java item子view的点击事件 setOnItemChildClickListener 同java item子view的长按事件 setOnItemChildLongClickListener 同java 添加需要响应点击事件的子View id addChildClickViewIds() 同java 添加以后,setOnItemChildClickListener才会响应 添加需要响应长按事件的子View id getChildLongClickViewIds() 同java 动画 是否打开动画 setAnimationEnable() animationEnable 默认:false 动画是否仅第一次执行 setAnimationFirstOnly() isAnimationFirstOnly 设置自定义动画 setAdapterAnimation() adapterAnimation 设置使用内置默认动画 setAnimationWithDefault() setAnimationWithDefault() 参数为枚举 ## 2020-11-19 新增断点续传工具 library/com.swgk.core.download.*; - 使用: //创建下载任务管理器 mDownloadManager = DownloadManager.getInstance(); //将下载任务添加至任务管理器中,并创建下载线程 // uri 下载路径 // filePath 存放路径 // fileName 存放文件名称 mDownloadManager.add(uri, filePath, fileName, new DownloadListner() { @Override public void onFinished() { //下载完成 MLog.e("自动更新", "下载完成!"); } @Override public void onProgress(float progress, boolean isDownloading) { //更新中 MLog.e("自动更新", "更新中" + progress); } @Override public void onPause() { //暂停 MLog.e("自动更新", "暂停了"); } @Override public void onCancel() { //取消 MLog.e("自动更新", "下载已取消"); } }); mDownloadManager.download(uri); //开始下载 ## 2020-11-18 集成阿里云热修复功能 - 集成配置 1.平台上新建对应应用 指定对应applicationId生成以下manifest.xml配置参数,当然也可以代码里直接进行设置 2.新增SophixStubApplication里的RealApplicationStub指定AppApplication,manifest application android:name启动替换成SophixStubApplication 3.导入implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.15' - 热修复操作步骤 1.平台上去下载SophixPatchTool-3.2.5工具到本地,此工具用于分析修复前后包差异 2.每次发版需保留发版 未加固 前的apk包,然后获取修复内容的 未加固 apk包 用工具SophixPatchTool-3.2.5对新旧包进行打补丁 3.在平台上补丁管理上传生成补丁文件,注意添加版本的版本号和应用的versionName版本号必须对应 4.然后发布补丁,可灰度和全量发布两种方式,终止补丁应用于未生效机子,回滚后所有补丁失效,恢复旧版功能,补丁发布后需1-2次冷启动方生效 - 注意事项 1、确保没有新增四大组件,没有修改AndroidManifest.xml和入口Application中的代码。 2、如果使用了混淆,确保打包使用的新旧包的混淆保持已经确保一致,如新包apply了旧包的mapping文件。 3、如果使用了加固,确保打包使用的新旧包都是加固前的正常包。 4、如果有资源修复,确保没有修改通知栏图标、启动图标资源以及RemoteViews等系统负责展示的资源。 5、如果有SO库的修复,确保所需要修复的SO都是以System.loadLibrary的方式,而不是以具体路径的方式进行加载。 6.调试补丁可参照平台稳定调试补丁步骤操作 ## 2020-11-17 ***为兼容版本更新,暂时回退*** 升级classpath 'com.android.tools.build:gradle:4.1.0'工具到4.1.0 compileSdkVersion 29 buildToolsVersion "29.0.2" 需在对应gradle-wrapper.properties配置gradle6.5 distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip 后续持续对编译慢问题进行优化 去掉dexOptions等实际对编译提供无用配置 ## 2020-11-06 增加高德地图封装依赖包 alimapLibrary包含: - 定位工具(MapLocationTools)使用: /** * 开始定位 */ private void startLocation() { //初始化定位工具 if (mapLocationTools == null) { mapLocationTools = new MapLocationTools(getApplicationContext()); mapLocationTools.initLocation(false); } //定位成功回调 mapLocationTools.setLocationListener(new MapLocationTools.LocationListener() { @Override public void getLocationListener(String address, Double Longitude, Double Latitude) { //TODO 得到定位后的实现 } }); //开始定位 mapLocationTools.startLocation(); } } - poi搜索工具(MapPoiTools)使用简单具体可参考工具(MapMarkerView) - 基础地图显示和标记(MapLocationTools)使用简单具体可参考工具(MapMarkerView) - MapMarkerView 继承高德地图的自定义View,集合了基础地图,定位,poi搜索功能为一身,通过自定义属性可以进行简单配置,具体使用为: 1.xml中放入地图承载不局 //默认定位标记 2.activity或Fragment中做地图初始化,在onC @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(savedInstanceState); } private void initView(Bundle savedInstanceState) { initMap(savedInstanceState); initPoiSearch(); } private void initMap(Bundle savedInstanceState) { binding.mMapView.initMap(savedInstanceState, getLifecycle(), new MapMarkerView.CallBack() { @Override public void onMarkerClick(int pos, String title) { //点击地图上的标记时回调响应 } @Override public void onLocation(Double Lat, Double Log, String string) { //地位成功回调 } @Override public void getAddress(Double Lat, Double Log,String address) { super.getAddress(Lat,Log,address); //定位成功后回调返回当前位置信息 } @Override public void onRegeocodeSearched(Double Lat, Double Log, String string) { super.onRegeocodeSearched(Lat,Log,string); //通过经纬度获取详情地址回调 } }); binding.mMapView.setMapClick(); } //在地图上标记已知经纬度处苗点 private void initPoiSearch() { if (currentLat !=0 && currentLong != 0){ LatLng latLng = new LatLng(currentLat, currentLong); binding.mMapView.setMyLocation(currentLat,currentLong,R.mipmap.map_goods_mark); binding.mMapView.getLatLotExtra(currentLat,currentLong); } } ## 2019-05-21 - 初始化项目结构,完成项目创建 ## 2019-05-24 - 完成项目架构搭建 - 完成主页面创建 - 完成我的页面布局 - 首页页面部分布局及部分接口 - 解决首页滑动冲突问题 ## 2019-05-28 - 工程材料首页页面布局 - 工程材料首页接口数据 ## 2019-05-29 - 首页滑动崩溃问题解决 - 工程机械页面布局 - 工程机械相关接口数据 ## 2019-05-30 - 工程设备页面布局 - 工程设备相关接口数据 ## 2019-05-31 - 工程工队页面布局 - 工程工队相关接口数据 ## 2019-06-03 - 优化各模块菜单显示问题 - 招采信息页面布局 - 招采信息相关接口数据 ## 2019-06-04 - 工程机械底部菜单 - 工程机械出租 - 工程机械求租 ## 2019-06-05 - 工程设备、工程工队底部菜单 - 工程设备出租 - 工程工队人才、工队 ## 2019-06-06 - 启动页 - 应用图标替换 ## 2019-06-10 - 登陆、注册、忘记密码页面 - 首页各模块列表下拉刷新加载更多功能加入 ## 2019-06-11 - 登陆、注册、忘记密码接口和功能,登陆接口还有问题 - 招采信息下拉筛选条件加入 ## 2019-06-13 - 完善招采模块功能 - 各模块底部菜单图标更改 - 分类功能加入 ## 2019-06-15 - 各模块首页刷新加入 - 登录接口 - 部分二级网页页面 ## 2019-06-18 - 分类跳转 ## 2019-06-20 - 首页选择省份页面加入 - 工程设备相关接口调整 ## 2019-06-27 - 工程机械调整 - 登陆跳转跳转 - 工程材料、工程机械、工程设备、工程工队地区选择 - 工程材料、工程机械、工程设备热门搜索、最近搜索、检索 - 建设力量部分功能 ## 2022-03-02 - 封装扫码器,解码器在dev-zxing分支