初次提交,修改了头像不能展示

This commit is contained in:
2025-08-11 11:01:55 +08:00
commit 7e2dcad9c9
3841 changed files with 227903 additions and 0 deletions

1
lib_base/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

190
lib_base/build.gradle Normal file
View File

@@ -0,0 +1,190 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-kapt'
}
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 22
targetSdkVersion 30
versionCode 1
versionName "1.0"
dataBinding {
//noinspection DataBindingWithoutKapt
enabled = true
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/libs']
}
}
repositories { flatDir { dirs 'libs' } }
}
dependencies {
api fileTree(dir: 'src/main/libs', include: ['*.jar', '*.aar'])
api fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// api 'com.baidu.lbsyun:BaiduMapSDK_Location_All:9.1.8'
// api 'com.baidu.lbsyun:BaiduMapSDK_Map:7.4.0'
implementation project(path:':LocalAar:alipaySdk')
implementation project(path:':LocalAar:paytypelibrary')
api 'androidx.core:core-ktx:1.2.0'
api 'androidx.appcompat:appcompat:1.1.0'
api 'com.google.android.material:material:1.1.0'
api 'androidx.constraintlayout:constraintlayout:1.1.3'
api 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
api 'androidx.navigation:navigation-fragment-ktx:2.2.2'
api 'androidx.lifecycle:lifecycle-extensions:2.2.0'
api 'androidx.navigation:navigation-ui-ktx:2.2.2'
api 'com.blankj:utilcodex:1.31.1'
api 'com.google.zxing:core:3.2.1'
//协程
api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
api 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
//retrofit + okHttp3
api 'com.squareup.retrofit2:retrofit:2.6.0'
api 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
api 'com.squareup.retrofit2:converter-gson:2.6.0'
api 'com.squareup.okhttp3:logging-interceptor:3.10.0'
api 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
api 'com.github.zhengpengzheng:FlycoTabLayout:1.0'
api 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
api 'com.alibaba:arouter-api:1.4.1'
kapt 'com.alibaba:arouter-compiler:1.2.2'
//想使用 Glide 请依赖 arms-imageloader-glide 扩展库, 使用方式请看 #4.1
api 'me.jessyan:arms-imageloader-glide:2.5.0'
api 'com.youth.banner:banner:1.4.10'
api "jp.wasabeef:glide-transformations:2.0.1"
api 'com.github.tbruyelle:rxpermissions:0.10.2'
api 'io.reactivex.rxjava2:rxjava:2.2.3'
api 'org.litepal.android:java:3.0.0'
api 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.47'
api 'com.makeramen:roundedimageview:2.3.0' //带圆角边框的的ImageView
// api 'com.tencent.tbs.tbssdk:sdk:43903'
api 'com.cysion:ImagePicker:1.2.0.x'
api 'com.contrarywind:Android-PickerView:4.1.8'
api 'com.baoyz.actionsheet:library:1.1.7'
api 'com.github.yyued:SVGAPlayer-Android:2.4.6'
api 'com.alibaba:fastjson:1.2.44'
api 'com.afollestad.material-dialogs:core:0.9.6.0'
api 'com.hyman:flowlayout-lib:1.1.2'
api 'org.greenrobot:eventbus:3.1.1'
//轮播图点
api 'me.relex:circleindicator:1.3.2'
api 'com.kaopiz:kprogresshud:1.2.0'
api "org.java-websocket:Java-WebSocket:1.4.0"
api 'top.zibin:Luban:1.1.8'
// 基础依赖包,必须要依赖
api 'com.gyf.immersionbar:immersionbar:3.0.0'
// fragment快速实现可选
api 'com.gyf.immersionbar:immersionbar-components:3.0.0'
// kotlin扩展可选
api 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
api 'com.zhy:okhttputils:2.6.2'
api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
api 'com.kongzue.dialog_v3:dialog:3.2.5'
api 'com.github.gittjy:LoadingDialog:1.0.2'
//QMUI
api 'com.qmuiteam:qmui:1.2.0'
api 'com.hyman:flowlayout-lib:1.1.2'
// api 'com.github.Liberuman:ShadowDrawable:0.1'
//bugly
api 'com.tencent.bugly:crashreport:4.1.9.3'
// 声网三大件
api 'io.agora.rtc:agora-special-full:4.1.1.23'
api 'com.github.agorabuilder:rtm-sdk:1.4.10'
api 'com.github.AgoraIO-Community:LyricsView:1.1.1'
//录音
api 'com.github.zhaolewei:ZlwAudioRecorder:1.0.6'
api "com.nostra13.universalimageloader:universal-image-loader:1.9.5"
api 'com.beloo.widget:ChipsLayoutManager:0.3.7@aar'
// api "com.egame.vap:animplayer:2.0.6"
api "io.github.tencent:vap:2.0.28"
api('com.github.bumptech.glide:glide:4.12.0') {
exclude group: 'com.github.bumptech.glide'
}
api project(':Muti-Barrage')
api 'com.teprinciple:updateapputils:2.3.0'
api 'me.jessyan:autosize:1.2.1'
api 'org.linwg1988:lcardview:1.5.4'
api 'com.github.FlyJingFish:GradientTextView:1.2.0'
api 'io.github.lucksiege:pictureselector:v3.11.1'
api 'com.ruffian.library:RTextView:1.0.11'
api 'com.github.Yuphee:RewardLayout:1.0.6.4'
api 'com.github.xuexiangjys:XUpdate:2.1.4'
api 'com.github.xuexiangjys:XUI:1.2.1'
api 'androidx.multidex:multidex:2.0.0'
api 'com.gyf.cactus:cactus:1.1.3-beta13'
api 'com.github.princekin-f:EasyFloat:2.0.4'
// 其他依赖...
api "androidx.work:work-runtime-ktx:2.8.1"
}

View File

21
lib_base/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yuyin.lib_base">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<application>
<activity android:name="com.yuyin.lib_base.ui.X5WebViewActivity" />
<activity android:name=".view.WebViewActivity"/>
<activity android:name="com.yuyin.lib_base.ui.followfans.FollowFansActivity" />
<activity android:name=".ui.jubao.JuBaoActivity" />
<activity android:name=".MessageActivity" />
<service android:name="com.zlw.main.recorderlib.recorder.RecordService" />
<service android:name=".RoomPlayService" />
<!-- *******************************授权页*********************************** -->
<activity
android:name="com.chuanglan.shanyan_sdk.view.CmccLoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="false"
android:launchMode="singleTop" />
<activity
android:name="com.chuanglan.shanyan_sdk.view.ShanYanOneKeyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="false"
android:launchMode="singleTop" />
<!-- *******************************协议页*********************************** -->
<activity
android:name="com.chuanglan.shanyan_sdk.view.CTCCPrivacyProtocolActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<activity-alias
android:name="com.cmic.gen.sdk.view.GenLoginAuthActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="false"
android:launchMode="singleTop"
android:targetActivity="com.chuanglan.shanyan_sdk.view.CmccLoginActivity" />
</application>
</manifest>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="mini" />
<version value="1" />
<list>
<mapping class="com.yuyin.lib_base.model.Login" />
<mapping class="com.yuyin.lib_base.model.SearchHis" />
<mapping class="com.yuyin.lib_base.model.PhotoMemory" />
</list>
<storage value="internal" />
</litepal>

View File

@@ -0,0 +1,119 @@
package com.yuyin.lib_base
import android.app.Application
import android.content.Context
import android.content.IntentFilter
import android.net.http.HttpResponseCache
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.multidex.MultiDex
import com.alibaba.android.arouter.launcher.ARouter
import com.gyf.cactus.Cactus
import com.gyf.cactus.ext.cactus
import com.lzy.imagepicker.ImagePicker
import com.lzy.imagepicker.view.CropImageView
import com.scwang.smartrefresh.layout.SmartRefreshLayout
import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.scwang.smartrefresh.layout.footer.ClassicsFooter
import com.scwang.smartrefresh.layout.header.ClassicsHeader
import com.xuexiang.xupdate.XUpdate
import com.yuyin.lib_base.base.UserManager
import com.yuyin.lib_base.model.ConfigBean
import com.yuyin.lib_base.util.ImageLoaderUtils
import com.yuyin.lib_base.util.UpdateAppHttpUtil
import com.yuyin.lib_base.view.ImgPikerGlideImageLoader
import org.litepal.LitePal
import java.io.IOException
open class App : Application() {
override fun onCreate() {
super.onCreate()
instance = this
MultiDex.install(this)
ARouter.openLog() // 打印日志
ARouter.openDebug() // 开启调试模式(如果在InstantRun模式下运行必须开启调试模式线上版本需要关闭,否则有安全风险)
ARouter.init(this) // 尽可能早推荐在Application中初始化
//数据库初始化
LitePal.initialize(this)
//读取本地用户信息
UserManager.initData()
//设置全局的下拉刷新
SmartRefreshLayout.setDefaultRefreshHeaderCreator { context: Context?, layout: RefreshLayout ->
ClassicsHeader(
context
)
}
SmartRefreshLayout.setDefaultRefreshFooterCreator { context: Context?, layout: RefreshLayout ->
ClassicsFooter(
context
)
}
try {
HttpResponseCache.install(cacheDir, (1024 * 1024 * 1024).toLong())
} catch (e: IOException) {
e.printStackTrace()
}
initImagePicker()
ImageLoaderUtils.initConfiguration(this)
XUpdate.get()
.debug(false)
.supportSilentInstall(true)
.setIUpdateHttpService(UpdateAppHttpUtil())
.init(this)
//可选,注册广播监听器
// registerReceiver(MainReceiver(), IntentFilter().apply {
// addAction(Cactus.CACTUS_WORK)
// addAction(Cactus.CACTUS_STOP)
// addAction(Cactus.CACTUS_BACKGROUND)
// addAction(Cactus.CACTUS_FOREGROUND)
// })
// cactus {
// //可选是否是debug模式
// isDebug(true)
// setTitle("秘耳语音")
// setContent("秘耳语音正在运行")
// setLargeIcon(R.mipmap.ic_launcher_app)
// setSmallIcon(R.mipmap.ic_launcher_app)
// //可选,退到后台是否可以播放音乐
// setBackgroundMusicEnabled(true)
// //可选设置奔溃可以重启google原生rom android 10以下可以正常重启
// setCrashRestartUIEnabled(false)
//// //可选,切后台切换回调
//// addBackgroundCallback {
////// Toast.makeText(this@App, if (it) "退到后台啦" else "跑到前台啦", Toast.LENGTH_SHORT).show()
//// }
// }
}
companion object {
var is_private_chat = 2
var guild_id = "0"
var rid="0"
var isShangJia=false //上架开关,隐藏盲盒,砸蛋游戏,提现
var configBean: ConfigBean = ConfigBean()
var isStart: Boolean = false //是否启动
var isTop = false//是否在顶部被启动
var roomActivity: AppCompatActivity? = null
var instance: App? = null
private set
}
private fun initImagePicker() {
val imagePicker = ImagePicker.getInstance()
imagePicker.imageLoader = ImgPikerGlideImageLoader() //设置图片加载器
imagePicker.isShowCamera = true //显示拍照按钮
imagePicker.isCrop = true //允许裁剪(单选才有效)
imagePicker.isSaveRectangle = true //是否按矩形区域保存
imagePicker.style = CropImageView.Style.RECTANGLE //裁剪框的形状
imagePicker.focusWidth = 800 //裁剪框的宽度。单位像素(圆形自动取宽高最小值)
imagePicker.focusHeight = 800 //裁剪框的高度。单位像素(圆形自动取宽高最小值)
imagePicker.outPutX = 1000 //保存文件的宽度。单位像素
imagePicker.outPutY = 1000 //保存文件的高度。单位像素
}
}

View File

@@ -0,0 +1,112 @@
package com.yuyin.lib_base
import com.yuyin.lib_base.model.MyListBean
object Const {
const val HTTP_CODE_SUCC = 200
const val ROOM_TYPE = "4"
const val URL1 = "http://mr.qixing2.top:621/api/"
const val URL3 = "http://mr.qixing2.top:621/"
// 2025-8-7 16:05:10 //测试服务器
// const val URL1 = "http://xmrc.qixing2.top/api/"
// const val URL3 = "http://xmrc.qixing2.top/"
// const val URL1 = "http://47.120.21.132:621/api/"
// const val URL3 = "http://47.120.21.132:621/"
const val ROOM_TYPE_HOT = -2
const val ROOM_TYPE_TOP = -1
const val ROOM_TYPE_ALL = 0
const val ROOM_TYPE_COMM = 1
const val ROOM_CHAT_PEIVATE_TICHU = "700001"
const val ROOM_CHAT_PEIVATE_JINYAN = "700002"
const val ROOM_CHAT_PEIVATE_JINYAN_JC = "700003"
const val ROOM_CHAT_PEIVATE_JINMAI = "700004"
const val ROOM_CHAT_PEIVATE_JINMAI_JC = "700005"
const val ROOM_CHAT_PEIVATE_MANAGER_ADD = "700006"
const val ROOM_CHAT_PEIVATE_MANAGER_UN = "700007"
const val ROOM_CHAT_PEIVATE_MAI_DOWN = "700008"
const val ROOM_CHAT_PEIVATE_MAI_UP = "700009"
const val ROOM_CHAT_PEIVATE_ADD_HOST = "700011"//添加为主持人
const val ROOM_CHAT_PEIVATE_CANCEL_HOST = "700012"//取消主持人
const val ROOM_CHAT_ADD_KTV = "700013"//邀请合唱
const val ROOM_CHAT_ADD_BLACK = "1211"//拉黑
const val ROOM_CHAT_PEIVATE_GIF = "1014"//撩Ta
const val ROOM_CHAT_PUBLIC_WELCOME = "60000"
const val ROOM_CHAT_PUBLIC_JOIN_ROOM = "60001"
const val ROOM_CHAT_PUBLIC_OPEN_BOX = "60002"
const val ROOM_CHAT_PUBLIC_SEND_GIFT = "60003"
const val ROOM_CHAT_PUBLIC_SEND_CHAT = "60004"
const val ROOM_CHAT_PUBLIC_SEND_EMOJI = "60005"
const val ROOM_CHAT_PUBLIC_CLEAR_MESSAGE = "60006"
const val ROOM_CHAT_PUBLIC_PLAY_VIP_TX = "60007"
const val ROOM_CHAT_PUBLIC_SEND_TRAY = "60008"
const val ROOM_CHAT_PUBLIC_PLAY_VIP_CPTX = "60009"
const val ROOM_CHAT_PUBLIC_SEND_LRC_POSITION = "60021"
const val ROOM_CHAT_PUBLIC_SEND_LRC_HC = "60088"
const val PAGE_ABOUT = "$URL3/index/index/page_show?id=1" //1 《关于我们》
const val PAGE_DENGJI = "$URL3/index/index/page_show?id=2" //2 《等级说明》
const val PAGE_DENGJI2 = "$URL3/index/index/page_show?id=7" //2 《等级说明》
const val PAGE_USER_XIEYI = "$URL3/index/index/page_show?id=6" //3 《用户隐私协议》
const val PAGE_USER_XIEYI2 = "$URL3/index/index/page_show?id=4" //3 《用户隐私协议》
const val PAGE_JUE_WEI = "$URL3/index/index/page_show?id=11" //3 《用户隐私协议》
const val PAGE_ERTONG = "$URL3/index/index/page_show?id=10" //3 《用户隐私协议》
const val ROOM_BUTIE = "$URL3/index/index/page_show?id=18" //3 《用户隐私协议》
const val GH_BUTIE = "$URL3/index/index/page_show?id=19" //3 《用户隐私协议》
const val WEEK_JIESHAO = "$URL3/index/index/page_show?id=20" //3 《用户隐私协议》
const val MTL_JIESHAO = "$URL3/index/index/page_show?id=21" //3 《用户隐私协议》
const val LOGOUT = "102"
const val FANHUIZHUYE = "105" //返回主页
const val XUANFUYINCANG = "107" //隐藏悬浮窗
const val FASONGMAIXULIWU = "114" //发送麦序礼物
const val SHEZHIGUANLI = "108" //房间管理员设置
const val QuxiaoGUANLI = "109" //房间管理员设置
const val DIANJIBIAOQING = "113" //fragment点击表情发送通知
const val TUISONG = "121" //推送通知
const val FANGJIANSHEZHI = "106" //修改房间设置成功
const val CHANGELRCPOSITION = "126" //更新歌词进度
const val WEIXINZHIFU = "116" //发送指定礼物
const val KE_FU =
"https://kefu.muye.club/index/index/home?visiter_id=&visiter_name=&avatar=&business_id=39&groupid=18&special=58"
const val CEHUA_RIGHT = "6001"
var GH_REMOVE = false
val myList1: ArrayList<MyListBean> = ArrayList()
val myList2: ArrayList<MyListBean> = ArrayList()
init {
// myList2.add(MyListBean(R.mipmap.my_list_qianbao, "我的钱包"))
// myList2.add(MyListBean(R.mipmap.my_list_zhuangban, "礼物记录"))
// myList2.add(MyListBean(R.mipmap.my_list_room, "我的爵位"))
// myList2.add(MyListBean(R.mipmap.my_list_vip, "装扮商城"))
// myList2.add(MyListBean(R.mipmap.my_list_gonghui, "我的等级"))
myList1.add(MyListBean(R.mipmap.my_list_fangjian, "我的房间"))
myList1.add(MyListBean(R.mipmap.my_list_degnji, "我的等级"))
myList1.add(MyListBean(R.mipmap.my_list_zegnsong, "赠送记录"))
myList1.add(MyListBean(R.mipmap.my_list_gonghhui, "我的公会"))
// myList1.add(MyListBean(R.mipmap.my_list_yiren, "签约艺人"))
myList1.add(MyListBean(R.mipmap.my_list_yaoqing, "邀请好友"))
myList1.add(MyListBean(R.mipmap.my_list_kefu, "入驻联系运营"))
// myList1.add(MyListBean(R.mipmap.my_list_qiandao, "签到"))
// myList1.add(MyListBean(R.mipmap.my_list_set, "系统设置"))
myList1.add(MyListBean(R.mipmap.my_kefu, "帮助反馈"))
}
}

View File

@@ -0,0 +1,30 @@
package com.yuyin.lib_base
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.blankj.utilcode.util.LogUtils
import com.gyf.cactus.Cactus
class MainReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
intent.action?.apply {
when (this) {
Cactus.CACTUS_WORK -> {
LogUtils.d(
this + "--" + intent.getIntExtra(Cactus.CACTUS_TIMES, 0)
)
}
Cactus.CACTUS_STOP -> {
LogUtils.d( this)
}
Cactus.CACTUS_BACKGROUND -> {
LogUtils.d( this)
}
Cactus.CACTUS_FOREGROUND -> {
LogUtils.d( this)
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.yuyin.lib_base
import android.content.Context
import android.text.TextUtils
import android.view.KeyEvent
import android.view.View
import androidx.databinding.ViewDataBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.yuyin.lib_base.arouter.AroutUtil
import com.yuyin.lib_base.base.BaseDataBindingActivity
import com.yuyin.lib_base.base.BaseViewModel
import io.agora.rtc2.UserInfo
import kotlinx.android.synthetic.main.activity_message.*
class MessageActivity : BaseDataBindingActivity<BaseViewModel, ViewDataBinding>() {
override fun startObserve() {
}
override fun getLayoutId(): Int = R.layout.activity_message
override fun initView() {
}
override fun initData() {
// val conversationFragment = ConversationFragment()
// val manager = supportFragmentManager
// val transaction = manager.beginTransaction()
// transaction.replace(R.id.container, conversationFragment)
// transaction.commit()
// val userInfo =
// RongUserInfoManager.getInstance().getUserInfo(intent.getStringExtra("targetId"))
// if (userInfo != null)
// tv_main_title.text = userInfo.name
}
override fun initEvent() {
iv_base_back2.setOnClickListener {
if (!TextUtils.isEmpty(intent.getStringExtra("rid"))) {
backToRoom()
}else{
finish()
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN && !TextUtils.isEmpty(
intent.getStringExtra("rid")
)
) {
backToRoom()
return true
}
return super.onKeyDown(keyCode, event)
}
}

View File

@@ -0,0 +1,83 @@
package com.yuyin.lib_base;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.RequiresApi;
public class RoomPlayService extends Service {
private NotificationManager notificationManager;
private String notificationId = "room_play_channelId";
private String notificationName = "room_play_channelName";
//通知的唯一标识号。
private static final int NOTIFICATION_ID = 11210666;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//创建NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
startForeground(1, getNotification());
}
private Notification getNotification() {
// PendingIntent如果用户选择此通知则启动我们的活动
// PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification.Builder builder = new Notification.Builder(this)
.setTicker("正在运行")
.setSmallIcon(R.mipmap.ic_launcher_app)
// .setContentIntent(pendingIntent)
.setContentTitle(getString(R.string.app_name))
.setContentText("运行中");
//设置Notification的ChannelID,否则不能正常显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(notificationId);
}
Notification notification = builder.build();
//发送通知
// notificationManager.notify(NOTIFICATION_ID,notification);
return notification;
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onDestroy() {
super.onDestroy();
if (notificationManager != null) {
notificationManager.cancel(NOTIFICATION_ID);
}
}
}

View File

@@ -0,0 +1,43 @@
package com.yuyin.lib_base.adapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* listview的adapter基类
*/
public class MyBaseAdapter<T> extends BaseAdapter {
public List<T> list_adapter;
@Override
public int getCount() {
return list_adapter == null ? 0 : list_adapter.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Object getItem(int position) {
return list_adapter.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
public List<T> getList_adapter() {
if (list_adapter == null)
list_adapter = new ArrayList<>();
return list_adapter;
}
}

View File

@@ -0,0 +1,43 @@
package com.yuyin.lib_base.adapter;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import java.util.List;
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
private List<String> typeOnes;
public MyPagerAdapter(FragmentManager fm, List<Fragment> mFragments, List<String> ones) {
super(fm);
this.fragments = mFragments;
this.typeOnes = ones;
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return typeOnes.get(position);
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}

View File

@@ -0,0 +1,10 @@
package com.yuyin.lib_base.adapter;
/**
* Created by cxf on 2017/8/9.
* RecyclerView的Adapter点击事件
*/
public interface OnItemClickListener<T> {
void onItemClick(T bean, int position);
}

View File

@@ -0,0 +1,32 @@
package com.yuyin.lib_base.adapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
/**
* 作者:sgm
* 描述:
*/
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> mFragments) {
super(fm);
this.fragments = mFragments;
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
}

View File

@@ -0,0 +1,46 @@
package com.yuyin.lib_base.adapter;
import android.graphics.Typeface;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.lib_base.R;
import java.util.List;
public class RecyclerTabAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
public int selectPosition = 0;
public RecyclerTabAdapter(int layoutResId, @Nullable List<String> data) {
super(layoutResId, data);
}
@Override
protected void convert(@NonNull BaseViewHolder helper, String item) {
helper.setText(R.id.tv_name, item);
boolean isSelect = helper.getPosition() == selectPosition;
helper.getView(R.id.tv_name).setSelected(isSelect);
helper.getView(R.id.v_view).setSelected(isSelect);
TextView tvName = helper.getView(R.id.tv_name);
if (isSelect) {
tvName.setTypeface(Typeface.DEFAULT_BOLD);
} else {
tvName.setTypeface(Typeface.DEFAULT);
}
}
public void setSelectPosition(int index) {
notifyItemChanged(selectPosition);
notifyItemChanged(index);
selectPosition = index;
}
}

View File

@@ -0,0 +1,105 @@
package com.yuyin.lib_base.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import androidx.recyclerview.widget.RecyclerView;
import com.yuyin.lib_base.util.ClickUtil;
import java.util.ArrayList;
import java.util.List;
import static com.blankj.utilcode.util.ConvertUtils.dp2px;
/**
* Created by cxf on 2018/6/7.
*/
public abstract class RefreshAdapter<T> extends RecyclerView.Adapter {
protected Context mContext;
protected List<T> mList;
protected LayoutInflater mInflater;
protected int mLoadMoreHeight;
protected RecyclerView mRecyclerView;
protected OnItemClickListener<T> mOnItemClickListener;
public RefreshAdapter(Context context) {
this(context, new ArrayList<T>());
}
public RefreshAdapter(Context context, List<T> list) {
mList = list;
mContext = context;
mInflater = LayoutInflater.from(mContext);
mLoadMoreHeight = dp2px(50);
setHasStableIds(true);
}
@Override
public int getItemCount() {
if (mList != null) {
return mList.size();
}
return 0;
}
public void setOnItemClickListener(OnItemClickListener<T> onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
public void setList(List<T> list) {
if (mList != null) {
mList.clear();
mList.addAll(list);
}
}
public void refreshData(List<T> list) {
if (mRecyclerView != null && list != null) {
mList.clear();
mList.addAll(list);
notifyDataSetChanged();
}
}
public void insertList(List<T> list) {
if (mRecyclerView != null && mList != null && list != null && list.size() > 0) {
int p = mList.size();
mList.addAll(list);
notifyItemRangeInserted(p, list.size());
mRecyclerView.scrollBy(0, mLoadMoreHeight);
}
}
public void clearData() {
if (mRecyclerView != null && mList != null) {
mList.clear();
notifyDataSetChanged();
}
}
@Override
public long getItemId(int position) {
return position;
}
protected boolean canClick() {
return ClickUtil.canClick();
}
public List<T> getList() {
return mList;
}
}

View File

@@ -0,0 +1,59 @@
package com.yuyin.lib_base.arouter
object AroutUtil {
const val COMMUNITY_JUBAO = "/lib/jubao"//举报
const val LIB_FOLLOW_FANS = "/lib/follow_fans"//粉丝关注
const val MAIN_MESSAGE_OFFICE = "/home/message3"//系统消息
const val MAIN_MAIN = "/home/mainA"//首页
const val MAIN_GAME_TYPE = "/home/game_type"//YOUXIFENLEI
const val MAIN_SEARCH_MAIN = "/home/search"//搜索主页
const val LOGIN_MAIN = "/login/mainA"//登录界面
const val COMMUNITY_FABU = "/community/fabu"//发布动态
const val COMMUNITY_DETAIL = "/community/detail"//动态详情
const val PLAY_LIST_MAIN = "/play/mainA"//陪玩分类首页
const val PLAY_LIST_Detail = "/play/detail"//陪玩详情
const val PLAY_PLACE_ORDER = "/play/place_order"//陪玩下单主页
const val PLAY_ORDER_MAIN = "/play/order_main"//我的订单首页
const val PLAY_REAL_NAME = "/play/real_name"//实名认证
const val PLAY_REAL_SELECT_GAME = "/play/select_game"//实名认证选择游戏
const val LIVE_MAIN = "/live/main"//直播间
const val LIVE_RANK = "/live/Rank"//排行榜
const val LIVE_LIVESET = "/live/RoomSet"//房间设置
const val LIVE_LIVESETNEW = "/live/RoomSetnew"//房间设置
const val MY_COMM_FEEDBACK = "/my/feedback"//帮助与反馈
const val MY_COMM_SET = "/my/set"//设置
const val MY_COMM_DENGJI = "/my/dengji"//等级
const val MY_COMM_ZHUANGBAN = "/my/zhuangban"//我的装扮
const val MAIN_MY_USER_INFO = "/my/bianji"//编辑资料
const val MAIN_MY_BINDALI = "/my/bindali"//绑定支付宝
const val MAIN_MY_TIXIAN = "/my/tixian"//申请提现
const val MAIN_MY_MONEY = "/my/money"//我的钱包
const val MAIN_MY_LOG_TIXIAN = "/my/tixian_log"//提现记录
const val MAIN_MY_LOG_TIXIAN_NEW = "/my/tixian_log"//提现记录
const val MAIN_MY_DUIHUAN = "/my/duihuan"//兑换
const val MAIN_MY_LOG_DUIHUAN = "/my/duihuan_log"//兑换记录
const val MAIN_MY_LOG_ZHUANZENG = "/my/zhuanzeng_log"//转赠记录
const val MAIN_MY_LOG_JIFEN = "/my/jifen_log"//积分记录
const val MAIN_MY_SHOUCANG = "/my/shoucang"//收藏房间
const val MAIN_MY_PAY_PS = "/my/payps"//交易密码
const val MAIN_MY_GIFT_LOG = "/my/gift_log"//礼物记录
const val MAIN_MY_GIFT_LOG_SUB = "/my/gift_log_sub"//礼物记录详情
const val MAIN_MY_HOME_PAGE = "/my/homepage"//个人主页
const val BLACK_LIST = "/my/black"//黑名单
const val GHMainActivity = "/my/GHMainActivity"
// const val MY_COMM_ZHUANGBAN = "/my/zhuangban"//我的装扮
const val My_COMM_GONGHUI = "/my/gonghui"//公会
const val My_COMM_GONGHUI_XIANGQING = "/my/gonghuixiangqing"//详情
const val My_COMM_GONGHUI_SHENGQING = "/my/shenqing"//公会的申请列表
const val MY_COMM_ZHUANGBAN_SHANGCHENG = "/my/zhuangban_shangcheng"//装扮商城
const val GIFT_WALL = "/my/gift_wall"
}

View File

@@ -0,0 +1,307 @@
package com.yuyin.lib_base.base
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProviders
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.yuyin.lib_base.R
import com.yuyin.lib_base.http.ApiException
import com.yuyin.lib_base.util.StatusBarUtil
import com.yuyin.lib_base.util.getClass
import com.yuyin.lib_base.util.showToast
import org.json.JSONException
import java.lang.reflect.InvocationTargetException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
abstract class BaseActivity<VM : BaseViewModel> : AppCompatActivity() {
lateinit var viewModel: VM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutId())
setStatusBar()
viewModel = ViewModelProviders.of(this).get(getClass(this))
lifecycle.addObserver(viewModel)
startObserveError()
startObserve()
initData()
initView()
initEvent()
val ivBaseBack = findViewById<View>(R.id.iv_base_back)
ivBaseBack?.setOnClickListener {
finish()
}
}
fun loadImage(imageView: ImageView, url: String) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: String, defaultId: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(defaultId).placeholder(defaultId))
.into(imageView)
}
abstract fun startObserve()
private fun startObserveError() {
viewModel.getError().observe(this, {
//处理一些已知异常
it?.run {
when (it) {
is ApiException -> {
var e: ApiException = it
it.msg.showToast()
}
is SocketTimeoutException -> {
"网络连接超时".showToast()
}
is UnknownHostException -> {
"未知主机地址".showToast()
}
is ConnectException -> {
"网络连接异常".showToast()
}
is JSONException -> {
"JSONException".showToast()
}
}
}
})
}
/**
* 必须实现的方法
*/
abstract fun getLayoutId(): Int
abstract fun initView()
abstract fun initData()
abstract fun initEvent()
override fun onDestroy() {
super.onDestroy()
if (this::viewModel.isInitialized)
lifecycle.removeObserver(viewModel)
}
/**
* 设置透明状态栏
*/
private fun setStatusBar() {
StatusBarUtil.StatusBarLightMode(this, true)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// val window = window
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// if (isStatusBarWhite()) {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// } else {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// }
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// window.statusBarColor = Color.TRANSPARENT
// }
}
/**
* 设置透明状态栏
*/
public fun setStatusBar(isLight: Boolean) {
if (isLight) {
StatusBarUtil.StatusBarLightMode(this, true)
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = window
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
if (isStatusBarWhite()) {
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
} else {
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.TRANSPARENT
}
}
}
protected open fun isStatusBarWhite(): Boolean {
return true
}
/**
* 加载多次gif
*/
open fun loadMoreTimeGif(
context: Context,
imageView: ImageView,
url: String?,
times: String,
gifListener: GifListener
) {
Glide
.with(context)
.asGif()
.load(url)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.listener(object : RequestListener<GifDrawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any,
target: Target<GifDrawable>,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: GifDrawable,
model: Any,
target: Target<GifDrawable>,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
try {
val gifStateField = GifDrawable::class.java.getDeclaredField("state")
gifStateField.isAccessible = true
val gifStateClass =
Class.forName("com.bumptech.glide.load.resource.gif.GifDrawable\$GifState")
val gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader")
gifFrameLoaderField.isAccessible = true
val gifFrameLoaderClass =
Class.forName("com.bumptech.glide.load.resource.gif.GifFrameLoader")
val gifDecoderField = gifFrameLoaderClass.getDeclaredField("gifDecoder")
gifDecoderField.isAccessible = true
val gifDecoderClass =
Class.forName("com.bumptech.glide.gifdecoder.GifDecoder")
val gifDecoder =
gifDecoderField[gifFrameLoaderField[gifStateField[resource]]]
val getDelayMethod = gifDecoderClass.getDeclaredMethod(
"getDelay",
Int::class.javaPrimitiveType
)
getDelayMethod.isAccessible = true
// 计算动画时长
//获得总帧数
val count = resource.frameCount
var delay = 0
for (i in 0 until count) {
//计算每一帧所需要的时间进行累加
delay += getDelayMethod.invoke(gifDecoder, i) as Int
}
var cishu = 1
Log.d("❤❤❤❤❤", "$cishu--1")
try {
val miss = times.toInt() * 1000
cishu = miss / delay + 1
Log.d("❤❤❤❤❤", "$cishu--2")
} catch (e: Exception) {
e.printStackTrace()
}
Log.d("❤❤❤❤❤", "$cishu--3")
//设置只播放一次
resource.setLoopCount(cishu)
Log.d("❤❤❤❤❤", cishu.toString() + "*" + delay + "=" + delay * cishu + "")
Log.d("❤❤❤❤❤", times)
var xianshiTime: Int
try {
xianshiTime = times.toInt() * 1000
} catch (e: Exception) {
xianshiTime = delay * cishu
e.printStackTrace()
}
imageView.postDelayed({
if (gifListener != null) {
gifListener.gifPlayComplete()
}
}, xianshiTime.toLong())
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
} catch (e: NoSuchMethodException) {
e.printStackTrace()
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
return false
}
}).into(imageView)
}
/**
* Gif播放完毕回调
*/
interface GifListener {
fun gifPlayComplete()
}
// 字体大小不跟随系统
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(getConfigurationContext(newBase))
}
private fun getConfigurationContext(context: Context): Context? {
val configuration: Configuration = context.resources.configuration
configuration.fontScale = 1f
return context.createConfigurationContext(configuration)
}
// 字体大小不跟随系统
override fun getResources(): Resources? {
val res: Resources = super.getResources()
val config = Configuration()
config.setToDefaults() // 设置为默认值
res.updateConfiguration(config, res.getDisplayMetrics())
return res
}
fun getVersionCode(): String {
val manager: PackageManager = packageManager
var code = ""
try {
val info: PackageInfo = manager.getPackageInfo(packageName, 0)
code = info.versionName
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return code
}
}

View File

@@ -0,0 +1,73 @@
package com.voice.lib_base.base.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.voice.lib_base.ext.inflateBindingWithGeneric
import com.yuyin.lib_base.R
open class BaseBottomFragmentDialog<B : ViewBinding?>(private val resourceID: Int) :
DialogFragment() {
var mDatabind: B? = null
val mBinding: B get() = mDatabind!!
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = Dialog(requireActivity(), R.style.myChooseDialog)
mDatabind = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(requireContext()), resourceID, null, false) as B
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(mBinding!!.root)
val window = dialog.window
val params = window!!.attributes
params.width = WindowManager.LayoutParams.MATCH_PARENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.BOTTOM
window.attributes = params
dialog.setCanceledOnTouchOutside(true)
return dialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mDatabind = inflateBindingWithGeneric(inflater, container, false)
return if (mBinding != null) mBinding!!.root else null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(requireDialog().window!!, false)
requireDialog().setOnShowListener { dialog: DialogInterface? ->
(view.parent as ViewGroup).setBackgroundColor(
Color.TRANSPARENT
)
}
}
override fun onDestroyView() {
super.onDestroyView()
mDatabind = null
}
fun setBundleArgs(bundleArgs: Bundle?): BaseBottomFragmentDialog<B> {
arguments = bundleArgs
return this
}
}

View File

@@ -0,0 +1,55 @@
package com.yuyin.lib_base.base;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.WindowCompat;
import androidx.viewbinding.ViewBinding;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.yuyin.lib_base.util.UiUtil;
public class BaseBottomSheetDialogFragment<B extends ViewBinding> extends BottomSheetDialogFragment {
public B mBinding;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mBinding = getViewBindingByReflect(inflater, container);
return mBinding != null ? mBinding.getRoot() : null;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
WindowCompat.setDecorFitsSystemWindows(requireDialog().getWindow(), false);
requireDialog().setOnShowListener(dialog -> ((ViewGroup) view.getParent()).setBackgroundColor(Color.TRANSPARENT));
}
@Override
public void onDestroyView() {
super.onDestroyView();
mBinding = null;
}
private B getViewBindingByReflect(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
try {
Class<B> c = UiUtil.getGenericClass(getClass(), 0);
return UiUtil.getViewBinding(c, inflater, container);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public BaseBottomSheetDialogFragment<B> setBundleArgs(Bundle bundleArgs){
setArguments(bundleArgs);
return this;
}
}

View File

@@ -0,0 +1,324 @@
package com.yuyin.lib_base.base
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProviders
import com.alibaba.android.arouter.launcher.ARouter
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.kaopiz.kprogresshud.KProgressHUD
import com.yuyin.lib_base.Const
import com.yuyin.lib_base.Const.LOGOUT
import com.yuyin.lib_base.R
import com.yuyin.lib_base.arouter.AroutUtil
import com.yuyin.lib_base.http.ApiException
import com.yuyin.lib_base.model.FirstEvent
import com.yuyin.lib_base.util.StatusBarUtil
import com.yuyin.lib_base.util.getClass
import com.yuyin.lib_base.util.showToast
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import java.lang.reflect.InvocationTargetException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
abstract class BaseDataBindingActivity<VM : BaseViewModel, DB : ViewDataBinding> :
AppCompatActivity() {
var hubProgress: KProgressHUD? = null
lateinit var viewModel: VM
lateinit var mDataBinding: DB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDataBinding = DataBindingUtil.setContentView(this, getLayoutId())
mDataBinding.lifecycleOwner = this
viewModel = ViewModelProviders.of(this).get(getClass(this))
setStatusBar()
lifecycle.addObserver(viewModel)
startObserveError()
initData()
startObserve()
initView()
initEvent()
val ivBaseBack = findViewById<ImageView>(R.id.iv_base_back)
ivBaseBack?.setOnClickListener {
finish()
}
}
fun showLoading() {
hubProgress = KProgressHUD
.create(this)
.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
.setLabel("请稍等...")
.show()
}
fun disMiss() {
if (hubProgress != null && hubProgress!!.isShowing) {
hubProgress!!.dismiss()
}
}
abstract fun startObserve()
private fun startObserveError() {
viewModel.getError().observe(this, {
//处理一些已知异常
it?.run {
when (it) {
is ApiException -> {
var e: ApiException = it
it.msg!!.showToast()
if(it.msg=="登录失效"){
EventBus.getDefault().post(FirstEvent("指定发送", Const.LOGOUT))
UserManager.layout()
ARouter.getInstance().build(AroutUtil.LOGIN_MAIN).withInt("sign", 1)
.navigation()
}
}
is SocketTimeoutException -> {
"网络连接超时".showToast()
}
is UnknownHostException -> {
"未知主机地址".showToast()
}
is ConnectException -> {
"网络连接异常".showToast()
}
is JSONException -> {0
"JSONException".showToast()
}
}
}
})
}
/**
* 必须实现的方法
*/
abstract fun getLayoutId(): Int
abstract fun initView()
abstract fun initData()
abstract fun initEvent()
override fun onDestroy() {
super.onDestroy()
if (this::viewModel.isInitialized)
lifecycle.removeObserver(viewModel)
}
/**
* 设置透明状态栏
*/
private fun setStatusBar() {
StatusBarUtil.StatusBarLightMode(this,true)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// val window = window
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// if (isStatusBarWhite()) {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// } else {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// }
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// window.statusBarColor = Color.TRANSPARENT
// }
}
protected open fun isStatusBarWhite(): Boolean {
return true
}
fun loadImage(imageView: ImageView, url: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: String) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: String, defaultId: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(defaultId).placeholder(defaultId))
.into(imageView)
}
/**
* 加载多次gif
*/
open fun loadMoreTimeGif(
context: Context,
imageView: ImageView,
url: String?,
times: String,
gifListener: GifListener
) {
Glide
.with(context)
.asGif()
.load(url)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.listener(object : RequestListener<GifDrawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any,
target: Target<GifDrawable>,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: GifDrawable,
model: Any,
target: Target<GifDrawable>,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
try {
val gifStateField = GifDrawable::class.java.getDeclaredField("state")
gifStateField.isAccessible = true
val gifStateClass =
Class.forName("com.bumptech.glide.load.resource.gif.GifDrawable\$GifState")
val gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader")
gifFrameLoaderField.isAccessible = true
val gifFrameLoaderClass =
Class.forName("com.bumptech.glide.load.resource.gif.GifFrameLoader")
val gifDecoderField = gifFrameLoaderClass.getDeclaredField("gifDecoder")
gifDecoderField.isAccessible = true
val gifDecoderClass =
Class.forName("com.bumptech.glide.gifdecoder.GifDecoder")
val gifDecoder =
gifDecoderField[gifFrameLoaderField[gifStateField[resource]]]
val getDelayMethod = gifDecoderClass.getDeclaredMethod(
"getDelay",
Int::class.javaPrimitiveType
)
getDelayMethod.isAccessible = true
// 计算动画时长
//获得总帧数
val count = resource.frameCount
var delay = 0
for (i in 0 until count) {
//计算每一帧所需要的时间进行累加
delay += getDelayMethod.invoke(gifDecoder, i) as Int
}
var cishu = 1
Log.d("❤❤❤❤❤", "$cishu--1")
try {
val miss = times.toInt() * 1000
cishu = miss / delay + 1
Log.d("❤❤❤❤❤", "$cishu--2")
} catch (e: Exception) {
e.printStackTrace()
}
Log.d("❤❤❤❤❤", "$cishu--3")
//设置只播放一次
resource.setLoopCount(cishu)
Log.d("❤❤❤❤❤", cishu.toString() + "*" + delay + "=" + delay * cishu + "")
Log.d("❤❤❤❤❤", times)
var xianshiTime: Int
try {
xianshiTime = times.toInt() * 1000
} catch (e: Exception) {
xianshiTime = delay * cishu
e.printStackTrace()
}
imageView.postDelayed({
if (gifListener != null) {
gifListener.gifPlayComplete()
}
}, xianshiTime.toLong())
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
} catch (e: NoSuchMethodException) {
e.printStackTrace()
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
return false
}
}).into(imageView)
}
/**
* Gif播放完毕回调
*/
interface GifListener {
fun gifPlayComplete()
}
fun backToRoom() {
// ARouter.getInstance().build(AroutUtil.LIVE_MAIN).withTransition(R.anim.slide_left_in, R.anim.slide_right_out).navigation(this)
finish()
}
// 字体大小不跟随系统
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(getConfigurationContext(newBase))
}
private fun getConfigurationContext(context: Context): Context? {
val configuration: Configuration = context.resources.configuration
configuration.fontScale = 1F
return context.createConfigurationContext(configuration)
}
// 字体大小不跟随系统
override fun getResources(): Resources {
val res: Resources = super.getResources()
val config = Configuration()
config.setToDefaults() // 设置为默认值
res.updateConfiguration(config, res.getDisplayMetrics())
return res
}
fun getVersionCode(): String {
val manager: PackageManager = packageManager
var code = ""
try {
val info: PackageInfo = manager.getPackageInfo(packageName, 0)
code = info.versionName
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return code
}
}

View File

@@ -0,0 +1,147 @@
package com.yuyin.lib_base.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.blankj.utilcode.util.ToastUtils
import com.yuyin.lib_base.R
import com.yuyin.lib_base.http.ApiException
import com.yuyin.lib_base.util.StatusBarUtil
import com.yuyin.lib_base.util.getClass
import com.yuyin.lib_base.util.showToast
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import org.json.JSONException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
abstract class BaseDataBindingFragment<VM : BaseViewModel, DB : ViewDataBinding> : Fragment() {
lateinit var viewModel: VM
lateinit var mDataBinding: DB
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false)
mDataBinding.lifecycleOwner = this
return mDataBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setStatusBar()
initView()
viewModel = ViewModelProviders.of(this).get(getClass(this))
lifecycle.addObserver(viewModel)
startObserveError()
startObserve()
initData()
initEvent()
super.onViewCreated(view, savedInstanceState)
}
abstract fun startObserve()
private fun startObserveError() {
viewModel.getError().observe(requireActivity(), {
//处理一些已知异常
it?.run {
when (it) {
is ApiException -> {
var e: ApiException = it
// Toast.makeText(context,e.msg,Toast.LENGTH_SHORT).show()
e.msg.showToast()
}
is SocketTimeoutException -> {
"网络连接超时".showToast()
}
is UnknownHostException -> {
"未知主机地址".showToast()
}
is ConnectException -> {
"网络连接异常".showToast()
}
is JSONException -> {
"JSONException".showToast()
}
}
}
})
}
/**
* 必须实现的方法
*/
abstract fun getLayoutId(): Int
abstract fun initView()
abstract fun initData()
abstract fun initEvent()
override fun onDestroy() {
super.onDestroy()
if (this::viewModel.isInitialized)
lifecycle.removeObserver(viewModel)
}
/**
* 设置透明状态栏
*/
private fun setStatusBar() {
StatusBarUtil.StatusBarLightMode(requireActivity(), true)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// val window = requireActivity().window
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// if (isStatusBarWhite()) {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// } else {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// }
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// window.statusBarColor = Color.TRANSPARENT
// }
}
protected open fun isStatusBarWhite(): Boolean {
return false
}
fun loadImage(imageView: ImageView, url: String) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: String, defaultId: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(defaultId).placeholder(defaultId))
.into(imageView)
}
}

View File

@@ -0,0 +1,68 @@
package com.voice.lib_base.base.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.voice.lib_base.ext.inflateBindingWithGeneric
import com.yuyin.lib_base.R
open class BaseFragmentDialog<B : ViewBinding?>(private val resourceID: Int) : DialogFragment() {
var mDatabind: B? = null
val mBinding: B get() = mDatabind!!
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = Dialog(requireActivity(), R.style.myChooseDialog)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
mDatabind = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(requireContext()), resourceID, null, false) as B
dialog.setContentView(mDatabind!!.root)
val window = dialog.window
val params = window!!.attributes
params.width = WindowManager.LayoutParams.MATCH_PARENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
window.attributes = params
dialog.setCanceledOnTouchOutside(true)
return dialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mDatabind = inflateBindingWithGeneric(inflater, container, false)
return if (mBinding != null) mBinding!!.root else null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(requireDialog().window!!, false)
requireDialog().setOnShowListener { dialog: DialogInterface? ->
(view.parent as ViewGroup).setBackgroundColor(
Color.TRANSPARENT
)
}
}
override fun onDestroyView() {
super.onDestroyView()
mDatabind = null
}
fun setBundleArgs(bundleArgs: Bundle?): BaseFragmentDialog<B> {
arguments = bundleArgs
return this
}
}

View File

@@ -0,0 +1,68 @@
package com.voice.lib_base.base.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.voice.lib_base.ext.inflateBindingWithGeneric
import com.yuyin.lib_base.R
open class BaseFragmentFullDialog<B : ViewBinding?>(private val resourceID: Int) : DialogFragment() {
var mDatabind: B? = null
val mBinding: B get() = mDatabind!!
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = Dialog(requireActivity(), R.style.myChooseDialog)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
mDatabind = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(requireContext()), resourceID, null, false) as B
dialog.setContentView(mDatabind!!.root)
val window = dialog.window
val params = window!!.attributes
params.width = WindowManager.LayoutParams.MATCH_PARENT
params.height = WindowManager.LayoutParams.MATCH_PARENT
window.attributes = params
dialog.setCanceledOnTouchOutside(true)
return dialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mDatabind = inflateBindingWithGeneric(inflater, container, false)
return if (mBinding != null) mBinding!!.root else null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(requireDialog().window!!, false)
requireDialog().setOnShowListener { dialog: DialogInterface? ->
(view.parent as ViewGroup).setBackgroundColor(
Color.TRANSPARENT
)
}
}
override fun onDestroyView() {
super.onDestroyView()
mDatabind = null
}
fun setBundleArgs(bundleArgs: Bundle?): BaseFragmentFullDialog<B> {
arguments = bundleArgs
return this
}
}

View File

@@ -0,0 +1,2 @@
package com.yuyin.lib_base.base

View File

@@ -0,0 +1,7 @@
package com.yuyin.lib_base.base
import com.yuyin.lib_base.http.RequestService
object BaseServer {
val api by lazy { RequestService.create<BaseService>() }
}

View File

@@ -0,0 +1,5 @@
package com.yuyin.lib_base.base
interface BaseService {
}

View File

@@ -0,0 +1,208 @@
package com.yuyin.lib_base.base
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.*
import com.alibaba.android.arouter.launcher.ARouter
import com.kongzue.dialog.v3.InputDialog
import com.tencent.bugly.proguard.ba
import com.yuyin.lib_base.App
import com.yuyin.lib_base.arouter.AroutUtil
import com.yuyin.lib_base.http.BaseRepository
import com.yuyin.lib_base.http.PassRoomException
import com.yuyin.lib_base.model.*
import com.yuyin.lib_base.util.ClickUtil
import com.yuyin.lib_base.util.DeviceUtils
import com.yuyin.lib_base.util.showToast
import com.yuyin.lib_base.view.InputPassDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import okhttp3.MultipartBody
/**
*
*/
open class BaseViewModel : ViewModel(), LifecycleObserver {
private var clickTime: Long = 0
var baseRepository = BaseRepository()
private val passRoom by lazy { MutableLiveData<Exception>() }
private val error by lazy { MutableLiveData<Exception>() }
private val finally by lazy { MutableLiveData<Int>() }
var userInfoData = MutableLiveData<UserBean>()
var roomInfoData = MutableLiveData<EnterRoomInfo>()
var configBean = MutableLiveData<ConfigBean>()
var imUserInfo = MutableLiveData<Login>()
var kfMessageBean = MutableLiveData<List<kfMessageBean>>()
//获取系统配置
fun get_system_base_config(app_version: String, app_type: String) {
launchUI {
var data = baseRepository.get_system_base_config(app_version, app_type)
configBean.value = data.data
}
}
//获取个人信息
fun loadUserInfo() {
launchUI {
var data = baseRepository.getUserinfo()
App.guild_id = data.data.guild_id
userInfoData.value = data.data
}
}
val userCancel = MutableLiveData<String>()
fun user_cancel(sms_code: String) {
launchUI {
val result = baseRepository.user_cancel(sms_code)
userCancel.value = "成功"
}
}
fun user_log_out() {
launchUI {
baseRepository.user_log_out()
}
}
//进入房间
fun enterRoom(rid: String, password: String, context: AppCompatActivity) {
launchUI {
val data = baseRepository.enter_room_info(rid, password)
if (data.code == 202) {
if (password.isNotEmpty()) {
data.msg.showToast()
}
val inputPassDialog = InputPassDialog(context)
inputPassDialog.binding.tvConfirm.setOnClickListener {
val pwd = inputPassDialog.binding.etText.content.toString()
Log.e("密码密码", "enterRoom: 密码:::$pwd" )
enterRoom(rid,pwd , context)
inputPassDialog.dismiss()
}
inputPassDialog.show()
} else {
if (App.isStart) {
App.isStart = false
App.roomActivity?.finish() //先销毁
}
if (ClickUtil.canClickRoom()) {
ARouter.getInstance().build(AroutUtil.LIVE_MAIN).withSerializable("enterRoom", data.data).navigation()
}
}
}
}
//获取用户基本信息详情
fun get_base_user_info(uid: String) {
launchUI {
var data = baseRepository.get_base_user_info(uid)
imUserInfo.value = data.data
}
}
//获取客服信息
fun get_kf_message() {
launchUI {
var data = baseRepository.get_kf_message()
kfMessageBean.value=data.data
}
}
//进入房间
fun getRoomInfo(rid: String, password: String) {
launchUI {
var data = baseRepository.enter_room_info(rid, password)
roomInfoData.value = data.data
}
}
var imgListData: MutableLiveData<List<String>> = MutableLiveData()
fun uploadImages(imgFiles: List<MultipartBody.Part>) {
launchUI {
var result = baseRepository.uploadImages2(imgFiles)
imgListData.value = result.data
}
}
//运行在UI线程的协程
fun launchUI(block: suspend CoroutineScope.() -> Unit) = viewModelScope.launch {
try {
block()
} catch (e: Exception) {
if (e is PassRoomException) {
passRoom.value = e
} else {
error.value = e
// throw e
}
} finally {
finally.value = 200
}
}
/**
* 请求失败,出现异常
*/
fun getError(): LiveData<Exception> {
return error
}
/**
* 请求完成,在此处做一些关闭操作
*/
fun getFinally(): LiveData<Int> {
return finally
}
var userMoney = MutableLiveData<UserMoneyBean>()
fun get_user_money() {
launchUI {
var result = baseRepository.get_user_money()
userMoney.value = result.data
}
}
fun UserGiveIntegral(
reveive_uid: String,
integral: String,
) {
launchUI {
baseRepository.user_give_integral(reveive_uid, integral,com.blankj.utilcode.util
.DeviceUtils.getUniqueDeviceId())
}
}
val messageCount = MutableLiveData<MessageCount>()
fun get_user_message_cover_info(){
launchUI {
val result = baseRepository.get_user_message_cover_info()
messageCount.value = result.data
}
}
/**
* BaseViewModel 添加
*
*/
var captchaBean = MutableLiveData<CaptchaBean>()
fun create_captcha() {
launchUI {
val result = baseRepository.create_captcha()
captchaBean.value = result.data
}
}
}

View File

@@ -0,0 +1,130 @@
package com.yuyin.lib_base.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.yuyin.lib_base.R
import com.yuyin.lib_base.http.ApiException
import com.yuyin.lib_base.util.StatusBarUtil
import com.yuyin.lib_base.util.getClass
import com.yuyin.lib_base.util.showToast
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import org.json.JSONException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
abstract class BaseViewModelFragment<VM : BaseViewModel> : Fragment() {
lateinit var viewModel: VM
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(getLayoutId(), container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setStatusBar()
initView()
viewModel = ViewModelProviders.of(this).get(getClass(this))
lifecycle.addObserver(viewModel)
startObserveError()
startObserve()
initData()
initEvent()
super.onViewCreated(view, savedInstanceState)
}
private fun startObserveError() {
viewModel.getError().observe(requireActivity(), {
//处理一些已知异常
it?.run {
when (it) {
is ApiException -> {
var e: ApiException = it
it.msg!!.showToast()
}
is SocketTimeoutException -> {
"网络连接超时".showToast()
}
is UnknownHostException -> {
"未知主机地址".showToast()
}
is ConnectException -> {
"网络连接异常".showToast()
}
is JSONException -> {
"JSONException".showToast()
}
}
}
})
}
/**
* 必须实现的方法
*/
abstract fun getLayoutId(): Int
abstract fun initView()
abstract fun initData()
abstract fun initEvent()
abstract fun startObserve()
override fun onDestroy() {
super.onDestroy()
if (this::viewModel.isInitialized)
lifecycle.removeObserver(viewModel)
}
/**
* 设置透明状态栏
*/
private fun setStatusBar() {
StatusBarUtil.StatusBarLightMode(requireActivity(),true)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// val window = requireActivity().window
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// if (isStatusBarWhite()) {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// } else {
// window.decorView.systemUiVisibility =
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// }
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// window.statusBarColor = Color.TRANSPARENT
// }
}
protected open fun isStatusBarWhite(): Boolean {
return false
}
fun loadImage(imageView: ImageView, url: String) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(R.mipmap.no_tu).placeholder(R.mipmap.no_tu))
.into(imageView)
}
fun loadImage(imageView: ImageView, url: String, defaultId: Int) {
Glide
.with(this)
.load(url)
.apply(RequestOptions().error(defaultId).placeholder(defaultId))
.into(imageView)
}
}

View File

@@ -0,0 +1,35 @@
package com.yuyin.lib_base.base
import com.yuyin.lib_base.model.Login
import org.litepal.LitePal
/**
* 作者:sgm
* 描述:存储用户信息的数据库操作类
*/
object UserManager {
var login: List<Login>? = null
var IS_LOGIN = false
fun initData() {
login = LitePal.findAll(Login::class.java)
if (login != null && login!!.size > 0) {
IS_LOGIN = true
}
}
val user: Login
get() {
val login = LitePal.findAll(Login::class.java)
return if (login.size > 0) {
login[0]
} else {
Login()
}
}
//账号退出调用即可
fun layout() {
LitePal.deleteAll(Login::class.java)
IS_LOGIN = false
}
}

View File

@@ -0,0 +1,8 @@
package com.yuyin.lib_base.http
import java.io.IOException
/**
* 自定义异常信息显示
*/
data class ApiException(val code:Int ,var msg: String) : IOException()

View File

@@ -0,0 +1,5 @@
package com.yuyin.lib_base.http
object BaseApiServer {
val api by lazy { RequestService.create<BaseApiService>() }
}

View File

@@ -0,0 +1,227 @@
package com.yuyin.lib_base.http
import com.yuyin.lib_base.model.*
import okhttp3.MultipartBody
import retrofit2.http.*
interface BaseApiService {
/**
* 获取房间详情
*/
@POST("user_report/report_list")
@FormUrlEncoded
suspend fun report_list(
@Field("xx") xx: String
): ResponseData<List<JuBaoBean>>
/**
*
*/
@POST("user_report/user_report")
@FormUrlEncoded
suspend fun user_report(
@FieldMap map: MutableMap<String, String>
): ResponseData<Any>
/**
* 首页房间分类
*/
@POST("room/get_category_list")
@FormUrlEncoded
suspend fun get_category_list(@Field("tid") tid: String): ResponseData<ArrayList<CategorRoomBean>>
/**
* 房间详情
*/
@POST("room/get_room_info")
@FormUrlEncoded
suspend fun get_room_info(@Field("rid") rid: String): ResponseData<EnterRoomInfo>
/**
* 我的cp详情
*/
@GET("gift/my_cp")
suspend fun my_cp(): ResponseData<MyCpBean>
/**
* 我的cp详情
*/
@GET("gift/my_cp_txk")
suspend fun my_cp_txk(@Query("type") type: String): ResponseData<ArrayList<MyCpTxBean>>
/**
* 排行榜前三名
*/
@GET("room/get_user_rank_top")
suspend fun get_user_rank_top(): ResponseData<RankTopThreeBean>
/**
* 注销账号
*/
@GET("user/logout_user_name")
suspend fun user_cancel(@Query("sms_code") sms_code: String): ResponseData<Any>
/**
* 获取系统基础配置
*/
@GET("api/get_system_base_config")
suspend fun get_system_base_config(
@Query("app_version") app_version: String,
@Query("app_type") app_type: String
): ResponseData<ConfigBean>
/**
* 获取系统基础配置
*/
@GET("user/user_open_verify_token")
suspend fun user_open_verify_token(): ResponseData<Any>
@Multipart
@POST("upload/img_upload")
suspend fun uploadImages2(@Part list: List<MultipartBody.Part>): ResponseData<List<String>>
/**
* 用户个人信息
*/
@GET("user/get_user_info")
suspend fun getUserinfo(): ResponseData<UserBean>
/**
* 退出登录
*/
@GET("user/user_log_out")
suspend fun user_log_out(): ResponseData<Any>
/**
* 获取验证码
* phone 手机号
* type 验证码类型
*/
@POST("login/send_sms")
@FormUrlEncoded
suspend fun verification(
@Field("mobile") phone: String,
@Field("type") type: String,
@Field("captcha_code") captcha_code: String,
@Field("captcha_key") captcha_key: String
): ResponseData<Any>
/**
* 添加关注
*/
@POST("user/follow_user")
@FormUrlEncoded
suspend fun follow(
@Field("follow_uid") followed_user_id: String
): ResponseData<Any>
/**
* 取消关注
*/
@POST("user/unfollow_user")
@FormUrlEncoded
suspend fun cancel_follow(
@Field("follow_uid") followed_user_id: String
): ResponseData<Any>
/**
* 我的余额记录
*/
@POST("user/get_user_money_log_list")
@FormUrlEncoded
suspend fun get_user_money_log_list(
@Field("page") page: String
): ResponseData<ArrayList<MoneyLogList>>
/**
* 我的积分记录
*/
@POST("user/get_user_integral_log_list")
@FormUrlEncoded
suspend fun get_user_integral_log_list(
@Field("page") page: String
): ResponseData<ArrayList<MoneyLogList>>
/**
* 获取用户关注列表
*/
@POST("user/get_user_follow_list")
@FormUrlEncoded
suspend fun get_user_follow_list(
@Field("page") page: String
): ResponseData<List<FollowFansBean>>
/**
* 获取用户粉丝列表
*/
@POST("user/get_user_fans_list")
@FormUrlEncoded
suspend fun get_user_fans_list(
@Field("page") page: String
): ResponseData<List<FollowFansBean>>
/**
* 获取房间详情
*/
@POST("room/enter_room_info")
@FormUrlEncoded
suspend fun enter_room_info(
@Field("rid") rid: String,
@Field("password") password: String
): ResponseData<EnterRoomInfo>
/**
* 获取用户基本信息详情
*/
@GET("user/get_base_user_info")
suspend fun get_base_user_info(@Query("uid") uid: String): ResponseData<Login>
/**
* 获取客服信息
*/
@GET("user/get_kf_message")
suspend fun get_kf_message(): ResponseData<List<kfMessageBean>>
/**
* 计算器配置
*/
@GET("api/calculator")
suspend fun calculator(): ResponseData<CalculatorBean>
/**
* 获取提现详情
*/
@GET("user/get_user_money")
suspend fun get_user_money(): ResponseData<UserMoneyBean>
/**
* 用户转赠积分
*/
@POST("user/user_give_integral")
@FormUrlEncoded
suspend fun user_give_integral(
@Field("reveive_uid") reveive_uid: String,
@Field("integral") integral: String,
@Field("last_login_device") last_login_device: String
): ResponseData<Any>
@GET("user_message/get_user_message_cover_info")
suspend fun get_user_message_cover_info(): ResponseData<MessageCount>
/**
* BaseApiService 添加
* 图形验证码
*/
@GET("login/create_captcha")
suspend fun create_captcha(): ResponseData<CaptchaBean>
}

View File

@@ -0,0 +1,157 @@
package com.yuyin.lib_base.http
import com.yuyin.lib_base.model.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MultipartBody
import retrofit2.http.Field
/**
*
*/
open class BaseRepository {
suspend fun <T : Any> request(call: suspend () -> ResponseData<T>): ResponseData<T> {
return withContext(Dispatchers.IO) { call.invoke() }.apply {
//这儿可以对返回结果errorCode做一些特殊处理比如token失效等可以通过抛出异常的方式实现
//例当token失效时后台返回errorCode 为 100下面代码实现,再到baseActivity通过观察error来处理
}
}
suspend fun report_list(): ResponseData<List<JuBaoBean>> =
request {
BaseApiServer.api.report_list("xx")
}
suspend fun user_report(map: MutableMap<String, String>): ResponseData<Any> =
request {
BaseApiServer.api.user_report(map)
}
suspend fun my_cp(): ResponseData<MyCpBean> = request {
BaseApiServer.api.my_cp()
}
suspend fun my_cp_txk(type: String): ResponseData<ArrayList<MyCpTxBean>> = request {
BaseApiServer.api.my_cp_txk(type)
}
suspend fun roomCategories(tid: String): ResponseData<ArrayList<CategorRoomBean>> = request {
BaseApiServer.api.get_category_list(tid)
}
suspend fun get_room_info(rid: String): ResponseData<EnterRoomInfo> = request {
BaseApiServer.api.get_room_info(rid)
}
suspend fun uploadImages2(imgFiles: List<MultipartBody.Part>): ResponseData<List<String>> =
request {
BaseApiServer.api.uploadImages2(imgFiles)
}
suspend fun getUserinfo(): ResponseData<UserBean> = request {
BaseApiServer.api.getUserinfo()
}
suspend fun user_log_out(): ResponseData<Any> = request {
BaseApiServer.api.user_log_out()
}
suspend fun get_system_base_config(
app_version: String,
app_type: String
): ResponseData<ConfigBean> = request {
BaseApiServer.api.get_system_base_config(app_version, app_type)
}
suspend fun user_open_verify_token(): ResponseData<Any> = request {
BaseApiServer.api.user_open_verify_token()
}
suspend fun verification(phone: String, type: String, captcha_code: String, captcha_key: String): ResponseData<Any> = request {
BaseApiServer.api.verification(phone, type, captcha_code, captcha_key)
}
suspend fun follow(follow_uid: String): ResponseData<Any> = request {
BaseApiServer.api.follow(follow_uid)
}
suspend fun cancel_follow(follow_uid: String): ResponseData<Any> = request {
BaseApiServer.api.cancel_follow(follow_uid)
}
suspend fun get_user_integral_log_list(
page: String
): ResponseData<ArrayList<MoneyLogList>> =
request {
BaseApiServer.api.get_user_integral_log_list(page)
}
suspend fun get_user_money_log_list(
page: String
): ResponseData<ArrayList<MoneyLogList>> =
request {
BaseApiServer.api.get_user_money_log_list(page)
}
suspend fun getFollowFansData(type: String, page: String): ResponseData<List<FollowFansBean>> =
request {
if (type == "1")
BaseApiServer.api.get_user_follow_list(page)
else
BaseApiServer.api.get_user_fans_list(page)
}
suspend fun enter_room_info(rid: String, password: String): ResponseData<EnterRoomInfo> =
request {
BaseApiServer.api.enter_room_info(rid, password)
}
suspend fun user_cancel(sms_code: String): ResponseData<Any> =
request {
BaseApiServer.api.user_cancel(sms_code)
}
suspend fun get_user_rank_top(): ResponseData<RankTopThreeBean> =
request {
BaseApiServer.api.get_user_rank_top()
}
suspend fun get_base_user_info(uid: String): ResponseData<Login> = request {
BaseApiServer.api.get_base_user_info(uid)
}
suspend fun get_kf_message(): ResponseData<List<kfMessageBean>> = request {
BaseApiServer.api.get_kf_message()
}
suspend fun calculator(): ResponseData<CalculatorBean> = request {
BaseApiServer.api.calculator()
}
suspend fun get_user_money(): ResponseData<UserMoneyBean> = request {
BaseApiServer.api.get_user_money()
}
suspend fun user_give_integral(
reveive_uid: String,
integral: String,
last_login_device: String
): ResponseData<Any> = request {
BaseApiServer.api.user_give_integral(reveive_uid, integral, last_login_device)
}
suspend fun get_user_message_cover_info(): ResponseData<MessageCount> =request {
BaseApiServer.api.get_user_message_cover_info()
}
/**
* BaseRepository 添加
*
*/
suspend fun create_captcha():ResponseData<CaptchaBean> =request {
BaseApiServer.api.create_captcha()
}
}

View File

@@ -0,0 +1,47 @@
package com.yuyin.lib_base.http;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public class CustomizeGsonConverterFactory extends Converter.Factory {
public static CustomizeGsonConverterFactory create() {
return create(new Gson());
}
public static CustomizeGsonConverterFactory create(Gson gson) {
return new CustomizeGsonConverterFactory(gson);
}
private final Gson gson;
private CustomizeGsonConverterFactory(Gson gson) {
if (gson == null) {
throw new NullPointerException("gson == null");
}
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new CustomizeGsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new CustomizeGsonRequestBodyConverter<>(gson, adapter);
}
}

View File

@@ -0,0 +1,40 @@
package com.yuyin.lib_base.http;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;
public class CustomizeGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
CustomizeGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}

View File

@@ -0,0 +1,47 @@
package com.yuyin.lib_base.http;
import android.util.Log;
import com.yuyin.lib_base.BuildConfig;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
public class CustomizeGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
CustomizeGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
//把responsebody转为string
String response = value.string();
if (BuildConfig.DEBUG) {
//打印后台数据
Log.e(BuildConfig.LIBRARY_PACKAGE_NAME, response);
}
ResponseData baseResponse = gson.fromJson(response, ResponseData.class);
// 这里只是为了检测code是否!=1,所以只解析HttpStatus中的字段,因为只要code和message就可以了
if (baseResponse.getCode() != 200&&baseResponse.getCode()!=202) {
value.close();
//抛出一个RuntimeException, 这里抛出的异常会到subscribe的onError()方法中统一处理
throw new ApiException(baseResponse.getCode(),baseResponse.getMsg());
}
try {
return adapter.fromJson(response);
} finally {
value.close();
}
}
}

View File

@@ -0,0 +1,8 @@
package com.yuyin.lib_base.http
import java.io.IOException
/**
* 自定义异常信息显示
*/
data class PassRoomException(var msg: String,var code: Int) : IOException()

View File

@@ -0,0 +1,127 @@
package com.yuyin.lib_base.http
import android.util.Log
import com.yuyin.lib_base.App
import com.yuyin.lib_base.BuildConfig
import com.yuyin.lib_base.Const
import com.yuyin.lib_base.base.UserManager
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.net.Proxy
import java.net.URLDecoder
import java.util.concurrent.TimeUnit
object RequestService {
private const val READ_TIMEOUT = 60L
private const val WRITE_TIMEOUT = 60L
private const val CONNECT_TIMEOUT = 30L
val BASE_URL = Const.URL1
private var mRetrofit: Retrofit? = null
private fun getClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor { message ->
try {
val text: String = URLDecoder.decode(message, "utf-8")
if (BuildConfig.DEBUG) {
Log.e("OKHttp-----", text)
}
} catch (e: Exception) {
e.printStackTrace()
// Log.e("OKHttp-----", message)
}
}
interceptor.level = HttpLoggingInterceptor.Level.BODY
return OkHttpClient.Builder()
.proxy(Proxy.NO_PROXY)
.retryOnConnectionFailure(true)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor { chain ->
val original: Request = chain.request()
val requestBuilder: Request.Builder = original.newBuilder()
if (UserManager.IS_LOGIN) {
requestBuilder.header("token", UserManager.user.login_token)
}
val currentTimeMillis = (System.currentTimeMillis()/1000).toString()
requestBuilder.header("app-sign", SignatureVerification.getAppSign(currentTimeMillis))
requestBuilder.header("timestamp", currentTimeMillis)
val request: Request = requestBuilder.build()
request.url().newBuilder()
.addQueryParameter("login_token", UserManager.user.login_token)
// .addQueryParameter("lat", App.latitude.toString())
// .addQueryParameter("lng", App.longitude.toString())
// .addQueryParameter("app_run_name", "yese")
.build()
chain.proceed(request)
}
.addInterceptor(interceptor)
.addInterceptor { chain ->
val request = chain.request()
val s = UserManager.user.login_token
if (UserManager.IS_LOGIN) {
val httpUrl = request.url()
.newBuilder() /* add parameter */
.removeAllQueryParameters("login_token")
.addQueryParameter("login_token", s)
// .addQueryParameter("lat", App.latitude.toString())
// .addQueryParameter("lng", App.longitude.toString())
// .addQueryParameter("app_run_name", "yese")
.build()
val build = request.newBuilder()
.url(httpUrl)
.build()
chain.proceed(build)
} else {
val httpUrl = request.url()
.newBuilder()
// .addQueryParameter("app_run_name", "yese")
.build()
val build = request.newBuilder()
.url(httpUrl)
.build()
chain.proceed(build)
}
}
.build()
}
fun getRetrofit(): Retrofit {
return mRetrofit ?: Retrofit.Builder()
.baseUrl(BASE_URL)
.validateEagerly(true)
.addConverterFactory(CustomizeGsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.client(getClient())
.build()
.also { mRetrofit = it }
}
fun getRetrofit2(): Retrofit {
return mRetrofit ?: Retrofit.Builder()
.baseUrl(BASE_URL)
.validateEagerly(true)
.addConverterFactory(CustomizeGsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.client(getClient())
.build()
.also { mRetrofit = it }
}
inline fun <reified T> create() = getRetrofit().create(T::class.java)
inline fun <reified T> create2() = getRetrofit2().create(T::class.java)
}

View File

@@ -0,0 +1,7 @@
package com.yuyin.lib_base.http
/**
* actor 晴天 create 2019/5/31
* 响应结果数据
*/
data class ResponseData<out T>(val code: Int, var msg: String, val data: T)

View File

@@ -0,0 +1,35 @@
package com.yuyin.lib_base.http
import android.util.Base64
import java.math.BigInteger
import java.security.MessageDigest
/**
* 验签
*/
object SignatureVerification {
/**
* 秘钥(后台定义)
*/
var theSecretKey = "R0M2NzFPU1cxM1hSQUtNVFlKWVI3UFVJUUJCUzUyWU8="
fun getAppSign(currentTimeMillis: String): String {
try {
val sign = theSecretKey + currentTimeMillis
return encodeBase64(sign.md5())
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
return ""
}
fun encodeBase64(input: String): String {
val inputBytes = input.toByteArray()
return Base64.encodeToString(inputBytes, Base64.NO_WRAP)
}
fun String.md5(): String {
val md5 = MessageDigest.getInstance("MD5")
return BigInteger(1, md5.digest(toByteArray())).toString(16).padStart(32, '0')
}
}

View File

@@ -0,0 +1,51 @@
package com.yuyin.lib_base.im;
import android.graphics.Color;
import com.yuyin.lib_base.R;
public class IMConfig {
private static IMConfig imConfig;
static {
imConfig = new IMConfig();
}
public static IMConfig getInstance() {
return imConfig;
}
// IM 私聊头像 圆角
public int avatarRadius = 50;
// IM 头像大小
public int avatarSize = 45;
// 右边聊天气泡
public int getRightBubble() {
return R.drawable.base_chat_bubble_other_bg;
}
// 左边聊天气泡
public int getLeftBubble() {
return R.drawable.base_chat_bubble_self_bg;
}
// 私聊背景
public int getIMBackground() {
return Color.parseColor("#ffffff");
}
public int getLeftTextColor() {
return Color.parseColor("#111111");
}
public int getRightTextColor() {
return Color.parseColor("#111111");
}
}

View File

@@ -0,0 +1,37 @@
package com.yuyin.lib_base.im;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.yuyin.lib_base.R;
import com.yuyin.lib_base.arouter.AroutUtil;
import com.yuyin.lib_base.util.GlideUtil;
public class IMPrivateChatHeadView extends FrameLayout {
public IMPrivateChatHeadView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.layout_private_chat, this);
view.findViewById(R.id.iv_close).setOnClickListener(v -> {
this.setVisibility(View.GONE);
});
}
}

View File

@@ -0,0 +1,362 @@
package com.yuyin.lib_base.model
import com.lzy.imagepicker.bean.ImageItem
import java.io.Serializable
data class McListBean(
var owner_info: McInfo = McInfo(),
var host_info: McInfo = McInfo(),
var mc_list: List<McInfo> = ArrayList(),
var room_dating_stage: Int = 0,
var dating_surplus_time: Int = 0,
var xq_talent_time: Int = 0,
var today_hot_value: Int = 0,
var room_micro_line_data: RoomHeartLineBean = RoomHeartLineBean(),
val room_new_auction_status: Int = 0,
val room_xq_stage: Int = 0,
var auction_surplus_time: Int = 0,
var room_auction_status: Int = 0,
var room_auction_info: RoomAuctionInfo = RoomAuctionInfo(),
val room_song_status: Int = 0,
var room_song_info: RoomSongInfo = RoomSongInfo(),
)
data class RoomAuctionInfo(
var relation_id: Int = 0,
val relation_name: String = "",
var gift_img: String = "",
var gid: Int = 0,
var gift_name: String = "",
var day: Int = 0
)
data class RoomSongInfo(
val is_producer: Int = 0,
val is_user_auction: Int = 0,
val producer_info: ProducerInfo = ProducerInfo(),
val surplus_time: Int = 0,
val user_auction_info: UserAuctionInfo = UserAuctionInfo(),
val user_info: UserInfo = UserInfo()
)
data class ProducerInfo(
val head_pic: String = "", val uid: Int = 0
)
data class UserAuctionInfo(
val auction_price: Int = 0,
val head_pic: String = "",
val nick_name: String = "",
val uid: Int = 0
)
data class UserInfo(
val auction_price: String = "",
val charm_value: Int = 0,
val head_pic: String = "",
val uid: Int = 0
)
data class RoomHeartLineBean(
val room_line_1: DatingRoomLine = DatingRoomLine(),
val room_line_2: DatingRoomLine = DatingRoomLine(),
val room_line_3: DatingRoomLine = DatingRoomLine()
)
data class DatingRoomLine(
val is_line: Int = 0, val rank_value: Int = 0
)
data class JuBaoBean(
val id: String = "", val type_name: String = ""
)
data class ImageItems(
var type: Int = 0, var image: ImageItem = ImageItem()
)
data class McInfo(
var isSelect: Boolean = false,
var mc_status: Int = 0,
var mc_user_info: McUserInfo = McUserInfo()
)
data class McUserInfo(
var avatar_base_image: String = "",
var avatar_play_image: String = "",
var micro_play_image: String = "",
var is_forbid_micro: Int = 0,
var charm_value: Int = 0,
var sex: Int = 0,
var head_pic: String = "",
var nick_name: String = "",
var uid: String = "",
var xq_uid_sm: String = "",
var light_type: String = "",
var auction_price: String = "",
var nick_name_color: String = "",
var is_online: Int = 0,
var user_auction_price: String = "",
var contribution_value: String = "",
var song_name: String = "",
var frame_gid_image: String = "",
var centre_gid_image: String = "",
var above_gid_image: String = "",
var below_gid_image: String = "",
var left_gid_image: String = "",
var right_gid_image: String = "",
var frame_gid_images: String = "",
var centre_gid_images: String = "",
var above_gid_images: String = "",
var below_gid_images: String = "",
var left_gid_images: String = "",
var right_gid_images: String = "",
val is_new: Int=0,
val user_role: Int=0,
val is_spotlight: Int=0,
val trac_line:Int=0,
var micro_surplus_time:Int=0,
var wish_gift_name:String="",
)
data class ConfigBean(
var del_user_relation_money: String = "",
var ry_app_key: String = "",
var websocket_server_address: String = "",
var silver_price: Int = 0,
var gold_price: Int = 0,
var drill_price: Int = 0,
var platina_price: Int = 0,
var promise_price: Int = 0,
var violet_price: Int = 0,
var europe_price: Int = 0,
var dial_price: Int = 0,
var withdraw_rate: Float = 0.0f,
var version_app: String = "",
var version_note: String = "",
var version_down_url: String = "",
var tencentyun_im_appid: String = "",
var five_price: Int = 0,
var six_price: Int = 0,
var version_is_force_update: Int = 0,
)
data class CategorRoomBean(
var category_name: String = "", val cate_id: String = "", val tid: String = "", var isSelect: Boolean = false
)
data class MyCpBean(
var cp_level: String = "",
var u_avatar_play_image: String = "",
var receive_avatar_play_image: String = "",
val uid: String = "",
val receive_uid: String = "",
var cp_value: Int=0,
var is_delete: String = "",
var u_nick_name: String = "",
var u_head_pic: String = "",
var receive_nick_name: String = "",
var receive_head_pic: String = "",
var next_cp_level: String = "",
var next_cp_value: String = "",
)
data class MyCpTxBean(
var level: String = "",
var head_decorate_id: String = "",
var head_decorate_img: String = "",
var head_decorate_play_img: String = "",
var cp_tx_img: String = "",
var cp_tx_play_img: String = "",
var cp_tx_id: String = "",
var udid: String = "",
var js_suo: String = "", //1解锁 2未解锁
var is_using: String = "", //1使用中 2未使用
var cp_tx_title: String = "",
var head_decorate_title: String = "",
)
data class EnterRoomInfo(
var is_gashapon: String = "",
var agora_app_id: String = "",
var agora_token: String = "",
var agora_rtm_token: String = "",
var rid: String = "",
var room_number: String = "",
var tid: String = "",
var cate_id: String = "",
var is_need_password: String = "",
var room_name: String = "",
var room_password: String = "",
var room_cover: String = "",
var room_owner_uid: String = "",
var room_host_uid: String = "",
var room_intro: String = "",
var room_background_id: String = "",
var is_online: String = "",
var visitor_num: String = "",
var room_status: String = "",
var room_background_image: String = "",
var is_collect: String = "",
var room_welcome: String = "",
var open_box_status: String = "",
var enter_user_type: String = "",
var is_host: String = "",
var pretty_room_number: Int = 0,
var is_open_box: Int = 0,
var open_silver_box_status: Int = 0,
var is_super_admin: Int = 0,
var is_lock: Int = 1,
var is_pk: Int = 0,
var is_hide_enter_room: Int = 0,
var is_dating: Int = 0,
var is_song: Int = 0,
var is_new: Int = 0,
var game_status: Int = 0,
var game_id: String = "",
var apply_status:Int = 0,
var reamrks: String = "",
var open_blind_box_term:Int=0,
var blind_box_term_over_time:Int=0
) : Serializable
data class IsOpenBean(
var is_open_box: Int = 0,
var is_open_box_one: Int = 0,
var is_open_box_two: Int = 0,
var is_open_box_three: Int = 0,
var is_open_box_four: Int = 0,
)
data class UserBean(
var uid: String = "",
var user_name: String = "",
var base64_nick_name: String = "",
var head_pic: String = "",
var login_token: String = "",
var sex: String = "",
var birthday: String = "",
var special_uid: String = "",
var money: String = "",
var frozen_money: String = "",
var integral: String = "",
var room_profit: String = "",
var is_real: String = "",
var follow_num: String = "",
var fans_num: String = "",
var autograph: String = "",
var hobby: String = "",
var country: String = "",
var province: String = "",
var city: String = "",
var nick_name: String = "",
var collect_room_num: String = "",
var constellation: String = "",
var reg_url: String = "",
var reg_code: String = "",
val is_open_verify: Int = 2,
var rid: String = "",
var guild_id: String = "",
var contribution_level_image: String = "",
var charm_level_image: String = "",
var is_hide_enter_room: Int = 0,
var is_room_hiding: Int = 0,
var nobility_image: String = "",
var is_teenager: Int = 0,
var cp_num: Int = 0,
var is_open_address: Int = 0,
var vid: Int = 0
)
data class MyListBean(
val img: Int = 0,
val title: String = "",
)
data class MoneyLogList(
var change_type: String = "",
var change_value: String = "",
var remarks: String = "",
var add_time: String = "",
var change_type_desc: String = ""
)
data class FollowFansBean(
val is_online:String="",
val fid: String = "",
val fuid: String = "",
val follow_uid: String = "",
val uid: String = "",
val head_pic: String = "",
val sex: String = "",
val special_uid: String = "",
val nick_name: String = "",
var is_follow: Int = 0
)
data class RankTopThreeBean(
val user_charm_rank_list: ArrayList<CharmRankTopBean> = ArrayList(),
val user_contribution_rank_list: ArrayList<ContributionRankTopBean> = ArrayList()
)
data class CharmRankTopBean(
val uid: String = "",
val head_pic: String = "",
val charm_value: String = "",
val nick_name: String = ""
)
data class ContributionRankTopBean(
val uid: String = "",
val head_pic: String = "",
val contribution_value: String = "",
val nick_name: String = ""
)
data class UserMoneyBean(
val alipay_account: String,
val alipay_name: String,
val bank_card: Any,
val bank_card_number: Any,
val bank_user_name: Any,
val gifts_income: Double,
val integral: String,
val is_ali: Int,
val money: String,
val open_bank: Any,
val real_name: String,
val room_profit: String,
val uid: Int
)
data class MessageCount(
val order_last_message: String,
val order_no_read_count: Int,
val relation_last_message: String,
val relation_no_read_count: Int,
val send_order_message_count: Int,
val system_no_read_count: Int,
val zone_last_message: String,
val zone_no_read_count: Int,
val system_last_message:SystemLastMessage
)
data class SystemLastMessage(
val title: String, val add_time: String
)
/**
* BaseBean 添加
*/
data class CaptchaBean(
val image: String,
val key: String
)

View File

@@ -0,0 +1,62 @@
package com.yuyin.lib_base.model;
import com.yuyin.lib_base.model.EnterRoomInfo;
/**
* 作者:sgm
* 类描述:
*/
public class FirstEvent {
/**
*
*/
private String msg;//消息内容
private String tag; //消息类型
private EnterRoomInfo enterRoom;
public FirstEvent() {
}
public FirstEvent(String msg, String tag, EnterRoomInfo enterRoom) {
this.msg = msg;
this.tag = tag;
this.enterRoom = enterRoom;
}
public FirstEvent(String msg, String tag) {
super();
this.msg = msg;
this.tag = tag;
}
public FirstEvent(String msg) {
this.msg = msg;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public EnterRoomInfo getEnterRoom() {
return enterRoom;
}
public void setEnterRoom(EnterRoomInfo enterRoom) {
this.enterRoom = enterRoom;
}
}

View File

@@ -0,0 +1,55 @@
package com.yuyin.lib_base.model
import com.google.gson.annotations.SerializedName
import org.litepal.crud.LitePalSupport
data class CalculatorBean(
var is_calculator: Float = 0.0f
)
data class kfMessageBean(
var image: String = "",
var content: String = "",
var contents: String = "",
)
class SearchHis : LitePalSupport() {
var id: Long = 0
var text: String = ""
}
class Login : LitePalSupport() {
@SerializedName(value = "id", alternate = ["uid"])
var uid: Long = 0
var head_pic: String = ""
var user_name: String = ""
var login_token: String = ""
var nick_name: String = ""
var sex: String = ""
var birthday: String = ""
var special_uid: String = ""
var money: String = ""
var frozen_money: String = ""
var integral: String = ""
var room_profit: String = ""
var is_real: String = ""
var follow_num: String = ""
var fans_num: String = ""
var autograph: String = ""
var country: String = ""
var province: String = ""
var city: String = ""
var collect_room_num: String = ""
var ry_token: String = ""
var is_kf = 0
var kf_uid: String = ""
var is_reg: String = ""
val user_sig: String = ""
}
class PhotoMemory : LitePalSupport() {
var photo: String = ""
var head_pic: String = ""
}

View File

@@ -0,0 +1,18 @@
package com.yuyin.lib_base.model
import com.google.gson.annotations.SerializedName
data class Wxmodel(
var appid: String = "",
var noncestr: String = "",
@SerializedName("package")
var packageX: String = "",
var partnerid: String = "",
var prepayid: String = "",
var timestamp: Int = 0,
var sign: String = "",
)
data class AliH5model(
var pay_info:String=""
)

View File

@@ -0,0 +1,66 @@
package com.yuyin.lib_base.socket;
import androidx.annotation.NonNull;
import com.zhangyf.gift.bean.GiftIdentify;
/**
* @author zhangyf
* @date 2017/3/20
*/
public abstract class BaseGiftBean implements GiftIdentify, Cloneable {
/**
* 礼物计数
*/
private int giftCount;
/**
* 礼物刷新时间
*/
private long latestRefreshTime;
/**
* 当前index
*/
private int currentIndex;
@Override
public int getTheGiftCount() {
return giftCount;
}
@Override
public long getTheLatestRefreshTime() {
return latestRefreshTime;
}
@Override
public int getTheCurrentIndex() {
return currentIndex;
}
@Override
public void setTheGiftCount(int count) {
giftCount = count;
}
@Override
public void setTheLatestRefreshTime(long time) {
latestRefreshTime = time;
}
@Override
public void setTheCurrentIndex(int index) {
currentIndex = index;
}
@Override
public int compareTo(@NonNull GiftIdentify o) {
return (int) (this.getTheLatestRefreshTime() - o.getTheLatestRefreshTime());
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View File

@@ -0,0 +1,25 @@
package com.yuyin.lib_base.socket
import android.util.Log
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft_6455
import org.java_websocket.handshake.ServerHandshake
import java.net.URI
open class JWebSocketClient(serverUri: URI?) : WebSocketClient(serverUri, Draft_6455()) {
override fun onOpen(handshakedata: ServerHandshake) {
Log.e("JWebSocketClient", "onOpen()")
}
override fun onMessage(message: String) {
Log.e("JWebSocketClient", "onMessage()")
}
override fun onClose(code: Int, reason: String, remote: Boolean) {
Log.e("JWebSocketClient", "onClose()")
}
override fun onError(ex: Exception) {
Log.e("JWebSocketClient", "onError()")
}
}

View File

@@ -0,0 +1,529 @@
package com.yuyin.lib_base.socket
import com.yuyin.lib_base.model.McListBean
data class SocketBean(
val code: Int, val data: Any
)
data class SocketSendBeanAll(
val code: Int, val data: SocketSendBeanAllSub = SocketSendBeanAllSub()
)
data class SocketSendBeanAllSub(
val room_info: SocketSendRoomBean = SocketSendRoomBean(),
val gift_list: ArrayList<SocketSendGiftBean> = ArrayList()
)
data class SocketSendRoomBean(
var rid: String = "", var room_name: String = ""
)
data class SocketNumBean(
val hid: String, val onilne_num: Int
)
data class RongIMMcBean(
var data: McListBean = McListBean(), var messageType: Int = 0, var msg: String = ""
)
data class SocketMicBean(
val code: Int, val data: McListBean = McListBean()
)
data class SocketOpenBoxBean(
val code: Int, val data: SocketOpenBean = SocketOpenBean()
)
data class SocketMtlBean(
val code: Int, val data: SocketMtlDataBean = SocketMtlDataBean()
)
data class SocketEditShangMaiBean(
val code: Int, val data: EditShangMaiBean, val msg: String
)
data class EditShangMaiBean(
val id: String, val micro_id: Int, val rid: String, val time: String, val uid: String
)
data class SocketGame(
val code: Int,
val data: SocketGameData,
val msg: String
)
data class SocketBarBean(
val code: Int,
val data: SocketBarData,
val msg: String
)
data class SocketBarData(
val img: String,
val receive_uid: String,
)
data class SocketBarListBean(
val code: Int,
val data: SocketBarListData,
val msg: String
)
data class SocketBarListData(
val img: String,
val to_uid_list:ArrayList<String> = ArrayList(),
)
data class SocketGameData(
val game_id: String,
val game_status: Int,
val rid: String
)
data class SocketMtlDataBean(
var u_nick_name: String = "",
var u_receive_name: String = "",
var level: String = "",
var gift_name: String = "",
var num: String = "",
var date: String = "",
)
data class SocketOpenBean(
val is_europe: Int = 0,
val gift_list: ArrayList<SocketGiftList> = ArrayList(),
val user_info: SocketGiftUserBean = SocketGiftUserBean()
)
data class SocketGiftList(
var gift_name: String = "",
var gift_price: String = "",
var base_image: String = "",
var open_num: String = "",
var type_name: String = ""
)
data class SocketGiftUserBean(
var uid: String = "", var nick_name: String = ""
)
data class SocketSendBean(
val code: Int, val data: ArrayList<SocketSendGiftBean> = ArrayList()
)
data class SocketSendGiftBean(
var integral:String="",
var gift_name: String = "",
var gift_type: String = "",
var num: String = "",
var base_image: String = "",
var play_image: String = "",
val send_user_info: SocketSendGiftUserBean = SocketSendGiftUserBean(),
val recived_user_info: SocketSendGiftUserBean = SocketSendGiftUserBean(),
var location: IntArray = IntArray(2),
var is_blind_gift: String = "",
var blind_box_name: String = "",
var blind_box_image: String = "",
val gift_price: String = "",
val surplus_time: Int = 0,
val rid: String = "",
var win_multiple: Int = 0,
var is_multiple_gift: Int = 0,
var isMark: Int = 0,
) : BaseGiftBean() {
override fun getTheGiftId(): Int {
return gift_name.hashCode()
}
override fun setTheGiftId(gid: Int) {
}
override fun getTheUserId(): Int {
return send_user_info.uid.toInt()
}
override fun setTheUserId(uid: Int) {
}
override fun getTheSendGiftSize(): Int {
return 1
}
override fun setTheSendGiftSize(size: Int) {
}
override fun getTheGiftStay(): Long {
return 3000
}
override fun setTheGiftStay(stay: Long) {
}
}
data class SocketSendGiftUserBean(
var uid: String = "", var nick_name: String = "", var head_pic: String = ""
)
data class SocketPKBean(
val code: Int = 0, val data: SocketPkData = SocketPkData(), val msg: String = ""
)
data class SocketPkData(
val end_seconds: Int = 0,
val group_a_value: String = "",
val group_b_value: String = "",
val is_close: Int = 0,
val pk_theme: String = "",
val pk_type: Int = 0,
val winner_group: Int = 0,
var is_pk: Int = 2
)
data class SocketNobilityBean(
val code: Int, val data: SocketNobility, val msg: String
)
data class SocketNobility(
val nick_name: String, val nobility_image: String, val nobility_name: String
)
data class SocketChatHallInfoBean(
val code: Int, val data: SocketChatHallInfo, val msg: String
)
data class SocketChatHallInfo(
var price: String = "", val info: Info, val surplus_time: Int
)
data class Info(
val content: String, val head_pic: String, val nick_name: String, val price: Int, val uid: Int
)
data class SocketSongBean(
val code: Int, val data: List<SocketSong>, val msg: String
)
data class SocketSong(
val base64_nick_name: String,
val did: Int,
val duration: Int,
val nick_name: String,
val poster: String,
val rid: Int,
val sex: Int,
val singer: String,
val song_code: String,
val song_name: String,
val uid: Int,
val is_accapella: Int,
val micro_uid: Int,
val is_add: Int,
val type: Int,
var aid: Int,
val micro_base64_nick_name: String,
val micro_nick_name: String,
val micro_sex: Int,
)
data class SocketAisle(
val data: SocketAisleBean
)
data class SocketAisleBean(
val common_aisle: List<CommonAisle>,
val common_count: Int,
val common_total_count: Int,
val priority_aisle: List<CommonAisle>,
val priority_count: Int,
val priority_total_count: Int,
val gid: Int,
val gift_name: String,
val base_image: String
)
data class CommonAisle(
val base64_nick_name: String,
val head_pic: String,
val id: Int,
val nick_name: String,
val rank_value: Int,
val rid: Int,
val type: Int,
val uid: Int,
var check: Boolean = false
)
data class SocketBindHeartLineBean(
val data: SocketBindHeartLine,
)
data class SocketBindHeartLine(
val pendant_image: String="", val receive_info: UserInfo, val user_info: UserInfo
)
data class UserInfo(
val head_pic: String, val nick_name: String, val uid: Int
)
data class SocketPrivateCottage(
val data: PrivateCottage,
)
data class PrivateCottage(
var rid: String, var prid: Int = 0, var agora_token: String = "", var agora_app_id: String = ""
)
data class SocketPrivateUpdateTimeBean(
val code: Int,
val data: SocketSendGiftBean,
)
data class SocketPrivateCardBean(
val data: SocketPrivateCard,
)
data class SocketPrivateCard(
val content: String, val id: Int, val type: Int
)
data class SocketAuctionBean(
val code: Int,
val data: SocketAuction,
)
data class SocketAuction(
val auction_user_info: AuctionUserInfo,
val sign_user_info: AuctionUserInfo,
val relation_name: String,
val is_push_user_song_award: Int,
val is_push_host_award: Int,
val push_user_song_award:PushUserAward,
val push_host_award:PushUserAward,
)
data class PushUserAward(
val content: String,
val head_pic: String,
val nick_name: String,
val uid: Int
)
data class AuctionUserInfo(
val head_pic: String, val nick_name: String, val uid: Int
)
data class SocketHugMicroBean(
val data: SocketHugMicro,
)
data class SocketHugMicro(
val micro_id: Int, val rid: String, val surplus_time: Int, val uid: String
)
data class SocketNewsComerRankBean(
val code: Int,
val data: NewsComerRankBean,
)
data class NewsComerRankBean(
val list: List<NewsComerRank>
)
data class NewsComerRank(
val base64_nick_name: String,
val head_pic: String,
val id: Int,
val nick_name: String,
val price: String,
val uid: Int
)
data class SocketCoinGift(
val code: Int, val data: SocketSendGiftBean = SocketSendGiftBean()
)
data class SocketQuiteRoomBean(
val data: SocketQuiteRoom,
)
data class SocketQuiteRoom(
val rid: String, val type: String
)
data class SocketSpriteMonsterInfo(
var code: Int, val data: SpriteMonsterInfo
)
data class SpriteMonsterInfo(
val airship: String,
val integral: String,
val is_finsh: Int,
val multiple_list: List<Multiple>,
val surplus_time: Int,
val win_number: Int,
val win_type_info: List<WinTypeInfo>,
val user_win_gift_list: List<UserWinGift>,
)
data class Gift(
val base_image: String,
val gid: Int,
val gift_name: String,
val gift_price: String,
val num: Int,
val open_num: Int,
val type_name: String
)
data class Multiple(
val base_image: String,
val id: Int,
val multiple: String,
val num: Int,
val type: Int,
val type_name: String
)
data class SocketSpriteResultInfo(
val code: Int,
val data: SpriteResultInfo,
)
data class SpriteResultInfo(
val airship: String,
val integral: String,
val evil_wind_type: Int,
val is_evil_wind: Int,
var is_win: Int,
val win_count: Int,
val win_gift_list: List<WinGift>,
val win_type_info: List<WinTypeInfo>
)
data class WinGift(
val base_image: String,
val gid: Int,
val gift_name: String,
val gift_price: String,
val num: Int,
val open_num: Int,
val type_name: String
)
data class WinTypeInfo(
val base_image: String, val type_name: String, val win_number: Int
)
data class UserWinGift(
val gift_list: List<Gift>,
val user_info: UserInfo
)
data class SocketNotificationBean(
val code: Int,
val data: SocketNotificationData,
val msg: String
)
data class SocketNotificationData(
val content: String,
val head_pic: String,
val nick_name: String,
val pay_integral: String,
val rid: Int,
val over_time: Int,
val type: Int,
val uid: Int
)
data class SocketOpenBox5(
val code: Int,
val data: SocketBoxList,
val msg: String
)
data class SocketBoxList(
val amount: Int,
val base_image: String,
val gift_name: String,
val nb_id: Int,
val nbl_id: Int,
val total_amount: Int,
val gift_price: Int,
val nbl_sn:Int
)
data class BoxOpenCJBean(
val amount: Int,
val base_image: String,
val gift_name: String,
val nbl_id: Int,
val total_amount: Int,
val nbl_sn:Int
)
data class SocketBT(
val code: Int,
val data: SocketBTData,
val msg: String
)
data class SocketBTData(
val xxs_box_consume: String,
val xxs_dis_box_consume: Float,
val xxs_user_consume: Float,
val fact_per:Float
)
data class SocketBlindBoxProgressBean(
val code: Int,
val data: SocketBlindBoxProgress,
val msg: String
)
data class SocketBlindBoxProgress(
val max_num: Int,
val min_num: Int
)
data class SocketBlindBoxOpenBean(
val code: Int,
val data: SocketBlindBoxOpen,
val msg: String
)
data class SocketBlindBoxOpen(
val term_id: String,
val content: String,
val over_time: Int
)

View File

@@ -0,0 +1,87 @@
package com.yuyin.lib_base.ui;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.yuyin.lib_base.R;
import com.yuyin.lib_base.base.BaseViewModel;
import com.yuyin.lib_base.model.UserMoneyBean;
import com.yuyin.lib_base.util.GlideUtil;
public class GiftGoldCoinsWindow extends Dialog {
private BaseViewModel roomViewModel;
private Context context;
private TextView tv_name, tv_user_id, tv_queding, tv_jinbi;
private EditText et_num;
private ImageView iv_img;
private String head_pic;
private String uid;
private String nickName;
public GiftGoldCoinsWindow(Context context, BaseViewModel roomViewModel, String head_pic, String uid, String nickName) {
super(context, R.style.myChooseDialog);
this.roomViewModel = roomViewModel;
this.context = context;
this.head_pic = head_pic;
this.uid = uid;
this.nickName = nickName;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_gift_gold_coins);
setWidows();
tv_name = findViewById(R.id.tv_name);
tv_user_id = findViewById(R.id.tv_user_id);
tv_queding = findViewById(R.id.tv_queding);
tv_jinbi = findViewById(R.id.tv_jinbi);
et_num = findViewById(R.id.et_num);
iv_img = findViewById(R.id.iv_img);
roomViewModel.get_user_money();
roomViewModel.getUserMoney().observe((LifecycleOwner) context, userMoneyBean -> tv_jinbi.setText("" + userMoneyBean.getIntegral() + ""));
////
GlideUtil.INSTANCE.loadImglogo(context, head_pic,iv_img);
tv_name.setText(nickName);
tv_user_id.setText("ID:"+uid);
tv_queding.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TextUtils.isEmpty(et_num.getText().toString().trim())) {
Toast.makeText(context, "数量不能为空", Toast.LENGTH_SHORT).show();
return;
}
roomViewModel.UserGiveIntegral(uid+ "", et_num.getText().toString().trim());
}
});
}
public void disss() {
// RoomManager.getInstance().sendPrivateMessage3(otherUserBean.getUid() + "", "给您发了" + et_num.getText().toString() + " 红包");
dismiss();
}
private void setWidows() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.width = QMUIDisplayHelper.getScreenWidth(context);
lp.height = (int) (Float.parseFloat(QMUIDisplayHelper.getScreenWidth(context) + "") / 375 * 420);
lp.alpha = 1.0f;
lp.gravity = Gravity.BOTTOM;
getWindow().setAttributes(lp);
this.setCanceledOnTouchOutside(true);
}
}

View File

@@ -0,0 +1,78 @@
package com.yuyin.lib_base.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import com.yuyin.lib_base.R
import com.yuyin.lib_base.base.BaseActivity
import com.yuyin.lib_base.base.BaseViewModel
import kotlinx.android.synthetic.main.activity_x5webview.*
class X5WebViewActivity : BaseActivity<BaseViewModel>() {
private fun canGoBack(): Boolean {
return x5wv_view != null && x5wv_view.canGoBack()
}
override fun onBackPressed() {
if (canGoBack()) {
x5wv_view.goBack()
} else {
finish()
}
}
companion object {
fun forward(context: Context, url: String, title: String) {
val intent = Intent(context, X5WebViewActivity::class.java)
intent.putExtra("URL", url)
intent.putExtra("title", title)
context.startActivity(intent)
}
}
override fun startObserve() {
}
override fun getLayoutId(): Int {
return R.layout.activity_x5webview
}
override fun initView() {
}
override fun initData() {
val url = intent.getStringExtra("URL")
val title = intent.getStringExtra("title")
x5wv_view.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
x5wv_view.loadUrl(url)
return true
}
override fun onPageFinished(webView: WebView, s: String) {
val handler = Handler()
handler.postDelayed({ //要执行的操作
if (title.isNullOrEmpty()) {
tv_main_title.text = webView.title
} else {
tv_main_title.text = title
}
}, 100) //2秒后执行Runnable中的run方法
}
}
url?.let { x5wv_view.loadUrl(it) }
iv_base_back.setOnClickListener {
onBackPressed()
}
}
override fun initEvent() {
}
}

View File

@@ -0,0 +1,50 @@
package com.yuyin.lib_base.ui.followfans
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.yuyin.lib_base.R
import com.yuyin.lib_base.adapter.MyPagerAdapter
import com.yuyin.lib_base.arouter.AroutUtil.LIB_FOLLOW_FANS
import com.yuyin.lib_base.base.BaseActivity
import com.yuyin.lib_base.base.BaseDataBindingActivity
import com.yuyin.lib_base.base.BaseViewModel
import com.yuyin.lib_base.databinding.ActivityFollowFansBinding
import kotlinx.android.synthetic.main.activity_follow_fans.*
@Route(path = LIB_FOLLOW_FANS)
class FollowFansActivity : BaseDataBindingActivity<BaseViewModel, ActivityFollowFansBinding>() {
private val titleList: ArrayList<String> = ArrayList()
private val mFragments: ArrayList<Fragment> = ArrayList()
private var mAdapter: MyPagerAdapter? = null
override fun startObserve() {
}
override fun getLayoutId(): Int = R.layout.activity_follow_fans
override fun initView() {
}
override fun initData() {
var currentTab = intent.getIntExtra("selectTab", 0)
if (currentTab == 0) {
tvaaa.text = "关注"
titleList.add("关注")
mFragments.add(FollowFansFragment.getInstance("1"))
} else {
tvaaa.text = "粉丝"
titleList.add("粉丝")
mFragments.add(FollowFansFragment.getInstance("2"))
}
mAdapter = MyPagerAdapter(supportFragmentManager, mFragments, titleList)
view_pager.adapter = mAdapter
tab_layout.setViewPager(view_pager)
tab_layout.setSnapOnTabClick(true)
view_pager.offscreenPageLimit = mFragments.size
}
override fun initEvent() {
}
}

View File

@@ -0,0 +1,125 @@
package com.yuyin.lib_base.ui.followfans
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.launcher.ARouter
import com.yuyin.lib_base.R
import com.yuyin.lib_base.base.BaseViewModelFragment
import com.yuyin.lib_base.model.FollowFansBean
import com.yuyin.lib_base.ui.followfans.adapter.FollowFansAdapter
import com.yuyin.lib_base.util.showToast
import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener
import com.yuyin.lib_base.arouter.AroutUtil
import kotlinx.android.synthetic.main.fragment_follow_fans.*
import java.util.*
class FollowFansFragment : BaseViewModelFragment<FollowFansViewModel>() {
private var friendAdapter: FollowFansAdapter? = null
private val mDataList: List<FollowFansBean> = ArrayList()
private var type = "1"
private var page = 1
companion object {
fun getInstance(type: String): FollowFansFragment {
val fragment = FollowFansFragment()
val bundle = Bundle()
bundle.putString("type", type)
fragment.arguments = bundle
return fragment
}
}
override fun startObserve() {
viewModel.getFinally().observe(requireActivity(), {
if (smart != null) {
smart.finishLoadMore()
smart.finishRefresh()
}
})
viewModel.listData.observe(requireActivity(), {
if (page == 1 && it.isEmpty()) {
ll_nodata.visibility = View.VISIBLE
} else {
ll_nodata.visibility = View.GONE
}
if (friendAdapter != null) {
if (page == 1) friendAdapter!!.data.clear()
friendAdapter!!.data.addAll(it)
friendAdapter!!.notifyDataSetChanged()
}
})
viewModel.cancelFollowData.observe(requireActivity(), {
page = 1
viewModel.loadData(type, page)
})
viewModel.followData.observe(requireActivity(), {
page = 1
viewModel.loadData(type, page)
})
}
override fun getLayoutId(): Int = R.layout.fragment_follow_fans
override fun initView() {
}
override fun initData() {
type = requireArguments().getString("type", "1")
friendAdapter = FollowFansAdapter(type,mDataList)
recyclerview.layoutManager = LinearLayoutManager(requireContext())
recyclerview.adapter = friendAdapter
viewModel.loadData(type, page)
}
override fun initEvent() {
smart.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
override fun onRefresh(refreshLayout: RefreshLayout) {
page = 1
viewModel.loadData(type, page)
}
override fun onLoadMore(refreshLayout: RefreshLayout) {
page++
viewModel.loadData(type, page)
}
})
if (friendAdapter != null)
friendAdapter!!.setOnItemChildClickListener { adapter, view, position ->
run {
when (view.id) {
R.id.btn_no_ok -> {
if (friendAdapter != null) {
val ids =
if (friendAdapter!!.data[position].fuid.isEmpty()) friendAdapter!!.data[position].uid else friendAdapter!!.data[position].fuid
viewModel.cancelFollowData(ids)
}
}
R.id.btn_ok -> {
if (friendAdapter != null) {
val ids =
if (friendAdapter!!.data[position].fuid.isEmpty()) friendAdapter!!.data[position].uid else friendAdapter!!.data[position].fuid
viewModel.followData(ids)
}
}
}
}
}
if (friendAdapter != null)
friendAdapter!!.setOnItemClickListener { _, _, pos ->
if (friendAdapter != null) {
ARouter
.getInstance()
.build(AroutUtil.MAIN_MY_HOME_PAGE)
.withString("from_id", friendAdapter!!.data[pos].uid)
.navigation()
}
}
}
}

View File

@@ -0,0 +1,32 @@
package com.yuyin.lib_base.ui.followfans
import androidx.lifecycle.MutableLiveData
import com.yuyin.lib_base.base.BaseViewModel
import com.yuyin.lib_base.model.FollowFansBean
class FollowFansViewModel : BaseViewModel() {
var listData = MutableLiveData<List<FollowFansBean>>()
var followData = MutableLiveData<Any>()
var cancelFollowData = MutableLiveData<Any>()
fun followData(userId: String) {
launchUI {
val result = baseRepository.follow(userId)
followData.value = result.data
}
}
fun cancelFollowData(userId: String) {
launchUI {
val result = baseRepository.cancel_follow(userId)
cancelFollowData.value = result.data
}
}
fun loadData(type: String, page: Int) {
launchUI {
val result = baseRepository.getFollowFansData(type, page.toString())
listData.value = result.data
}
}
}

View File

@@ -0,0 +1,92 @@
package com.yuyin.lib_base.ui.followfans.adapter
import android.view.View
import android.widget.ImageView
import com.yuyin.lib_base.R
import com.yuyin.lib_base.model.FollowFansBean
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
open class FollowFansAdapter(val type: String, data: List<FollowFansBean>) :
BaseQuickAdapter<FollowFansBean, BaseViewHolder>(R.layout.item_follow_fans, data) {
override fun convert(helper: BaseViewHolder, item: FollowFansBean) {
helper.addOnClickListener(R.id.btn_ok)
.addOnClickListener(R.id.btn_no_ok)
val imageView: ImageView = helper.getView(R.id.ci_head)
Glide.with(mContext).load(item.head_pic).error(R.mipmap.ic_launcher_app).into(imageView)
helper.setText(R.id.tv_title, item.nick_name)
.setText(R.id.tv_userid, item.fuid.ifEmpty { item.uid })
if (type == "1") {
if (item.is_follow == 1) {
helper.setBackgroundRes(R.id.btn_no_ok, R.mipmap.item_follow_3)
} else {
helper.setBackgroundRes(R.id.btn_no_ok, R.mipmap.item_follow2)
}
helper.getView<View>(R.id.btn_ok).visibility = View.GONE
helper.getView<View>(R.id.btn_no_ok).visibility = View.VISIBLE
}else{
if (item.is_follow == 1) {
helper.getView<View>(R.id.btn_ok).visibility = View.GONE
helper.getView<View>(R.id.btn_no_ok).visibility = View.VISIBLE
helper.setBackgroundRes(R.id.btn_no_ok, R.mipmap.item_follow_3)
} else {
helper.getView<View>(R.id.btn_ok).visibility = View.VISIBLE
helper.getView<View>(R.id.btn_no_ok).visibility = View.GONE
helper.setBackgroundRes(R.id.btn_ok, R.mipmap.item_follow1)
}
}
// if (type == "1") {
// helper.setBackgroundRes(R.id.btn_ok, R.mipmap.item_follow1)
// } else {
// helper.setBackgroundRes(R.id.btn_ok, R.mipmap.item_follow_3)
// }
// if (item.is_follow == 1) {
// helper.getView<View>(R.id.btn_ok).visibility = View.GONE
// helper.getView<View>(R.id.btn_no_ok).visibility = View.VISIBLE
// } else {
// helper.getView<View>(R.id.btn_ok).visibility = View.VISIBLE
// helper.getView<View>(R.id.btn_no_ok).visibility = View.GONE
// }
if (item.sex == "1") {
helper.setImageResource(R.id.iv_sex, R.mipmap.login_reg_nan1)
} else {
helper.setImageResource(R.id.iv_sex, R.mipmap.login_reg_nv1)
}
if(item.is_online=="1"){
helper.setImageResource(R.id.iv_online, R.mipmap.online1)
}else{
helper.setImageResource(R.id.iv_online, R.mipmap.online2)
}
}
override fun convertPayloads(
helper: BaseViewHolder,
item: FollowFansBean,
payloads: List<Any>
) {
super.convertPayloads(helper, item, payloads)
if (payloads.isEmpty()) {
convert(helper, item)
} else {
val payload = payloads[0] as String
if (payload == "follow") {
item.is_follow = 1
helper.getView<View>(R.id.btn_no_ok).visibility = View.VISIBLE
helper.getView<View>(R.id.btn_ok).visibility = View.GONE
} else if (payload == "cancelFollow") {
item.is_follow = 0
helper.getView<View>(R.id.btn_no_ok).visibility = View.GONE
helper.getView<View>(R.id.btn_ok).visibility = View.VISIBLE
}
}
}
}

View File

@@ -0,0 +1,97 @@
package com.yuyin.lib_base.ui.jubao;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
//九宫格添加
public class FullyGridLayoutManager extends GridLayoutManager {
public FullyGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
int count = getItemCount();
int span = getSpanCount();
for (int i = 0; i < count; i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
if (getOrientation() == HORIZONTAL) {
if (i % span == 0) {
width = width + mMeasuredDimension[0];
}
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
if (i % span == 0) {
height = height + mMeasuredDimension[1];
}
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
final RecyclerView.State mState = new RecyclerView.State();
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
int itemCount = mState.getItemCount();
if (position < itemCount) {
try {
View view = recycler.getViewForPosition(0);
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,35 @@
package com.yuyin.lib_base.ui.jubao
import android.view.View
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.R
import com.yuyin.lib_base.model.ImageItems
import java.util.*
class JBPicAdapter() :
BaseQuickAdapter<ImageItems, BaseViewHolder>(
R.layout.item_fabu_pics, ArrayList()
) {
override fun convert(helper: BaseViewHolder, item: ImageItems) {
helper.addOnClickListener(R.id.iv_del)
val ivDel = helper.getView<ImageView>(R.id.iv_del)
if (item.type == 1) {
ivDel.visibility = View.VISIBLE
Glide.with(mContext)
.load(item.image.path)
.placeholder(R.mipmap.no_tu)
.error(R.mipmap.no_tu)
.into((helper.getView<View>(R.id.iv_img) as ImageView))
} else {
ivDel.visibility = View.GONE
Glide.with(mContext)
.load(item.image.path)
.placeholder(R.mipmap.fabu_shangchuan)
.error(R.mipmap.fabu_shangchuan)
.into((helper.getView<View>(R.id.iv_img) as ImageView))
}
}
}

View File

@@ -0,0 +1,18 @@
package com.yuyin.lib_base.ui.jubao
import android.widget.RadioButton
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.R
import com.yuyin.lib_base.model.JuBaoBean
import java.util.*
class JBTypeAdapter :
BaseQuickAdapter<JuBaoBean, BaseViewHolder>(R.layout.item_jubao_type, ArrayList()) {
open var pos = -1
override fun convert(helper: BaseViewHolder, item: JuBaoBean) {
helper.setText(R.id.rb, item.type_name)
var rb: RadioButton = helper.getView(R.id.rb)
rb.isChecked = pos == helper.position
}
}

View File

@@ -0,0 +1,278 @@
package com.yuyin.lib_base.ui.jubao
import android.Manifest
import android.content.Intent
import android.text.TextUtils
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.baoyz.actionsheet.ActionSheet
import com.lzy.imagepicker.ImagePicker
import com.lzy.imagepicker.bean.ImageItem
import com.lzy.imagepicker.ui.ImageGridActivity
import com.tbruyelle.rxpermissions2.RxPermissions
import com.yuyin.lib_base.R
import com.yuyin.lib_base.arouter.AroutUtil.COMMUNITY_JUBAO
import com.yuyin.lib_base.base.BaseDataBindingActivity
import com.yuyin.lib_base.databinding.ActivityJubaoBinding
import com.yuyin.lib_base.model.ImageItems
import com.yuyin.lib_base.util.PermissionsChecker
import com.yuyin.lib_base.util.showToast
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import top.zibin.luban.Luban
import java.util.*
import kotlin.collections.ArrayList
@Route(path = COMMUNITY_JUBAO)
class JuBaoActivity :
BaseDataBindingActivity<JuBaoViewModel, ActivityJubaoBinding>() {
val REQUEST_CODE_SELECT = 100
private var maxSelectNum = 3 //最多显示的图片数量
var permissionListTmp = arrayOf<String>(Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
//标签
private var imageSize = 0
override fun startObserve() {
viewModel.imgListData.observe(this, {
disMiss()
setFaBu(it)
})
viewModel.publishZone.observe(this, {
"举报成功".showToast()
finish()
})
viewModel.juBaoBeans.observe(this, {
adapter_type.setNewData(it)
})
}
override fun getLayoutId(): Int = R.layout.activity_jubao
override fun initView() {
adapter.setOnItemClickListener { adapter2, view, position ->
var mPermissionsChecker= PermissionsChecker(this@JuBaoActivity)
if (mPermissionsChecker!!.lacksPermissions(*permissionListTmp)) {
mDataBinding.llQuanxian.visibility= View.VISIBLE
}else{
mDataBinding.llQuanxian.visibility= View.GONE
}
if (adapter.data[position].type == 2) {
var numss = 3 - (adapter.data.size - 1)
if (numss > 3) numss = 3
val rxPermissions = RxPermissions(this)
val finalNumss = numss
rxPermissions
.request(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe { granted: Boolean ->
if (granted) { // Always true pre-M
// 跳转到相册
mDataBinding.llQuanxian.visibility= View.GONE
ImagePicker.getInstance().selectLimit = finalNumss
ImagePicker.getInstance().isMultiMode = true
ImagePicker.getInstance().isCrop = false
val intent = Intent(this, ImageGridActivity::class.java)
//显示选中的图片
startActivityForResult(intent, REQUEST_CODE_SELECT)
}else{
mDataBinding.llQuanxian.visibility= View.GONE
}
}
}
}
adapter.setOnItemChildClickListener { adapter, view, position ->
when (view.id) {
R.id.iv_del -> {
tempList.removeAt(position)
imageListAll1.removeAt(position)
imageListAll2 = imageListAll1
if (tempList.size == maxSelectNum - 1) {
imageListAll2.add(ImageItems(2, ImageItem()))
adapter.setNewData(imageListAll2)
} else {
adapter.notifyDataSetChanged()
}
}
}
}
}
private fun uploadFile() {
val parts = java.util.ArrayList<MultipartBody.Part>()
for (i in tempList.indices) {
val file = Luban.with(this).load(imageListAll1[i].image.path).get()[0]
// val file = File(imageListAll1[i].image.path)
val requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file)
val body = MultipartBody.Part.createFormData("file[]", file.name, requestFile)
parts.add(body)
}
if (parts.size != 0) {
showLoading()
viewModel.uploadImages(parts)
} else {
setFaBu(null)
}
}
private fun setFaBu(urls: List<String>?) {
if (adapter_type.pos == -1) {
"请选择举报类型".showToast()
return
}
val map: MutableMap<String, String> = HashMap()
if (!TextUtils.isEmpty(mDataBinding.sorEt.text.toString())) {
map["content"] = mDataBinding.sorEt.text.toString()
}
map["to_uid"] = intent.getStringExtra("uid").toString()
// if (!TextUtils.isEmpty(path) && !TextUtils.isEmpty(sorEt.getText().toString())) {
// map["sound"] = urls[0]
// map["sound_duration"] = TimeUtil.toDateeee(duration)
// } else
if (tempList.size != 0) {
var url_s = ""
urls?.let {
for (i in urls.indices) {
url_s = url_s + (if (TextUtils.isEmpty(url_s)) "" else ",") + urls[i]
}
}
map["image"] = url_s
}
viewModel.juBaoBeans.value?.let {
map["type_id"] = it[adapter_type.pos].id
}
viewModel.publish_zone(map)
}
override fun initData() {
adapter = JBPicAdapter()
val manager = FullyGridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
mDataBinding.sorReleaseRv.layoutManager = manager
mDataBinding.sorReleaseRv.adapter = adapter
imageListAll2.add(ImageItems(2, ImageItem()))
adapter.setNewData(imageListAll2)
adapter_type = JBTypeAdapter()
val manager2222 = FullyGridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
mDataBinding.recyclerView.layoutManager = manager2222
mDataBinding.recyclerView.adapter = adapter_type
adapter_type.setOnItemClickListener { adapter, view, position ->
adapter_type.pos = position
adapter_type.notifyDataSetChanged()
}
viewModel.report_list()
}
override fun initEvent() {
mDataBinding.rightConfirm.setOnClickListener {
uploadFile()
}
}
//弹出选择拍照还是手机相册的弹窗
private fun showPop() {
ActionSheet.createBuilder(this, supportFragmentManager)
.setCancelButtonTitle("取消")
.setOtherButtonTitles("相机", "相册")
.setCancelableOnTouchOutside(true)
.setListener(object : ActionSheet.ActionSheetListener {
override fun onDismiss(actionSheet: ActionSheet, isCancel: Boolean) {}
override fun onOtherButtonClick(actionSheet: ActionSheet, index: Int) {
when (index) {
0 -> {
val rxPermissions = RxPermissions(this@JuBaoActivity)
rxPermissions
.request(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
.subscribe { granted: Boolean ->
if (granted) { // Always true pre-M
//相机
val intent = Intent(
this@JuBaoActivity,
ImageGridActivity::class.java
)
intent.putExtra(
ImageGridActivity.EXTRAS_TAKE_PICKERS,
true
) // 是否是直接打开相机
startActivityForResult(
intent,
REQUEST_CODE_SELECT
)
}
}
}
1 -> {
val rxPermissions = RxPermissions(this@JuBaoActivity)
rxPermissions
.request(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
.subscribe { granted: Boolean ->
if (granted) { // Always true pre-M
// 跳转到相册
ImagePicker.getInstance().selectLimit =
maxSelectNum - imageSize
ImagePicker.getInstance().isMultiMode = true
val intent = Intent(
this@JuBaoActivity,
ImageGridActivity::class.java
)
//显示选中的图片
startActivityForResult(intent, REQUEST_CODE_SELECT)
}
}
}
}
}
}).show()
}
private var tempList: ArrayList<ImageItem> = ArrayList()
private lateinit var adapter: JBPicAdapter
private lateinit var adapter_type: JBTypeAdapter
private var imageListAll1 = ArrayList<ImageItems>()
private var imageListAll2 = ArrayList<ImageItems>()
/*------图片选择回调------*/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (data == null) {
return
}
if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {
//添加图片返回
if (requestCode == REQUEST_CODE_SELECT) {
tempList.addAll(data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS) as ArrayList<ImageItem>)
imageSize = tempList.size
if (tempList == null) {
return
}
adapter.data.clear()
for (i in tempList.indices) {
imageListAll1.add(ImageItems(1, tempList[i]))
}
imageListAll2 = imageListAll1
if (imageListAll2.size < maxSelectNum) {
imageListAll2.add(ImageItems(2, ImageItem()))
}
adapter.setNewData(imageListAll2)
}
}
}
}

View File

@@ -0,0 +1,29 @@
package com.yuyin.lib_base.ui.jubao
import androidx.lifecycle.MutableLiveData
import com.yuyin.lib_base.base.BaseViewModel
import com.yuyin.lib_base.http.BaseRepository
import com.yuyin.lib_base.model.JuBaoBean
class JuBaoViewModel : BaseViewModel() {
var repository = BaseRepository()
var publishZone = MutableLiveData<Any>()
var juBaoBeans = MutableLiveData<List<JuBaoBean>>()
fun publish_zone(map: MutableMap<String, String>) {
launchUI {
var result = repository.user_report(map)
publishZone.value = result.data
}
}
fun report_list() {
launchUI {
var result = repository.report_list()
juBaoBeans.value = result.data
}
}
}

View File

@@ -0,0 +1,118 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.math.BigDecimal;
public class CacheDataManager {
/**
* 获取缓存大小
* @param context
* @return
* @throws
*/
public static String getTotalCacheSize(Context context) throws Exception {
long cacheSize = getFolderSize(context.getCacheDir());
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
cacheSize += getFolderSize(context.getExternalCacheDir());
}
return getFormatSize(cacheSize);
}
/**
* 清除所有缓存
* @param context
*/
public static void clearAllCache(Context context) {
deleteDir(context.getCacheDir());
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
deleteDir(context.getExternalCacheDir());
}
}
/**
* 删除文件目录
* @param dir
* @return
*/
private static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
return dir.delete();
}
/**
* MethodsTitle: 获取文件
* 步骤:
* Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/目录,一般放一些长时间保存的数据
* Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
* @param file
* @return
* @throws
*/
public static long getFolderSize(File file) throws Exception {
long size = 0;
try {
File[] fileList = file.listFiles();
for (int i = 0; i < fileList.length; i++) {
// 如果下面还有文件
if (fileList[i].isDirectory()) {
size = size + getFolderSize(fileList[i]);
} else {
size = size + fileList[i].length();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return size;
}
/**
* 格式化单位并计算缓存的大小
* @param size
* @return
*/
public static String getFormatSize(double size) {
double kiloByte = size / 1024;
if (kiloByte < 1) {
// return size + "Byte";
return "0K";
}
double megaByte = kiloByte / 1024;
if (megaByte < 1) {
BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "KB";
}
double gigaByte = megaByte / 1024;
if (gigaByte < 1) {
BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "MB";
}
double teraBytes = gigaByte / 1024;
if (teraBytes < 1) {
BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "GB";
}
BigDecimal result4 = new BigDecimal(teraBytes);
return result4.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "TB";
}
}

View File

@@ -0,0 +1,32 @@
package com.yuyin.lib_base.util
/**
* Created by cxf on 2018/9/29.
*/
object ClickUtil {
private var sLastClickTime: Long = 0
private var sLastClickTime2: Long = 0
@JvmStatic
fun canClick(): Boolean {
val curTime = System.currentTimeMillis()
if (curTime - sLastClickTime < 300) {
"请勿重复点击".showToast()
return false
}
sLastClickTime = curTime
return true
}
@JvmStatic
fun canClickRoom(): Boolean {
val curTime = System.currentTimeMillis()
if ((curTime - sLastClickTime2) < 5000) {
// "请勿重复点击".showToast()
return false
}
sLastClickTime2 = curTime
return true
}
}

View File

@@ -0,0 +1,4 @@
package com.yuyin.lib_base.util
class ConfigurationUtil {
}

View File

@@ -0,0 +1,62 @@
package com.yuyin.lib_base.util
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.text.DecimalFormat
object CountDownUtil {
/**
* 倒计时的实现
*/
fun countDown(lifecycleScope: LifecycleCoroutineScope,
time: Int = 5,
start: (scop: CoroutineScope) -> Unit,
end: () -> Unit,
next: (time: Int) -> Unit
) {
lifecycleScope.launch {
// 在这个范围内启动的协程会在Lifecycle被销毁的时候自动取消
flow {
(time downTo 0).forEach {
delay(1000)
emit(it)
}
}.onStart {
// 倒计时开始 在这里可以让Button 禁止点击状态
start(this@launch)
}.onCompletion {
// 倒计时结束 在这里可以让Button 恢复点击状态
end()
}.catch {
//错误
// YYLogUtils.e(it.message ?: "Unkown Error")
}.collect {
// 在这里 更新值来显示到UI
next(it)
}
}
}
fun formatCountDownTime(milliseconds: Long): String {
val sb = StringBuilder()
val mss = milliseconds * 1000 / 1000
val days = mss / (60 * 60 * 24)
val hours = mss % (60 * 60 * 24) / (60 * 60)
val minutes = mss % (60 * 60) / 60
val seconds = mss % 60
val format = DecimalFormat("00")
if (days > 0 || hours > 0) {
sb.append(format.format(hours)).append(":").append(format.format(minutes)).append(":")
.append(format.format(seconds))
} else {
sb.append(format.format(minutes)).append(":").append(format.format(seconds))
}
return sb.toString()
}
}

View File

@@ -0,0 +1,69 @@
package com.yuyin.lib_base.util
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
object CountDownUtils {
/**
* 倒计时的实现
*/
@ExperimentalCoroutinesApi
fun countDown(
lifecycleScope: LifecycleCoroutineScope,
time: Int = 5,
start: (scop: CoroutineScope) -> Unit,
end: () -> Unit,
next: (time: Int) -> Unit
) {
lifecycleScope.launch {
// 在这个范围内启动的协程会在Lifecycle被销毁的时候自动取消
flow {
(time downTo 0).forEach {
delay(1000)
emit(it)
}
}.onStart {
// 倒计时开始 在这里可以让Button 禁止点击状态
start(this@launch)
}.onCompletion {
// 倒计时结束 在这里可以让Button 恢复点击状态
end()
}.catch {
//错误
// YYLogUtils.e(it.message ?: "Unkown Error")
}.collect {
// 在这里 更新值来显示到UI
next(it)
}
}
}
fun countDownCoroutines(
total: Int,
scope: CoroutineScope,
onTick: (Int) -> Unit,
onStart: (() -> Unit)? = null,
onFinish: (() -> Unit)? = null,
): Job {
return flow {
for (i in total downTo 0) {
emit(i)
delay(1000)
}
}.flowOn(Dispatchers.Main)
.onStart { onStart?.invoke() }
.onCompletion { onFinish?.invoke() }
.onEach { onTick.invoke(it) }
.launchIn(scope)
}
}

View File

@@ -0,0 +1,60 @@
package com.yuyin.lib_base.util
import android.content.Context
import android.telephony.TelephonyManager
import android.text.TextUtils
import android.util.Log
import java.util.*
object DeviceUtils {
fun getDeviceId(context: Context): String {
val deviceId = StringBuilder()
// 渠道标志
deviceId.append("a")
try {
//IMEIimei
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val imei = tm.deviceId
if (!TextUtils.isEmpty(imei)) {
deviceId.append("imei")
deviceId.append(imei)
Log.e("getDeviceId : ", deviceId.toString())
return deviceId.toString()
}
//序列号sn
val sn = tm.simSerialNumber
if (!TextUtils.isEmpty(sn)) {
deviceId.append("sn")
deviceId.append(sn)
Log.e("getDeviceId : ", deviceId.toString())
return deviceId.toString()
}
//如果上面都没有, 则生成一个id随机码
val uuid = getUUID(context)
if (!TextUtils.isEmpty(uuid)) {
deviceId.append("id")
deviceId.append(uuid)
Log.e("getDeviceId : ", deviceId.toString())
return deviceId.toString()
}
} catch (e: Exception) {
e.printStackTrace()
deviceId.append("id").append(getUUID(context))
}
Log.e("getDeviceId : ", deviceId.toString())
return deviceId.toString()
}
/**k
* 得到全局唯一UUID
*/
fun getUUID(context: Context?): String {
var uuid = ""
uuid = SharedPreferencesUtils.getParam(context, "uuid", "").toString() + ""
if (TextUtils.isEmpty(uuid)) {
uuid = UUID.randomUUID().toString()
SharedPreferencesUtils.setParam(context, "uuid", uuid)
}
return uuid
}
}

View File

@@ -0,0 +1,119 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class DownloadUtils {
private static final String TAG = "DownloadUtils";
private static final String CACHE_FOLDER = "assets";
private final OkHttpClient okHttpClient =
new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS).build();
private static DownloadUtils instance;
public static DownloadUtils getInstance() {
if (instance == null) {
instance = new DownloadUtils();
}
return instance;
}
private DownloadUtils() {
}
@Nullable
public void download(Context context, String url, FileDownloadSuccessCallback callback, FileDownloadFailureCallback error) {
if (url == null || url.isEmpty()) {
return;
}
File folder = new File(context.getExternalCacheDir(), CACHE_FOLDER);
if (!folder.exists()) {
folder.mkdir();
}
File file = new File(folder, url.substring(url.lastIndexOf("/") + 1));
if (file.exists()) {
callback.onSuccess(file);
return;
}
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
error.onFailed(e);
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
ResponseBody body = response.body();
if (body == null) {
error.onFailed((Exception) new Throwable("body is empty"));
return;
}
long total = body.contentLength();
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = body.byteStream();
fos = new FileOutputStream(file);
long sum = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
int progress = (int) (sum * 1.0f / total * 100);
Log.d(TAG, file.getName() + ", progress: " + progress);
}
fos.flush();
Log.d(TAG, file.getName() + " onComplete");
callback.onSuccess(file);
} catch (Exception e) {
error.onFailed(e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
}
}
}
});
}
public interface FileDownloadSuccessCallback {
void onSuccess(File file);
}
public interface FileDownloadFailureCallback {
void onFailed(Exception exception);
}
}

View File

@@ -0,0 +1,38 @@
package com.yuyin.lib_base.util
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
/**
* @author hyx
* @description
* @date 2018/6/18.
*/
object FragmentUtils {
/**
* The `fragment` is added to the container view with id `frameId`. The operation is
* performed by the `fragmentManager`.
*
*/
fun addOrShowFragmentToActivity(
fragmentManager: FragmentManager,
fragment: Fragment, frameId: Int
) {
val transaction: FragmentTransaction = fragmentManager.beginTransaction()
if (fragmentManager.getFragments() != null) {
for (f in fragmentManager.getFragments()) {
transaction.hide(f)
}
if (fragmentManager.getFragments().contains(fragment)) {
transaction.show(fragment)
transaction.commitAllowingStateLoss()
return
}
}
transaction.add(frameId, fragment)
// transaction.commit();
transaction.commitAllowingStateLoss()
fragmentManager.executePendingTransactions()
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.content.res.AssetManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* <读取Json文件的工具类>
*/
public class GetJsonDataUtil {
public String getJson(Context context, String fileName) {
StringBuilder stringBuilder = new StringBuilder();
try {
AssetManager assetManager = context.getAssets();
BufferedReader bf = new BufferedReader(new InputStreamReader(
assetManager.open(fileName)));
String line;
while ((line = bf.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.lib_base.util
import android.content.Context
import android.widget.ImageView
import com.yuyin.lib_base.R
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
object GlideUtil {
fun loadImglogo(context: Context, url: String, view: ImageView) {
val options = RequestOptions()
.placeholder(R.mipmap.ic_launcher_app)
.error(R.mipmap.ic_launcher_app)
try {
Glide.with(context).load(url)
.apply(options)
.into(view)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun loadImglogo2(context: Context, url: String, view: ImageView) {
val options = RequestOptions()
.placeholder(R.color.translant)
.error(R.color.translant)
try {
Glide.with(context).load(url)
.apply(options)
.into(view)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -0,0 +1,45 @@
package com.yuyin.lib_base.util;
import android.text.Editable;
import android.widget.EditText;
import java.util.regex.Pattern;
public class HSTextUtils {
/**
* 将输入的聊天内容字符串给过滤掉空字符
*/
public static String filterEmptyInputChatContent(String content) {
if (content == null || content.isEmpty()) return content;
return replaceEmptyLineEnd(content);
}
public static String replaceEmptyLineEnd(String param) {
if (param == null) return null;
String str = param;
str = str.replaceAll("\\n$", "");
str = str.replaceAll("\\r$", "");
return str;
}
/**
* 判断是否为整数
*
* @param str 传入的字符串
* @return 是整数返回true, 否则返回false
*/
public static boolean isInteger(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}
public static String getText(EditText editText) {
Editable text = editText.getText();
if (text != null) {
return text.toString();
}
return null;
}
}

View File

@@ -0,0 +1,181 @@
package com.yuyin.lib_base.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 身份证效验
*/
public class IDCard {
public static String getRandomString(int length) { //length表示生成字符串的长度
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 功能:身份证的有效验证
*
* @param IDStr 身份证号
* @return true 有效false 无效
*/
public static boolean IDCardValidate(String IDStr) {
String[] ValCodeArr = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
String Ai = "";
// ================ 号码的长度18位 ================
if (IDStr.length() != 18) {
return false;
}
// ================ 数字 除最后以为都为数字 ================
if (IDStr.length() == 18) {
Ai = IDStr.substring(0, 17);
}
if (isNumeric(Ai) == false) {
//errorInfo = "身份证15位号码都应为数字 ; 18位号码除最后一位外都应为数字。";
return false;
}
// ================ 出生年月是否有效 ================
String strYear = Ai.substring(6, 10);// 年份
String strMonth = Ai.substring(10, 12);// 月份
String strDay = Ai.substring(12, 14);// 日
if (isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
// errorInfo = "身份证生日无效。";
return false;
}
GregorianCalendar gc = new GregorianCalendar();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
try {
if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
//errorInfo = "身份证生日不在有效范围。";
return false;
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (java.text.ParseException e) {
e.printStackTrace();
}
if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
//errorInfo = "身份证月份无效";
return false;
}
if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
//errorInfo = "身份证日期无效";
return false;
}
// ================ 地区码时候有效 ================
Hashtable h = GetAreaCode();
if (h.get(Ai.substring(0, 2)) == null) {
//errorInfo = "身份证地区编码错误。";
return false;
}
// ================ 判断最后一位的值 ================
int TotalmulAiWi = 0;
for (int i = 0; i < 17; i++) {
TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
}
int modValue = TotalmulAiWi % 11;
String strVerifyCode = ValCodeArr[modValue];
Ai = Ai + strVerifyCode;
if (IDStr.length() == 18) {
if (Ai.equals(IDStr) == false) {
//errorInfo = "身份证无效,不是合法的身份证号码";
return false;
}
} else {
return true;
}
return true;
}
/**
* 功能:设置地区编码
*
* @return Hashtable 对象
*/
@SuppressWarnings("unchecked")
private static Hashtable GetAreaCode() {
Hashtable hashtable = new Hashtable();
hashtable.put("11", "北京");
hashtable.put("12", "天津");
hashtable.put("13", "河北");
hashtable.put("14", "山西");
hashtable.put("15", "内蒙古");
hashtable.put("21", "辽宁");
hashtable.put("22", "吉林");
hashtable.put("23", "黑龙江");
hashtable.put("31", "上海");
hashtable.put("32", "江苏");
hashtable.put("33", "浙江");
hashtable.put("34", "安徽");
hashtable.put("35", "福建");
hashtable.put("36", "江西");
hashtable.put("37", "山东");
hashtable.put("41", "河南");
hashtable.put("42", "湖北");
hashtable.put("43", "湖南");
hashtable.put("44", "广东");
hashtable.put("45", "广西");
hashtable.put("46", "海南");
hashtable.put("50", "重庆");
hashtable.put("51", "四川");
hashtable.put("52", "贵州");
hashtable.put("53", "云南");
hashtable.put("54", "西藏");
hashtable.put("61", "陕西");
hashtable.put("62", "甘肃");
hashtable.put("63", "青海");
hashtable.put("64", "宁夏");
hashtable.put("65", "新疆");
// hashtable.put("71", "台湾");
// hashtable.put("81", "香港");
// hashtable.put("82", "澳门");
// hashtable.put("91", "国外");
return hashtable;
}
/**
* 功能:判断字符串是否为数字
*
* @param str
* @return
*/
private static boolean isNumeric(String str) {
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if (isNum.matches()) {
return true;
} else {
return false;
}
}
/**
* 功能:判断字符串是否为日期格式
*
* @return
*/
public static boolean isDate(String strDate) {
Pattern pattern = Pattern
.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
Matcher m = pattern.matcher(strDate);
if (m.matches()) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,138 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import com.yuyin.lib_base.Const;
public class ImageLoaderUtils {
/**
* 初始化ImageLoaderConfiguration 这个可以只做简单的初始化,此方法建议在
* Application中进行初始化
*
* @param context
*/
public static void initConfiguration(Context context) {
ImageLoaderConfiguration.Builder configuration = new ImageLoaderConfiguration.Builder(context);
//--------------------------------------------------------------------
// 本段代码如果是测试使用时可以不添加不影响ImageLoader的正常使用
configuration.memoryCacheExtraOptions(100, 100);
// // default = device screen dimensions
// // 缓存到磁盘中的图片宽高
// .diskCacheExtraOptions(480, 800, null)
// // .taskExecutor(null)
// // .taskExecutorForCachedImages()
// .threadPoolSize(3)
// // default 线程优先级
// .threadPriority(Thread.NORM_PRIORITY - 2)
// // default
// .tasksProcessingOrder(QueueProcessingType.FIFO)
// // // default设置在内存中缓存图像的多种尺寸
// // 加载同一URL图片时,imageView从小变大时,从内存缓存中加载
// .denyCacheImageMultipleSizesInMemory()
// // 超过设定的缓存大小时,内存缓存的清除机制
// .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
// // 内存的一个大小
// .memoryCacheSize(2 * 1024 * 1024).memoryCacheSizePercentage(13)
// // default 将图片信息缓存到该路径下
// // default 磁盘缓存的大小
// .diskCacheSize(50 * 1024 * 1024)
// // 磁盘缓存文件的个数
// .diskCacheFileCount(100)
// // 磁盘缓存的文件名的命名方式//一般使用默认值 (获取文件名称的hashcode然后转换成字符串)或MD5 new
// // Md5FileNameGenerator()源文件的名称同过md5加密后保存
// .diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
// // 设置默认的图片加载
// // 使用默认的图片解析器
// .imageDecoder(new BaseImageDecoder(true)) // default
// .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
// .writeDebugLogs();
//---------------------------------------------------------------------
ImageLoader.getInstance().init(configuration.build());
}
/**
* 初始化DisplayImageOptions
*
* @param context
* @return
*/
public static DisplayImageOptions initOptions() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
// 设置下载的图片是否缓存在内存中
.cacheInMemory(true)
// 设置下载的图片是否缓存在SD卡中
.cacheOnDisc(true)
//--------------------------------------------------------------------
//.memoryCacheExtraOptions(480, 800)
//如果您只想简单使用ImageLoader这块也可以不用配置
// 是否考虑JPEG图像EXIF参数旋转翻转
.considerExifParams(true)
// 设置图片以如何的编码方式显示
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
// 设置图片的解码类型//
.bitmapConfig(Bitmap.Config.RGB_565)
// 设置图片的解码配置
// .decodingOptions(options)
// .delayBeforeLoading(int delayInMillis)//int
// delayInMillis为你设置的下载前的延迟时间
// 设置图片加入缓存前对bitmap进行设置
// .preProcessor(BitmapProcessor preProcessor)
// 设置图片在下载前是否重置,复位
.resetViewBeforeLoading(true)
// 是否设置为圆角,弧度为多少
.displayer(new RoundedBitmapDisplayer(20))
// 是否图片加载好后渐入的动画时间
.displayer(new FadeInBitmapDisplayer(100))
// 构建完成
//-------------------------------------------------------------------
.build();
return options;
}
public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap oldbmp = drawableToBitmap(drawable);// drawable转换成bitmap
Matrix matrix = new Matrix(); // 创建操作图片用的Matrix对象
float scaleWidth = ((float) w / width); // 计算缩放比例
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidth, scaleHeight); // 设置缩放比例
Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true); // 建立新的bitmap其内容是对原bitmap的缩放后的图
return new BitmapDrawable(newbmp); // 把bitmap转换成drawable并返回
}
public static Bitmap drawableToBitmap(Drawable drawable)// drawable 转换成bitmap
{
int width = drawable.getIntrinsicWidth(); // 取drawable的长宽
int height = drawable.getIntrinsicHeight();
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; // 取drawable的颜色格式
Bitmap bitmap = Bitmap.createBitmap(width, height, config); // 建立对应bitmap
Canvas canvas = new Canvas(bitmap); // 建立对应bitmap的画布
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas); // 把drawable内容画到画布中
return bitmap;
}
public static String isHttp(String url) {
if (!url.startsWith("http") || !url.startsWith("https")) {
url = Const.URL3 + url;
}
return url;
}
}

View File

@@ -0,0 +1,135 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import com.yuyin.lib_base.R;
public class LoginConfig {
//
// /**
// * 样式G配置示例: SDK固有控件都有默认值只需设置自己想要修改的配置
// *
// * @param context 必须传getApplicationContext(),防止可能存在的内存泄漏
// * @return
// */
// public ShanYanUIConfig getGConfig(final Context context) {
// /************************************SDK固有控件********************************/
// //授权页背景
// Drawable mAuthBackgroundImg = context.getResources().getDrawable(R.color.mainColor);
// //登录按钮背景
// Drawable mLoginBt = context.getResources().getDrawable(R.drawable.shape_butt_main_24);
//
// /************************************授权页添加自定义控件*************************/
//
//
// /**************************授权页配置(示例配置自上而下,可调整顺序)****************/
// ShanYanUIConfig uiConfig = new ShanYanUIConfig.Builder()
// //设置授权页背景
// .setAuthBGImgPath(mAuthBackgroundImg)
// .setTextSizeIsdp(false)
// .setFitsSystemWindows(false)
// //设置隐藏状态栏
// .setStatusBarHidden(true)
// //设置隐藏导航栏
// .setAuthNavHidden(true)
// //设置logo隐藏
// .setLogoHidden(false)
// .setLogoWidth(105)
// .setLogoHeight(105)
// .setLogoOffsetY(150)
// //设置号码栏距离顶部(状态栏)偏移量
// .setNumFieldOffsetBottomY(400)
// //设置号码栏文字颜色
// .setNumberColor(Color.parseColor("#ffffff"))
// //设置号码栏字体大小
// .setNavTextSize(100)
// .setNumberSize(34)
// .setNumberBold(true)
// .setLogoImgPath(context.getResources().getDrawable(R.mipmap.ic_launcher_app))
// //设置号码栏字体加粗
// .setNumberBold(true)
// //设置登录按钮距离顶部(状态栏)偏移量
// .setLogBtnOffsetBottomY(320)
// //设置登录按钮宽度
// .setLogBtnWidth(getScreenWidth(context, true) - 60)
// .setLogBtnHeight(53)
// //设置登录按钮背景图片
// .setLogBtnImgPath(mLoginBt)
// .setLogBtnTextBold(true)
// .setLogBtnTextColor(Color.parseColor("#FFFFFF"))
// .setLogBtnTextSize(16)
// //设置slogan距离顶部状态栏偏移量
//// .setSloganOffsetBottomY(260)
//// //设置slogan文字大小
//// .setSloganTextSize(48)
//// .setSloganTextBold(true)
// //设置slogan文字颜色
// .setSloganTextColor(Color.TRANSPARENT)
// //设置隐藏协议复选框
// .setCheckBoxHidden(false)
// //设置协议文字左对齐
// .setPrivacyOffsetGravityLeft(true)
// //设置运营商协议展示到最后一个
// .setOperatorPrivacyAtLast(true)
// //设置协议栏距离屏幕底部偏移量
//// .setPrivacyOffsetBottomY()
// //设置协议文字颜色参数1协议名称之外的文字颜色参数2协议名称文字颜色
// .setAppPrivacyColor(Color.parseColor("#8B8E98"), Color.parseColor("#25D4D0"))
// //设置协议隐藏书名号
// .setPrivacySmhHidden(true)
// .setPrivacyTextBold(true)
// //设置自定义协议参数1协议名称参数2协议链接
//// .setAppPrivacyOne("《隐私政策》", Const.PAGE_USER_XIEYI)
//// .setAppPrivacyTwo("《用户协议》", Const.PAGE_USER_XIEYI2) //设置开发者隐私条款2名称和URL(名称url)
// //设置协议外部文字描述 https://api.253.com/api_doc/yin-si-zheng-ce/wei-hu-wang-luo-an-quan-sheng-ming.html
// .setPrivacyText("我阅读并同意", "和", "和", "", "并授权获取本机号码")
// /**
// * 添加自定义控件
// * @param view 自定义view
// * @param isFinish 点击是否自动销毁true点击自定义控件时自动销毁授权页false点击自定义控件时不销毁授权页
// * @param type 是否添加到导航栏内部true添加到导航栏false添加到导航栏以下空白处
// * @param ShanYanCustomInterface 自定义控件点击事件监听填null即屏蔽父布局点击事件
// */
//// .addCustomView(thirdRelativeLayout, false, false, null)
//// .addCustomView(cusBRelativeLayout, false, false, null)
//// .addCustomView(privacyRelativeLayout, false, false, null)
//// .addCustomView(registerRelativeLayout, false, false, null)
// .build();
//
//
// return uiConfig;
//
// }
//
//
// public int getScreenWidth(Context context, boolean isDp) {
// int screenWidth = 0;
// int winWidth;
// WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
// Display defaultDisplay = wm.getDefaultDisplay();
// Point point = new Point();
// defaultDisplay.getSize(point);
// if (point.x > point.y) {
// winWidth = point.y;
// } else {
// winWidth = point.x;
// }
// DisplayMetrics dm = new DisplayMetrics();
// wm.getDefaultDisplay().getMetrics(dm);
// if (!isDp) {
// return winWidth;
// }
// float density = dm.density; // 屏幕密度0.75 / 1.0 / 1.5
// screenWidth = (int) (winWidth / density);// 屏幕高度(dp)
// return screenWidth;
// }
}

View File

@@ -0,0 +1,124 @@
package com.yuyin.lib_base.util;
import android.media.AudioManager;
import android.media.MediaPlayer;
import java.io.IOException;
/**
* Created by Administrator on 2017/11/28.
* 播放录音类
*/
public class MediaManager {
private static MediaPlayer mMediaPlayer;
private static boolean isPause;
//播放录音
public static void playSound(String filePath, MediaPlayer.OnCompletionListener onCompletionListener) {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
//播放错误 防止崩溃
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mMediaPlayer.reset();
return false;
}
});
} else {
mMediaPlayer.reset();
}
try {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnCompletionListener(onCompletionListener);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
//播放录音
public static void playSoundAsync(String filePath, MediaPlayer.OnCompletionListener onCompletionListener, MediaPlayer.OnPreparedListener onPreparedListener) {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
//播放错误 防止崩溃
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mMediaPlayer.reset();
return false;
}
});
} else {
mMediaPlayer.reset();
}
try {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnCompletionListener(onCompletionListener);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(onPreparedListener);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 如果 播放时间过长,如30秒
* 用户突然来电话了,则需要暂停
*/
public static boolean isPlaying() {
if (mMediaPlayer != null) {
return mMediaPlayer.isPlaying();
}
return false;
}
/**
* 如果 播放时间过长,如30秒
* 用户突然来电话了,则需要暂停
*/
public static void pause() {
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
isPause = true;
}
}
/**
* 播放
*/
public static void resume() {
if (mMediaPlayer != null && isPause) {
mMediaPlayer.start();
isPause = false;
}
}
/**
* activity 被销毁 释放
*/
public static void release() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
//获取当前播放进度
public static int getMusicCurrentPosition() {
int rtn = 0;
if (mMediaPlayer != null) {
rtn = mMediaPlayer.getCurrentPosition();
}
return rtn;
}
}

View File

@@ -0,0 +1,26 @@
package com.yuyin.lib_base.util
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
class PermissionsChecker (context: Context) {
private var mContext: Context = context.applicationContext
// 判断权限集合
fun lacksPermissions(vararg permissions: String): Boolean {
for (permission in permissions) {
if (lacksPermission(permission)) {
return true
}
}
return false
}
// 判断是否缺少权限
private fun lacksPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_DENIED
}
}

View File

@@ -0,0 +1,213 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.security.MessageDigest;
import java.util.Locale;
public class SBUtils {
public static String initData(Context context) {
String str1 = "";
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String mtype = Build.MODEL; // 手机型号
String mtyb = Build.BRAND;//手机品牌
String phoneInfo = "Product: " + Build.PRODUCT;
phoneInfo += ", CPU_ABI: " + Build.CPU_ABI;
phoneInfo += ", TAGS: " + Build.TAGS;
phoneInfo += ", VERSION_CODES.BASE: " + Build.VERSION_CODES.BASE;
phoneInfo += ", SDK: " + Build.VERSION.SDK;
phoneInfo += ", VERSION.RELEASE: " + Build.VERSION.RELEASE;
phoneInfo += ", DEVICE: " + Build.DEVICE;
phoneInfo += ", DISPLAY: " + Build.DISPLAY;
phoneInfo += ", BRAND: " + Build.BRAND;
phoneInfo += ", BOARD: " + Build.BOARD;
phoneInfo += ", FINGERPRINT: " + Build.FINGERPRINT;
phoneInfo += ", ID: " + Build.ID;
phoneInfo += ", MANUFACTURER: " + Build.MANUFACTURER;
phoneInfo += ", mtype: " + mtype;
phoneInfo += ", mtyb: " + mtyb;
phoneInfo += ", phoneInfo: " + phoneInfo;
Log.d("AAAAAAAAAAAAAA", phoneInfo);
str1 = phoneInfo;
} catch (Exception e) {
e.printStackTrace();
}
return str1;
}
public static String getDeviceId(Context context) {
String str1 = "";
try {
StringBuilder sbDeviceId = new StringBuilder();
String imei = getIMEI(context);
String androidId = getAndroidId(context);
String serial = getSerial();
String uuid = getDeviceUUID();
//附加imei
if (imei != null && imei.length() > 0) {
sbDeviceId.append(imei);
sbDeviceId.append("附加imei|");
}
//附加androidId
if (androidId != null && androidId.length() > 0) {
sbDeviceId.append(androidId);
sbDeviceId.append("附加androidId|");
}
//附加serial
if (serial != null && serial.length() > 0) {
sbDeviceId.append(serial);
sbDeviceId.append("附加serial|");
}
//附加uuid
if (uuid != null && uuid.length() > 0) {
sbDeviceId.append(uuid);
sbDeviceId.append("附加uuid");
}
// if (sbDeviceId.length() > 0) {
// try {
// byte[] hash = getHashByString(sbDeviceId.toString());
// String sha1 = bytesToHex(hash);
// if (sha1 != null && sha1.length() > 0) {
// //返回最终的DeviceId
// return sha1;
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// return null;
str1 = sbDeviceId.toString();
} catch (Exception e) {
e.printStackTrace();
}
return str1;
}
/**
* 转16进制字符串
*
* @param data 数据
* @return 16进制字符串
*/
private static String bytesToHex(byte[] data) {
StringBuilder sb = new StringBuilder();
String string;
for (int i = 0; i < data.length; i++) {
string = (Integer.toHexString(data[i] & 0xFF));
if (string.length() == 1) {
sb.append("0");
}
sb.append(string);
}
return sb.toString().toUpperCase(Locale.CHINA);
}
/**
* 取 SHA1
*
* @param data 数据
* @return 对应的Hash值
*/
private static byte[] getHashByString(String data) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.reset();
messageDigest.update(data.getBytes("UTF-8"));
return messageDigest.digest();
} catch (Exception e) {
return "".getBytes();
}
}
/**
* 获取硬件的UUID
*
* @return
*/
private static String getDeviceUUID() {
String deviceId = "9527" + Build.ID + "|" +
Build.DEVICE + "|" +
Build.BOARD + "|" +
Build.BRAND + "|" +
Build.HARDWARE + "|" +
Build.PRODUCT + "|" +
Build.MODEL + "|" +
Build.SERIAL;
return deviceId;
// return new UUID(deviceId.hashCode(), Build.SERIAL.hashCode()).toString().replace("-", "");
}
private static String getSerial() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Build.getSerial();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取AndroidId
*
* @param context 上下文
* @return AndroidId
*/
public static String getAndroidId(Context context) {
try {
String androidId = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
return androidId;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 获取IMEI
*
* @param context 上下文
* @return IMEI
*/
private static String getIMEI(Context context) {
try {
TelephonyManager telephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}

View File

@@ -0,0 +1,100 @@
package com.yuyin.lib_base.util;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Color;
import android.util.DisplayMetrics;
import java.lang.reflect.Field;
/**
* Created by cxf on 2017/10/30.
* 获取屏幕尺寸
*/
public class ScreenDimenUtil {
private Resources mResources;
private int mStatusBarHeight;//状态栏高度
private int mContentHeight;
private int mScreenWdith;
private int mScreenHeight;
private static ScreenDimenUtil sInstance;
private ScreenDimenUtil(Activity context) {
mResources = context.getResources();
DisplayMetrics dm = mResources.getDisplayMetrics();
mScreenWdith = dm.widthPixels;
mScreenHeight = dm.heightPixels;
//网上找的办法使用反射在DecoderView未绘制出来之前计算状态栏的高度
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
mStatusBarHeight = mResources.getDimensionPixelSize(x);
mContentHeight = mScreenHeight - mStatusBarHeight;
} catch (Exception e) {
e.printStackTrace();
}
}
public static ScreenDimenUtil getInstance(Activity context) {
if (sInstance == null) {
synchronized (ScreenDimenUtil.class) {
if (sInstance == null) {
sInstance = new ScreenDimenUtil(context);
}
}
}
return sInstance;
}
/**
* 获取屏幕的宽度
*
* @return
*/
public int getScreenWdith() {
return mScreenWdith;
}
/**
* 获取屏幕的高度
*
* @return
*/
public int getScreenHeight() {
return mScreenHeight;
}
/**
* 获取ContentView的高度
*
* @return
*/
public int getContentHeight() {
return mContentHeight;
}
/**
* 获取状态栏的高度
*
* @return
*/
public int getStatusBarHeight() {
return mStatusBarHeight;
}
/**
* 根据百分比改变颜色透明度
*/
public static int changeAlpha(int color, float fraction, int red, int green, int blue) {
int alpha = (int) (Color.alpha(color) * fraction);
return Color.argb(alpha, red, green, blue);
}
}

View File

@@ -0,0 +1,73 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.content.SharedPreferences;
/**
* SharedPreferences的一个工具类调用setParam就能保存String, Integer, Boolean, Float, Long类型的参数
* 同样调用getParam就能获取到保存在手机里面的数据
*
* @author liqiang
*/
public class SharedPreferencesUtils {
/**
* 保存在手机里面的文件名
*/
private static final String FILE_NAME = "share_date";
// *
// * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
// * @param context
// * @param key
// * @param object
//
public static boolean setParam(Context context, String key, Object object) {
String type = object.getClass().getSimpleName();
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if ("String".equals(type)) {
editor.putString(key, (String) object);
} else if ("Integer".equals(type)) {
editor.putInt(key, (Integer) object);
} else if ("Boolean".equals(type)) {
editor.putBoolean(key, (Boolean) object);
} else if ("Float".equals(type)) {
editor.putFloat(key, (Float) object);
} else if ("Long".equals(type)) {
editor.putLong(key, (Long) object);
}
editor.apply();
return false;
}
// *
// * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
// * @param context
// * @param key
// * @param defaultObject
// * @return
public static Object getParam(Context context, String key, Object defaultObject) {
String type = defaultObject.getClass().getSimpleName();
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
if ("String".equals(type)) {
return sp.getString(key, (String) defaultObject);
} else if ("Integer".equals(type)) {
return sp.getInt(key, (Integer) defaultObject);
} else if ("Boolean".equals(type)) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if ("Float".equals(type)) {
return sp.getFloat(key, (Float) defaultObject);
} else if ("Long".equals(type)) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
}

View File

@@ -0,0 +1,122 @@
package com.yuyin.lib_base.util;
import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.yuyin.lib_base.R;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class StatusBarUtil {
/**
* 设置状态栏黑色字体图标,
* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
*
* @param activity
* @return 1:MIUUI 2:Flyme 3:android6.0
*/
public static int StatusBarLightMode(Activity activity, Boolean dark) {
setStatusBarColor(activity, R.color.translant);
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (MIUISetStatusBarLightMode(activity.getWindow(), dark)) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 1;
} else if (FlymeSetStatusBarLightMode(activity.getWindow(), dark)) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (dark)
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
else
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
result = 3;
}
}
return result;
}
/**
* 修改状态栏颜色支持4.4以上版本
* @param activity
* @param colorId
*/
public static void setStatusBarColor(Activity activity, int colorId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(activity.getResources().getColor(colorId));
}
}
/**
* 设置状态栏字体图标为深色需要MIUIV6以上
*
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
}
result = true;
} catch (Exception e) {
}
}
return result;
}
/**
* 设置状态栏图标为深色和魅族特定的文字风格
* 可以用来判断是否为Flyme用户
*
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
try {
WindowManager.LayoutParams lp = window.getAttributes();
Field darkFlag = WindowManager.LayoutParams.class
.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class
.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
return result;
}
}

View File

@@ -0,0 +1,593 @@
package com.yuyin.lib_base.util;
import android.text.TextUtils;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class TimeUtil {
/**
* yy_MM_DD HH:MM:SS 转
*
* @param
* @return
*/
public static String chatTimee2(String timeyys) {
try {
long timestamp = Long.parseLong(timeyys)*1000;//转时间戳
long timeMillis = System.currentTimeMillis();
long timeKK = timeMillis - timestamp;
if (timeKK > DayS) {
return toDateYmd3(timestamp);
} else if (timeKK > HourS) {
int time = (int) (timeKK / HourS);
return time + "小时前";
} else if (timeKK > MS) {
int time = (int) (timeKK / MS);
return time + "分钟前";
} else {
return "刚刚";
}
} catch (NumberFormatException e) {
e.printStackTrace();
return "未知";
}
}
/**
* 获取当前时间
*
* @return
*/
public static String getTime() {
Date date = new Date();// 创建一个时间对象,获取到当前的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);// 设置时间显示格式
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String CurrentTime = sdf.format(date);
return CurrentTime;
}
public static String getTime2() {
long timeMillis = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(timeMillis);
}
public static String getLongTime() {
long timeMillis = System.currentTimeMillis();
return timeMillis + "";
}
/**
* 获取当前时间
*
* @return
*/
public static String getTimeYmd() {
Date date = new Date();// 创建一个时间对象,获取到当前的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);// 设置时间显示格式
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String CurrentTime = sdf.format(date);
return CurrentTime;
}
/**
* 获取当前时间
*
* @return
*/
public static String getTimeYm() {
Date date = new Date();// 创建一个时间对象,获取到当前的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM", Locale.CHINA);// 设置时间显示格式
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String CurrentTime = sdf.format(date);
return CurrentTime;
}
/**
* 比较两个日期的大小日期格式为yyyy-MM-dd
*
* @param str1 the first date
* @param str2 the second date
* @return true <br/>false
*/
public static boolean isDate2Bigger(String str1, String str2) {
boolean isBigger = false;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
Date dt1 = null;
Date dt2 = null;
try {
dt1 = sdf.parse(str1);
dt2 = sdf.parse(str2);
} catch (ParseException e) {
e.printStackTrace();
}
if (dt1.getTime() > dt2.getTime()) {
isBigger = false;
} else if (dt1.getTime() <= dt2.getTime()) {
isBigger = true;
}
return isBigger;
}
private static final long SS = 1000;
private static final long MS = SS * 60;
private static final long HourS = MS * 60;
private static final long DayS = HourS * 24;
private static final long MonthS = DayS * 30;
private static final long YearS = MonthS * 12;
/**
* 时间戳转
*
* @param timestamp 时间戳
* @return
*/
public static String sendTime(long timestamp) {
long timeMillis = System.currentTimeMillis();
long timeKK = timeMillis - timestamp;
if (timeKK > YearS) {
int time = (int) (timeKK / YearS);
return time + "年前";
} else if (timeKK > MonthS) {
int time = (int) (timeKK / MonthS);
return time + "个月前";
} else if (timeKK > DayS) {
int time = (int) (timeKK / DayS);
return time + "天前";
} else if (timeKK > HourS) {
int time = (int) (timeKK / HourS);
return time + "小时前";
} else if (timeKK > MS) {
int time = (int) (timeKK / MS);
return time + "分钟前";
} else if (timeKK > SS) {
int time = (int) (timeKK / SS);
return time + "秒前";
} else {
return "刚刚";
}
}
/**
* yy_MM_DD HH:MM:SS 转
*
* @param timeyy
* @return
*/
public static String sendTime(String timeyy) {
long timestamp = TimeUtil.dataOne(timeyy);//转时间戳
long timeMillis = System.currentTimeMillis();
long timeKK = timeMillis - timestamp;
if (timeKK > YearS) {
int time = (int) (timeKK / YearS);
return time + "年前";
} else if (timeKK > MonthS) {
int time = (int) (timeKK / MonthS);
return time + "个月前";
} else if (timeKK > DayS) {
int time = (int) (timeKK / DayS);
return time + "天前";
} else if (timeKK > HourS) {
int time = (int) (timeKK / HourS);
return time + "小时前";
} else if (timeKK > MS) {
int time = (int) (timeKK / MS);
return time + "分钟前";
} else if (timeKK > SS) {
int time = (int) (timeKK / SS);
return time + "秒前";
} else {
return "刚刚";
}
}
/**
* yy_MM_DD HH:MM:SS 转
*
* @param timeyy
* @return
*/
public static String chatTime(String timeyy) {
long timestamp = TimeUtil.dataOne(timeyy);//转时间戳
long timeMillis = System.currentTimeMillis();
long timeKK = timeMillis - timestamp;
if (timeKK > 3 * DayS) {
return timeyy;
} else if (timeKK > 2 * DayS) {
return "前天" + toDateHhmm(dataOne(timeyy));
} else if (timeKK > DayS) {
return "昨天" + toDateHhmm(dataOne(timeyy));
} else if (timeKK > 5 * MS) {
return toDateHhmm(dataOne(timeyy));
} else if (timeKK > MS) {
int time = (int) (timeKK / MS);
return time + "分钟前";
} else if (timeKK > SS) {
int time = (int) (timeKK / SS);
return time + "秒前";
} else {
return "刚刚";
}
}
/**
* yy_MM_DD HH:MM:SS 转
*
* @param timeyy
* @return
*/
public static String chatTimee(String timeyy) {
long timestamp = TimeUtil.dataOne(timeyy);//转时间戳
long timeMillis = System.currentTimeMillis();
long timeKK = timeMillis - timestamp;
if (timeKK > DayS) {
return timeyy;
} else if (timeKK > HourS) {
int time = (int) (timeKK / HourS);
return time + "小时前";
} else if (timeKK > MS) {
int time = (int) (timeKK / MS);
return time + "分钟前";
} else {
return "刚刚";
}
}
/**
* 调此方法输入所要转换的时间输入例如("2014-06-14-16-09-00")返回时间戳
*
* @param time
* @return
*/
public static long dataOne(String time) {
SimpleDateFormat sdr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.CHINA);
sdr.setTimeZone(TimeZone.getTimeZone("GMT+8"));
Date date;
long ltime = 0;
try {
date = sdr.parse(time);
ltime = date.getTime();
/* String stf = String.valueOf(l);
times = stf.substring(0, 10);*/
} catch (Exception e) {
e.printStackTrace();
}
return ltime;
}
/**
* 时间戳 返回 HH:MM
*
* @param times
* @return
*/
public static String toDateHhmm(long times) {
SimpleDateFormat format = new SimpleDateFormat("HH:mm",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
/**
* 时间戳 返回 MM:ss
*
* @param times
* @return
*/
public static String toDateMMss(long times) {
SimpleDateFormat format = new SimpleDateFormat("mm:ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDateYmd(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times*1000);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDateYmd3(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDateYmd5(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times*1000);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDateYmdHan(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times*1000);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDateYmdHan3(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times * 1000);
}
public static String toDateYmdHan2(long times) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
public static String toDateYmdHanNew(long times,String str) {
SimpleDateFormat format = new SimpleDateFormat(str,
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
public static String longtoHM(long times) {
int lhour = (int) times / 60;
int lMin = (int) times % 60;
String strMIn;
if (lMin < 10) {
strMIn = "0" + lMin;
} else {
strMIn = lMin + "";
}
return lhour + ":" + strMIn;
}
/**
* 获取剩余天数
*
* @param serverTime 时间
* @param serverTime 样式
* @return
* @throws ParseException
*/
public static int getLeftDay(String serverTime) {
long timestamp = TimeUtil.dataOne(serverTime);//转时间戳
long timeMillis = System.currentTimeMillis();
long leftMillins = timestamp - timeMillis;
int leftDay = (int) (leftMillins / (3600 * 24 * 1000));
return leftDay;
}
// 根据年月日计算年龄,birthTimeString:"1994-11-14"
public static int getAgeByDay(Date date) {
// 得到当前时间的年、月、日
if (date != null) {
Calendar cal = Calendar.getInstance();
int yearNow = cal.get(Calendar.YEAR);
int monthNow = cal.get(Calendar.MONTH) + 1;
int dayNow = cal.get(Calendar.DATE);
//得到输入时间的年,月,日
cal.setTime(date);
int selectYear = cal.get(Calendar.YEAR);
int selectMonth = cal.get(Calendar.MONTH) + 1;
int selectDay = cal.get(Calendar.DATE);
// 用当前年月日减去生日年月日
int yearMinus = yearNow - selectYear;
int monthMinus = monthNow - selectMonth;
int dayMinus = dayNow - selectDay;
int age = yearMinus;// 先大致赋值
if (yearMinus <= 0) {
age = 0;
}
if (monthMinus < 0) {
age = age - 1;
} else if (monthMinus == 0) {
if (dayMinus < 0) {
age = age - 1;
}
}
return age;
}
return 0;
}
/**
* 日期转Date
*
* @param serverTime
* @param format
* @return
*/
public static Date parseServerTime(String serverTime, String format) {
if (format == null || format.isEmpty()) {
format = "yyyy-MM-dd HH:mm:ss";
}
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINESE);
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
Date date = null;
try {
date = sdf.parse(serverTime);
} catch (Exception e) {
}
return date;
}
/**
* 时间戳 返回 HH:MM:ss
*
* @param times
* @return
*/
public static String toDateHhmmss(long times) {
SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @param times
* @return
*/
public static String toDatee(long times) {
SimpleDateFormat format = new SimpleDateFormat("HH时mm分ss秒",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
public static String toDateee(long times) {
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return format.format(times);
}
public static String toDateeee(long times) {
SimpleDateFormat format = new SimpleDateFormat("ss",
Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String afterTime = format.format(times);
if(!TextUtils.isEmpty(afterTime)){
if (afterTime.startsWith("0")) {
afterTime = afterTime.substring(1);
}
}
return afterTime;
}
/**
* 获取指定单位数字
*/
public static int toMeFormat(String formatoo, String beginTime) {
SimpleDateFormat format = new SimpleDateFormat(formatoo, Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String format1 = format.format(beginTime);
return Integer.parseInt(format1);
}
private static String add00(int oldInt) {
if (oldInt < 10) {
return "0" + oldInt;
} else {
return oldInt + "";
}
}
/**
* 时间戳 返回 yyyy-MM-dd
*
* @return "yyyy-MM-dd HH:mm:ss"
*/
public static String getReachDay(String beginTime, int months, int days) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
int mm_start = Integer.parseInt(beginTime.substring(5, 7));
int day_start = Integer.parseInt(beginTime.substring(8, 10));
StringBuilder beginTime00 = new StringBuilder(beginTime);
StringBuilder replace0 = beginTime00.replace(5, 7, TimeUtil.add00(mm_start + months));
StringBuilder replace2 = replace0.replace(8, 10, TimeUtil.add00(day_start + days));
try {
return format.format(format.parse(replace2.toString()));
} catch (Exception e) {
}
return "";
}
public static String formatDateTime2(long milliseconds) {
StringBuilder sb = new StringBuilder();
long mss = milliseconds*1000 / 1000;
long days = mss / (60 * 60 * 24);
long hours = (mss % (60 * 60 * 24)) / (60 * 60);
long minutes = (mss % (60 * 60)) / 60;
long seconds = mss % 60;
DecimalFormat format = new DecimalFormat("00");
// Log.d("Time", "--days:" + days + "--hours:" + hours + "--minutes:" + minutes + "--seconds:" + seconds);
if (days > 0 || hours > 0) {
sb.append(format.format(hours)).append(":").append(format.format(minutes)).append(":").append(format.format(seconds));
} else {
sb.append(format.format(minutes)).append(":").append(format.format(seconds));
}
return sb.toString();
}
}

View File

@@ -0,0 +1,52 @@
package com.yuyin.lib_base.util;
import android.content.Context;
import android.os.Handler;
import android.widget.Toast;
/**
* 算是重写了个吐司,优化误操作多的时候疯狂弹吐司的情况。
*/
public class ToastUtil {
private static Toast mToast;
private static Handler mHandler = new Handler();
private static Runnable r = new Runnable() {
public void run() {
if (mToast != null)
mToast.cancel();
mToast = null;
}
};
public static void showToast(Context mContext, String text) {
mHandler.removeCallbacks(r);
if (mToast != null) {
mToast.setText(text);
} else {
if (mContext != null)
mToast = Toast.makeText(mContext, text, Toast.LENGTH_SHORT);
//下边是在吐司中加入图片
// LinearLayout toastView = (LinearLayout) mToast.getView();
// ImageView imageCodeProject = new ImageView(mContext);
// if (type == 1) {
// imageCodeProject.setImageResource(R.drawable.ic_toast_success);
// toastView.addView(imageCodeProject, 0);
// } else if (type == 2) {
// imageCodeProject.setImageResource(R.drawable.ic_toast_false);
// toastView.addView(imageCodeProject, 0);
// } else if (type == 3) {
// imageCodeProject.setImageResource(R.drawable.ic_toast_tips);
// toastView.addView(imageCodeProject, 0);
// }
}
// mToast.setGravity(Gravity.CENTER, 0, 0);
mHandler.postDelayed(r, 3000);
if (mToast != null)
mToast.show();
}
// public static void showToast(Context mContext, int resId, int duration) {
// showToast(mContext, Integer.parseInt(mContext.getResources().getString(resId)), duration);
// }
}

View File

@@ -0,0 +1,46 @@
package com.yuyin.lib_base.util;
import android.content.res.Resources;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.Keep;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@Keep
public class UiUtil {
public static int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
}
public static <T> Class<T> getGenericClass(Class<?> clz, int index) {
Type type = clz.getGenericSuperclass();
if (type == null) return null;
return (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[index];
}
public static Object getViewBinding(Class<?> bindingClass, LayoutInflater inflater) {
try {
Method inflateMethod = bindingClass.getDeclaredMethod("inflate", LayoutInflater.class);
return inflateMethod.invoke(null, inflater);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T getViewBinding(Class<T> bindingClass, LayoutInflater inflater, ViewGroup container) {
try {
Method inflateMethod = bindingClass.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, Boolean.TYPE);
return (T) inflateMethod.invoke(null, inflater, container, false);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,132 @@
package com.yuyin.lib_base.util;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import com.xuexiang.xupdate.proxy.IUpdateHttpService;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;
import com.zhy.http.okhttp.request.RequestCall;
import java.io.File;
import java.util.Map;
import java.util.TreeMap;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.Request;
/**
* Created by Vector
* on 2017/6/19 0019.
*/
public class UpdateAppHttpUtil implements IUpdateHttpService {
private boolean mIsPostJson;
public UpdateAppHttpUtil() {
this(false);
}
public UpdateAppHttpUtil(boolean isPostJson) {
mIsPostJson = isPostJson;
}
@Override
public void asyncGet(@NonNull String url, @NonNull Map<String, Object> params, final @NonNull Callback callBack) {
OkHttpUtils.get()
.url(url)
.params(transform(params))
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
callBack.onError(e);
}
@Override
public void onResponse(String response, int id) {
callBack.onSuccess(response);
}
});
}
@Override
public void asyncPost(@NonNull String url, @NonNull Map<String, Object> params, final @NonNull Callback callBack) {
//这里默认post的是Form格式使用json格式的请修改 post -> postString
RequestCall requestCall;
if (mIsPostJson) {
requestCall = OkHttpUtils.postString()
.url(url)
.content(new Gson().toJson(params))
.mediaType(MediaType.parse("application/json; charset=utf-8"))
.build();
} else {
requestCall = OkHttpUtils.post()
.url(url)
.params(transform(params))
.build();
}
requestCall
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
callBack.onError(e);
}
@Override
public void onResponse(String response, int id) {
callBack.onSuccess(response);
}
});
}
@Override
public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, final @NonNull DownloadCallback callback) {
OkHttpUtils.get()
.url(url)
.tag(url)
.build()
.execute(new FileCallBack(path, fileName) {
@Override
public void inProgress(float progress, long total, int id) {
callback.onProgress(progress, total);
}
@Override
public void onError(Call call, Exception e, int id) {
callback.onError(e);
}
@Override
public void onResponse(File response, int id) {
callback.onSuccess(response);
}
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
callback.onStart();
}
});
}
@Override
public void cancelDownload(@NonNull String url) {
OkHttpUtils.getInstance().cancelTag(url);
}
private Map<String, String> transform(Map<String, Object> params) {
Map<String, String> map = new TreeMap<>();
for (Map.Entry<String, Object> entry : params.entrySet()) {
map.put(entry.getKey(), entry.getValue().toString());
}
return map;
}
}

View File

@@ -0,0 +1,99 @@
package com.yuyin.lib_base.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.AssetFileDescriptor
import android.media.AudioManager
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build
import androidx.annotation.RequiresApi
/**
* 音频播放
*/
@SuppressLint("StaticFieldLeak")
object MediaPlayerUtil {
private var mContext: Context? = null
var mPlayer: MediaPlayer? = null
private var isPause = false
private var isPlaying = false
fun isPlaying(): Boolean {
return isPlaying
}
open fun initMedia(mContext: Context, rawRes: Int) {
mPlayer = MediaPlayer.create(mContext, rawRes)
mPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
}
@RequiresApi(Build.VERSION_CODES.N)
fun initMedia(mContext: Context, fad: AssetFileDescriptor) {
mPlayer = MediaPlayer()
mPlayer!!.setDataSource(fad)
}
fun initMedia(mContext: Context, path: String) {
mPlayer = MediaPlayer()
mPlayer!!.setDataSource(path)
}
fun initUriMedia(mContext: Context, uriPath: String) {
mPlayer = MediaPlayer()
mPlayer!!.setDataSource(mContext!!, Uri.parse(uriPath))
mPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
}
fun playMedia() {
if (mPlayer != null && !mPlayer!!.isPlaying) {
mPlayer!!.start()
}
}
fun prepare() {
if (mPlayer != null && !mPlayer!!.isPlaying) {
// mPlayer!!.prepare()
mPlayer!!.setOnPreparedListener {
}
}
}
fun prepareAsync() {
if (mPlayer != null && !mPlayer!!.isPlaying) {
mPlayer!!.prepareAsync()
}
}
fun pause() {
if (mPlayer != null && mPlayer!!.isPlaying) {
mPlayer!!.pause()
isPause = true
}
}
// 继续
fun resume() {
if (mPlayer != null && isPause) {
mPlayer!!.start()
isPause = false
}
}
fun release() {
if (mPlayer != null) {
try {
mPlayer!!.release()
} catch (e: Exception) {
}
mPlayer = null
}
isPlaying = false
}
}

View File

@@ -0,0 +1,57 @@
package com.voice.lib_base.ext
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.ParameterizedType
/**
* 作者 : QIngNing
* 时间 : 2021/12/21
* 描述 :
*/
@JvmName("inflateWithGeneric")
fun <VB : ViewBinding> AppCompatActivity.inflateBindingWithGeneric(layoutInflater: LayoutInflater): VB =
withGenericBindingClass<VB>(this) { clazz ->
clazz.getMethod("inflate", LayoutInflater::class.java).invoke(null, layoutInflater) as VB
}.also { binding ->
if (binding is ViewDataBinding) {
binding.lifecycleOwner = this
}
}
@JvmName("inflateWithGeneric")
fun <VB : ViewBinding> Fragment.inflateBindingWithGeneric(layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean): VB =
withGenericBindingClass<VB>(this) { clazz ->
clazz.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java)
.invoke(null, layoutInflater, parent, attachToParent) as VB
}.also { binding ->
if (binding is ViewDataBinding) {
binding.lifecycleOwner = viewLifecycleOwner
}
}
private fun <VB : ViewBinding> withGenericBindingClass(any: Any, block: (Class<VB>) -> VB): VB {
var genericSuperclass = any.javaClass.genericSuperclass
var superclass = any.javaClass.superclass
while (superclass != null) {
if (genericSuperclass is ParameterizedType) {
try {
return block.invoke(genericSuperclass.actualTypeArguments[0] as Class<VB>)
} catch (e: NoSuchMethodException) {
} catch (e: ClassCastException) {
} catch (e: InvocationTargetException) {
throw e.targetException
}
}
genericSuperclass = superclass.genericSuperclass
superclass = superclass.superclass
}
throw IllegalArgumentException("There is no generic of ViewBinding.")
}

View File

@@ -0,0 +1,28 @@
package com.yuyin.lib_base.util;
import android.view.View;
import androidx.core.view.ViewCompat;
//import com.sxu.shadowdrawable.ShadowDrawable;
/**
* Created by cxf on 2018/9/29.
*/
public class ViewUtil {
/*public static void setShadowDrawable(View view, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
ShadowDrawable drawable = new ShadowDrawable.Builder()
.setShapeRadius(shapeRadius)
.setShadowColor(shadowColor)
.setShadowRadius(shadowRadius)
.setOffsetX(offsetX)
.setOffsetY(offsetY)
.builder();
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
ViewCompat.setBackground(view, drawable);
}*/
}

View File

@@ -0,0 +1,127 @@
package com.yuyin.lib_base.util
import android.app.ActivityManager
import android.content.Context
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Shader
import android.text.TextUtils
import android.util.Base64
import android.widget.TextView
import com.blankj.utilcode.util.LogUtils
import com.yuyin.lib_base.App
import com.yuyin.lib_base.BuildConfig
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.lang.reflect.ParameterizedType
fun setGradient(textView: TextView) {
val endX = textView.paint.textSize * textView.text.length
val colors = intArrayOf(
Color.parseColor("#4E67F1"),
Color.parseColor("#AA88F8")
) //颜色的数组
val position = floatArrayOf(0f, 1.0f) //颜色渐变位置的数组
val linearGradient =
LinearGradient(0f, 0f, endX, 0f, colors, position, Shader.TileMode.CLAMP)
textView.paint.shader = linearGradient
textView.invalidate()
}
/**
* service是否正在运行
* @param context
* @param className
* @return
*/
fun isServiceExisted(context: Context, className: String): Boolean {
val activityManager = context
.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val serviceList = activityManager
.getRunningServices(Int.MAX_VALUE)
if (serviceList.size <= 0) {
return false
}
for (i in serviceList.indices) {
val serviceInfo = serviceList[i]
val serviceName = serviceInfo.service
val name = serviceName.className
if (name == className) {
return true
}
}
return false
}
fun String.showToast() {
if (!TextUtils.isEmpty(this)) {
// ToastUtils.showShort(this)
ToastUtil.showToast(App.instance, this)
}
}
fun String.log() {
if (!TextUtils.isEmpty(this)) {
if (BuildConfig.DEBUG)
LogUtils.dTag("yuyinLog", this)
}
}
fun String.log2() {
if (!TextUtils.isEmpty(this)) {
if (BuildConfig.DEBUG)
LogUtils.dTag("yuyinLog2", this)
}
}
/**
* 根据手机分辨率从DP转成PX
*
* @param context
* @param dpValue
* @return
*/
fun dip2px(context: Context, dpValue: Float): Int {
val scale = context.resources.displayMetrics.density
return (dpValue * scale + 0.5f).toInt()
}
fun <T> getClass(t: Any): Class<T> {
// 通过反射 获取父类泛型 (T) 对应 Class类
return (t.javaClass.genericSuperclass as ParameterizedType)
.actualTypeArguments[0]
as Class<T>
}
/**
* 文件转Base64.
*
* @param filePath
* @return
*/
fun file2Base64(filePath: String): String {
var objFileIS: FileInputStream? = null
try {
objFileIS = FileInputStream(filePath)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
val objByteArrayOS = ByteArrayOutputStream()
val byteBufferString = ByteArray(1024)
try {
var readNum: Int
while (objFileIS!!.read(byteBufferString).also { readNum = it } != -1) {
objByteArrayOS.write(byteBufferString, 0, readNum)
}
} catch (e: IOException) {
e.printStackTrace()
}
return Base64.encodeToString(objByteArrayOS.toByteArray(), Base64.DEFAULT)
}

View File

@@ -0,0 +1,159 @@
package com.yuyin.lib_base.util;
import android.os.Looper;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public final class ZipUtils {
private static final String TAG = ZipUtils.class.getSimpleName();
private static final Executor wokeExecutor = Executors.newSingleThreadExecutor();
private static final android.os.Handler mainThreadHandler = new android.os.Handler(Looper.getMainLooper());
public static void unzipOnlyPlainXmlFilesAsync(String zipFilePath,
String targetDirPath,
UnZipCallback callback) {
// This is for zipped lyrics file, we only need the plain .xml files
unZipAsync(zipFilePath, targetDirPath, "^(?!/)[a-zA-Z\\d]+.xml", callback);
}
public static void unZipAsync(String zipFilePath,
String targetDirPath,
String filter,
UnZipCallback callback) {
wokeExecutor.execute(() -> {
try {
List<String> outPath = unzipSync(zipFilePath, targetDirPath, filter, false);
if (callback != null) {
mainThreadHandler.post(() -> callback.onFileUnZipped(outPath));
}
} catch (Exception e) {
if (callback != null) {
mainThreadHandler.post(() -> callback.onError(e));
}
}
});
}
public static List<String> unzipSync(String zipFilePath,
String targetDirPath,
String filter,
boolean reserve) throws Exception {
File zipFile = new File(zipFilePath);
if (!zipFile.exists()) {
// CommonBaseLogger.w(TAG, "File " + zipFile + " not found");
throw new FileNotFoundException(zipFilePath);
}
File targetDir = new File(targetDirPath);
if (targetDir.exists() && targetDir.isFile()) {
throw new RuntimeException("The target direction is a file!");
}
if (!targetDir.exists()) {
targetDir.mkdirs();
}
ZipFile zzipFile = new ZipFile(zipFile);
Enumeration<? extends ZipEntry> entries = zzipFile.entries();
List<String> outPath = new ArrayList<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.getName().matches(filter)) {
copyEntry(zzipFile, entry, targetDir, reserve, outPath);
} else {
Log.w(TAG, "Skipping unexpected file: " + entry.getName());
}
}
return outPath;
}
private static void copyEntry(ZipFile zipFile,
ZipEntry entry,
File targetDir,
boolean reserve,
List<String> outFilesPath) throws IOException {
InputStream iStream = null;
OutputStream oStream = null;
if (entry.isDirectory()) {
if (reserve) {
// TODO 待实现
}
} else {
File oFile = new File(targetDir, entry.getName());
oFile.deleteOnExit();
oFile.createNewFile();
oStream = new FileOutputStream(oFile, false);
iStream = zipFile.getInputStream(entry);
outFilesPath.add(oFile.getAbsolutePath());
}
if (oStream == null || iStream == null) {
return;
}
try {
copy(iStream, oStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
iStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
oStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static long copy(InputStream from, OutputStream to) throws IOException {
byte[] buf = createBuffer();
long total = 0;
while (true) {
int r = from.read(buf);
if (r == -1) {
break;
}
to.write(buf, 0, r);
total += r;
}
return total;
}
private static final int BUFFER_SIZE = 8192;
/**
* Creates a new byte array for buffering reads or writes.
*/
static byte[] createBuffer() {
return new byte[BUFFER_SIZE];
}
private ZipUtils() {
}
public interface UnZipCallback {
void onFileUnZipped(List<String> unZipFilePaths);
void onError(Exception e);
}
}

View File

@@ -0,0 +1,105 @@
package com.yuyin.lib_base.util.img;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Point;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.viewpager.widget.ViewPager;
import com.yuyin.lib_base.R;
import java.util.List;
/**
* 看大图
*/
public class FullScreenUtil {
public static void showFullScreenDialog(Context context, final int pos, final List<String> imgList) {
final Dialog dialog = new Dialog(context, R.style.big_pic_dialog);
//设置是否允许Dialog可以被点击取消,也会阻止Back键
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
Window window = dialog.getWindow();
window.setGravity(Gravity.CENTER);
//获取Dialog窗体的根容器
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup root = (ViewGroup) dialog.getWindow().getDecorView().findViewById(android.R.id.content);
//设置窗口大小为屏幕大小item_img_pv
WindowManager wm = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Point screenSize = new Point();
wm.getDefaultDisplay().getSize(screenSize);
root.setLayoutParams(new LinearLayout.LayoutParams(screenSize.x, screenSize.y));
// 获取自定义布局,并设置给Dialog
View view = inflater.inflate(R.layout.pop_photo_vp, root, false);
final ViewPager img_vp = view.findViewById(R.id.img_vp);
final TextView img_num_iv = view.findViewById(R.id.img_num_iv);
final ImageView img_down_iv = view.findViewById(R.id.img_down_iv);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
ImgVPAdapter vpAdapter = new ImgVPAdapter(context, imgList);
img_vp.setAdapter(vpAdapter);
img_vp.setCurrentItem(pos);
img_num_iv.setText((pos + 1) + "/" + imgList.size());
img_down_iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//保存
/* if (imgList.get(pos) != null) {
ImageSaveUtils.saveImg(XQDetailActivity.this, imgList.get(pos));
}*/
}
});
img_vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(final int position) {
img_num_iv.setText((position + 1) + "/" + imgList.size());
img_down_iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* if(imgList.get(position)!=null){
ImageSaveUtils.saveImg(XQDetailActivity.this, imgList.get(position));
}
*/
}
});
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
vpAdapter.setAllClickListener(new ImgVPAdapter.AllClickListener() {
@Override
public void allclick(int pos) {
dialog.dismiss();
}
});
dialog.setContentView(view);
dialog.show();
}
}

View File

@@ -0,0 +1,69 @@
package com.yuyin.lib_base.util.img;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.viewpager.widget.PagerAdapter;
import com.bumptech.glide.Glide;
import com.yuyin.lib_base.R;
import java.util.List;
public class ImgVPAdapter extends PagerAdapter {
private Context context;
private List<String> paths;
public ImgVPAdapter(Context context, List<String> paths) {
this.context = context;
this.paths = paths;
}
@Override
public int getCount() {
return paths.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView iv_img = (ImageView) LayoutInflater.from(context).inflate(R.layout.item_img_pv, null);
// iv_img.setScaleType(ImageView.ScaleType.CENTER);
Glide.with(context).load( paths.get(position)).error(R.mipmap.no_tu).into(iv_img);
iv_img.setScaleType(ImageView.ScaleType.CENTER);
iv_img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (allClickListener != null) {
allClickListener.allclick(position);
}
}
});
container.addView(iv_img);
return iv_img;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
public interface AllClickListener {
void allclick(int pos);
}
public AllClickListener allClickListener;
public void setAllClickListener(AllClickListener allClickListener) {
this.allClickListener = allClickListener;
}
}

View File

@@ -0,0 +1,122 @@
package com.yuyin.lib_base.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.renderscript.RSRuntimeException;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import jp.wasabeef.glide.transformations.internal.FastBlur;
import jp.wasabeef.glide.transformations.internal.RSBlur;
/**
* 虚化Transformation
* 更多效果参考https://github.com/wasabeef/glide-transformations
*/
public class BlurTransformation extends BitmapTransformation {
private static String STRING_CHARSET_NAME = "UTF-8";
private static final String ID = "com.kevin.glidetest.BlurTransformation";
private static Charset CHARSET = Charset.forName(STRING_CHARSET_NAME);
private static final byte[] ID_BYTES = ID.getBytes(CHARSET);
private static int MAX_RADIUS = 25;
private static int DEFAULT_DOWN_SAMPLING = 1;
private Context mContext;
private BitmapPool mBitmapPool;
private int mRadius;
private int mSampling;
public BlurTransformation(Context context) {
this(context, Glide.get(context).getBitmapPool(), MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, BitmapPool pool) {
this(context, pool, MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, BitmapPool pool, int radius) {
this(context, pool, radius, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, int radius) {
this(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, int radius, int sampling) {
this(context, Glide.get(context).getBitmapPool(), radius, sampling);
}
public BlurTransformation(Context context, BitmapPool pool, int radius, int sampling) {
mContext = context.getApplicationContext();
mBitmapPool = pool;
mRadius = radius;
mSampling = sampling;
}
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int
outWidth, int outHeight) {
Bitmap source = toTransform ;
int width = source.getWidth();
int height = source.getHeight();
int scaledWidth = width / mSampling;
int scaledHeight = height / mSampling;
Bitmap bitmap = mBitmapPool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
canvas.scale(1 / (float) mSampling, 1 / (float) mSampling);
Paint paint = new Paint();
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(source, 0, 0, paint);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
try {
bitmap = RSBlur.blur(mContext, bitmap, mRadius);
} catch (RSRuntimeException e) {
bitmap = FastBlur.blur(bitmap, mRadius, true);
}
} else {
bitmap = FastBlur.blur(bitmap, mRadius, true);
}
//return BitmapResource.obtain(bitmap, mBitmapPool);
return bitmap;
}
@Override
public int hashCode() {
return ID.hashCode();
}
@Override
public boolean equals(Object obj) {
return obj instanceof BlurTransformation;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(ID_BYTES);
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.lib_base.view;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan;
public class CenterAlignImageSpan extends ImageSpan {
public CenterAlignImageSpan(Drawable drawable) {
super(drawable);
}
public CenterAlignImageSpan(Bitmap b) {
super(b);
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
Paint paint) {
Drawable b = getDrawable();
Paint.FontMetricsInt fm = paint.getFontMetricsInt();
int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
canvas.save();
canvas.translate(x, transY);//绘制图片位移一段距离
b.draw(canvas);
canvas.restore();
}
}

View File

@@ -0,0 +1,40 @@
package com.yuyin.lib_base.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
/**
* 圆形头像
*/
public class CircularImage extends MaskedImage {
public CircularImage(Context paramContext) {
super(paramContext);
}
public CircularImage(Context paramContext, AttributeSet paramAttributeSet) {
super(paramContext, paramAttributeSet);
}
public CircularImage(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
super(paramContext, paramAttributeSet, paramInt);
}
public Bitmap createMask() {
int i = getWidth();
int j = getHeight();
Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
Bitmap localBitmap = Bitmap.createBitmap(i, j, localConfig);
Canvas localCanvas = new Canvas(localBitmap);
Paint localPaint = new Paint(1);
float f1 = getWidth();
float f2 = getHeight();
RectF localRectF = new RectF(0.0F, 0.0F, f1, f2);
localCanvas.drawOval(localRectF, localPaint);
return localBitmap;
}
}

View File

@@ -0,0 +1,132 @@
package com.yuyin.lib_base.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
import java.security.MessageDigest;
public class CornerTransform implements Transformation<Bitmap> {
private BitmapPool mBitmapPool;
private float radius;
private boolean exceptLeftTop, exceptRightTop, exceptLeftBottom, exceptRightBotoom;
/**
* 除了那几个角不需要圆角的
*
* @param leftTop
* @param rightTop
* @param leftBottom
* @param rightBottom
*/
public void setExceptCorner(boolean leftTop, boolean rightTop, boolean leftBottom, boolean rightBottom) {
this.exceptLeftTop = leftTop;
this.exceptRightTop = rightTop;
this.exceptLeftBottom = leftBottom;
this.exceptRightBotoom = rightBottom;
}
public CornerTransform(Context context, float radius) {
this.mBitmapPool = Glide.get(context).getBitmapPool();
this.radius = radius;
}
@NonNull
@Override
public Resource<Bitmap> transform(@NonNull Context context, @NonNull Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int finalWidth, finalHeight;
float ratio; //输出目标的宽高或高宽比例
if (outWidth > outHeight) { //输出宽度>输出高度,求高宽比
ratio = (float) outHeight / (float) outWidth;
finalWidth = source.getWidth();
finalHeight = (int) ((float) source.getWidth() * ratio); //固定原图宽度,求最终高度
if (finalHeight > source.getHeight()) { //求出的最终高度>原图高度,求宽高比
ratio = (float) outWidth / (float) outHeight;
finalHeight = source.getHeight();
finalWidth = (int) ((float) source.getHeight() * ratio);//固定原图高度,求最终宽度
}
} else if (outWidth < outHeight) { //输出宽度 < 输出高度,求宽高比
ratio = (float) outWidth / (float) outHeight;
finalHeight = source.getHeight();
finalWidth = (int) ((float) source.getHeight() * ratio);//固定原图高度,求最终宽度
if (finalWidth > source.getWidth()) { //求出的最终宽度 > 原图宽度,求高宽比
ratio = (float) outHeight / (float) outWidth;
finalWidth = source.getWidth();
finalHeight = (int) ((float) source.getWidth() * ratio);
}
} else { //输出宽度=输出高度
finalHeight = source.getHeight();
finalWidth = finalHeight;
}
//修正圆角
this.radius *= (float) finalHeight / (float) outHeight;
Bitmap outBitmap = this.mBitmapPool.get(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
if (outBitmap == null) {
outBitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(outBitmap);
Paint paint = new Paint();
//关联画笔绘制的原图bitmap
BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//计算中心位置,进行偏移
int width = (source.getWidth() - finalWidth) / 2;
int height = (source.getHeight() - finalHeight) / 2;
if (width != 0 || height != 0) {
Matrix matrix = new Matrix();
matrix.setTranslate((float) (-width), (float) (-height));
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(true);
RectF rectF = new RectF(0.0F, 0.0F, (float) canvas.getWidth(), (float) canvas.getHeight());
canvas.drawRoundRect(rectF, this.radius, this.radius, paint); //先绘制圆角矩形
if (exceptLeftTop) { //左上角不为圆角
canvas.drawRect(0, 0, radius, radius, paint);
}
if (exceptRightTop) {//右上角不为圆角
canvas.drawRect(canvas.getWidth() - radius, 0, radius, radius, paint);
}
if (exceptLeftBottom) {//左下角不为圆角
canvas.drawRect(0, canvas.getHeight() - radius, radius, canvas.getHeight(), paint);
}
if (exceptRightBotoom) {//右下角不为圆角
canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius, canvas.getWidth(), canvas.getHeight(), paint);
}
return BitmapResource.obtain(outBitmap, this.mBitmapPool);
}
// @Override
// public String getId() {
// return this.getClass().getName();
// }
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
}

View File

@@ -0,0 +1,33 @@
package com.yuyin.lib_base.view
import android.content.Context
import android.widget.ImageView
import com.yuyin.lib_base.R
import com.yuyin.lib_base.util.dip2px
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.youth.banner.loader.ImageLoader
class GlideImageLoader : ImageLoader() {
override fun displayImage(context: Context, path: Any, imageView: ImageView) {
//Glide 加载图片简单用法
//设置图片圆角角度
val transformation = CornerTransform(context, dip2px(context, 10f).toFloat())
//只是绘制左上角和右上角圆角
transformation.setExceptCorner(false, false, false, false)
//Glide 加载图片简单用法
val options = RequestOptions()
.placeholder(R.mipmap.no_tu)
.transform(transformation)
.error(R.mipmap.no_tu)
if (context != null) {
try {
Glide.with(context).load(path)
.apply(options)
.into(imageView)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.lib_base.view
import android.content.Context
import android.widget.ImageView
import com.yuyin.lib_base.R
import com.yuyin.lib_base.util.dip2px
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.youth.banner.loader.ImageLoader
class GlideImageLoader2 : ImageLoader() {
override fun displayImage(context: Context, path: Any, imageView: ImageView) {
//Glide 加载图片简单用法
//设置图片圆角角度
// val transformation = CornerTransform(context, dip2px(context, 10f).toFloat())
//只是绘制左上角和右上角圆角
// transformation.setExceptCorner(false, false, false, false)
//Glide 加载图片简单用法
imageView.scaleType = ImageView.ScaleType.CENTER_INSIDE
val options = RequestOptions()
.placeholder(R.mipmap.no_tu)
// .transform(transformation)
.error(R.mipmap.no_tu)
if (context != null) {
try {
Glide.with(context).load(path)
.apply(options)
.into(imageView)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}

View File

@@ -0,0 +1,39 @@
package com.yuyin.mixin.module_login.ui
import android.app.Dialog
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Window
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import com.yuyin.lib_base.R
import com.yuyin.lib_base.databinding.DialogGraphicCodeBinding
class GraphicCodeDialog(context: Context) : Dialog(context, R.style.myChooseDialog) {
private lateinit var binding: DialogGraphicCodeBinding
init {
initDialog()
}
private fun initDialog() {
val inflater = LayoutInflater.from(context);
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_graphic_code, null, false)
setContentView(binding.root)
val win: Window? = this.window
val lp: WindowManager.LayoutParams = win!!.attributes
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
lp.gravity = Gravity.CENTER
win.attributes = lp
win.setBackgroundDrawableResource(android.R.color.transparent)
}
fun getBinding(): DialogGraphicCodeBinding {
return binding
}
}

Some files were not shown because too many files have changed in this diff Show More