diff --git a/Lib_Base/build.gradle b/Lib_Base/build.gradle index c3f6848..b263e7d 100644 --- a/Lib_Base/build.gradle +++ b/Lib_Base/build.gradle @@ -50,6 +50,8 @@ dependencies { api AndroidX.FragmentKtx api AndroidX.MultiDex + api Android.Material + api Kotlin.Kotlin api Kotlin.CoroutinesCore api Kotlin.CoroutinesAndroid @@ -72,6 +74,7 @@ dependencies { api GitHub.EventBus api GitHub.Bugly api GitHub.PermissionX + api GitHub.SpinKit kapt GitHub.GlideCompiler kapt GitHub.ARouteCompiler diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameActivity.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameActivity.kt index b561403..8b7c476 100644 --- a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameActivity.kt +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameActivity.kt @@ -18,12 +18,12 @@ import java.lang.reflect.ParameterizedType * @Remark: Activity基类 与项目无关 */ abstract class BaseFrameActivity : - AppCompatActivity() { + AppCompatActivity(), FrameView { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { val vbClass: Class = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class - val inflate = vbClass.getMethod("inflate", LayoutInflater::class.java) + val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java) inflate.invoke(null, layoutInflater) as VB } @@ -33,9 +33,6 @@ abstract class BaseFrameActivity : ViewModelProvider(this).get(vmClass) } - protected abstract fun initView() - protected abstract fun initViewObserve() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(mBinding.root) @@ -43,8 +40,9 @@ abstract class BaseFrameActivity : ARouter.getInstance().inject(this) // 注册EventBus if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this) - initView() - initViewObserve() + mBinding.initView() + initLiveDataObserve() + initRequestData() } override fun onDestroy() { diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameFragment.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameFragment.kt index 9924a86..c90dbcc 100644 --- a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameFragment.kt +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameFragment.kt @@ -19,13 +19,12 @@ import java.lang.reflect.ParameterizedType * @Class: BaseFrameFragment * @Remark: Fragment基类 与项目无关 */ -abstract class BaseFrameFragment : - Fragment() { +abstract class BaseFrameFragment : Fragment(), FrameView { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { val vbClass: Class = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class - val inflate = vbClass.getMethod("inflate", LayoutInflater::class.java) + val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java) inflate.invoke(null, layoutInflater) as VB } protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) { @@ -34,9 +33,6 @@ abstract class BaseFrameFragment : ViewModelProvider(this).get(vmClass) } - protected abstract fun initView() - protected abstract fun initViewObserve() - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -51,8 +47,9 @@ abstract class BaseFrameFragment : ARouter.getInstance().inject(this) // 注册EventBus if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this) - initView() - initViewObserve() + mBinding.initView() + initLiveDataObserve() + initRequestData() } override fun onDestroy() { diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMActivity.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMActivity.kt index a2d8cb4..bdf41ca 100644 --- a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMActivity.kt +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMActivity.kt @@ -15,17 +15,16 @@ import java.lang.reflect.ParameterizedType * @Class: BaseFrameNotMVVMActivity * @Remark: 不使用 MVVM 的 Activity 基类 */ -abstract class BaseFrameNotMVVMActivity : AppCompatActivity() { +abstract class BaseFrameNotMVVMActivity : AppCompatActivity(), + FrameNotMVVMView { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { val vbClass: Class = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class - val inflate = vbClass.getMethod("inflate", LayoutInflater::class.java) + val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java) inflate.invoke(null, layoutInflater) as VB } - protected abstract fun initView() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(mBinding.root) @@ -33,7 +32,7 @@ abstract class BaseFrameNotMVVMActivity : AppCompatActivity() ARouter.getInstance().inject(this) // 注册EventBus if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this) - initView() + mBinding.initView() } override fun onDestroy() { diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMFragment.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMFragment.kt index 8d73141..1cc6ee9 100644 --- a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMFragment.kt +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/BaseFrameNotMVVMFragment.kt @@ -17,17 +17,15 @@ import java.lang.reflect.ParameterizedType * @Class: BaseFrameNotMVVMFragment * @Remark: 不使用 MVVM 的 Fragment 基类 */ -abstract class BaseFrameNotMVVMFragment : Fragment() { +abstract class BaseFrameNotMVVMFragment : Fragment(), FrameNotMVVMView { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { val vbClass: Class = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class - val inflate = vbClass.getMethod("inflate", LayoutInflater::class.java) + val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java) inflate.invoke(null, layoutInflater) as VB } - protected abstract fun initView() - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -42,7 +40,7 @@ abstract class BaseFrameNotMVVMFragment : Fragment() { ARouter.getInstance().inject(this) // 注册EventBus if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this) - initView() + mBinding.initView() } override fun onDestroy() { diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameNotMVVMView.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameNotMVVMView.kt new file mode 100644 index 0000000..0cde3a2 --- /dev/null +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameNotMVVMView.kt @@ -0,0 +1,16 @@ +package com.quyunshuo.base.mvvm.v + +import androidx.viewbinding.ViewBinding + +/** + * @Author: QuYunShuo + * @Time: 2020/10/13 + * @Class: FrameNotMVVMView + * @Remark: View层基类抽象 + */ +interface FrameNotMVVMView { + /** + * 初始化View + */ + fun VB.initView() +} \ No newline at end of file diff --git a/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameView.kt b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameView.kt new file mode 100644 index 0000000..b84e9ab --- /dev/null +++ b/Lib_Base/src/main/java/com/quyunshuo/base/mvvm/v/FrameView.kt @@ -0,0 +1,26 @@ +package com.quyunshuo.base.mvvm.v + +import androidx.viewbinding.ViewBinding + +/** + * @Author: QuYunShuo + * @Time: 2020/10/13 + * @Class: FrameView + * @Remark: View层基类抽象 + */ +interface FrameView { + /** + * 初始化View + */ + fun VB.initView() + + /** + * 初始化LiveData的订阅关系 + */ + fun initLiveDataObserve() + + /** + * 初始化界面创建时的数据请求 + */ + fun initRequestData() +} \ No newline at end of file diff --git a/Lib_Base/src/main/res/values/colors.xml b/Lib_Base/src/main/res/values/colors.xml index b7cee75..063b78c 100644 --- a/Lib_Base/src/main/res/values/colors.xml +++ b/Lib_Base/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ - #6200EE - #3700B3 - #03DAC5 + #00CFEB + #00CFEB + #00CFEB \ No newline at end of file diff --git a/app/src/main/res/xml/network_security_config.xml b/Lib_Base/src/main/res/xml/base_network_security_config.xml similarity index 100% rename from app/src/main/res/xml/network_security_config.xml rename to Lib_Base/src/main/res/xml/base_network_security_config.xml diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/bean/TranslationResponse.kt b/Lib_Common/src/main/java/com/quyunshuo/common/bean/TranslationResponse.kt new file mode 100644 index 0000000..f7698f4 --- /dev/null +++ b/Lib_Common/src/main/java/com/quyunshuo/common/bean/TranslationResponse.kt @@ -0,0 +1,18 @@ +package com.quyunshuo.common.bean + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: TranslationResponse + * @Remark: 百度普通翻译Response + */ +data class TranslationResponse( + val from: String, + val to: String, + val trans_result: List +) + +data class TransResult( + val dst: String, + val src: String +) \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/constant/AppConstant.kt b/Lib_Common/src/main/java/com/quyunshuo/common/constant/AppConstant.kt new file mode 100644 index 0000000..4c3ea9b --- /dev/null +++ b/Lib_Common/src/main/java/com/quyunshuo/common/constant/AppConstant.kt @@ -0,0 +1,16 @@ +package com.quyunshuo.common.constant + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: AppConstant + * @Remark: + */ +object AppConstant { + + //百度翻译接口的AppId + const val translationAppId = "20200110000374346" + + //百度翻译接口的密钥 + const val translationSecurityKry = "gExnXw11K8ho50vo4aRm" +} \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/constant/NetUrl.kt b/Lib_Common/src/main/java/com/quyunshuo/common/constant/NetUrl.kt index 266398b..9b507c2 100644 --- a/Lib_Common/src/main/java/com/quyunshuo/common/constant/NetUrl.kt +++ b/Lib_Common/src/main/java/com/quyunshuo/common/constant/NetUrl.kt @@ -6,4 +6,8 @@ package com.quyunshuo.common.constant * @Class: NetUrl * @Remark: 请求公共地址 统一放在此类 */ -object NetUrl \ No newline at end of file +object NetUrl { + + // 百度翻译 + const val translationBaseUrl = "https://api.fanyi.baidu.com/" +} \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/constant/RouteUrl.kt b/Lib_Common/src/main/java/com/quyunshuo/common/constant/RouteUrl.kt index 2d0d113..b0e8317 100644 --- a/Lib_Common/src/main/java/com/quyunshuo/common/constant/RouteUrl.kt +++ b/Lib_Common/src/main/java/com/quyunshuo/common/constant/RouteUrl.kt @@ -6,4 +6,14 @@ package com.quyunshuo.common.constant * @Class: RoutePath * @Remark: 路由地址 */ -object RouteUrl \ No newline at end of file +object RouteUrl { + + // 启动页 + const val SplashActivity = "/Lib_Main/SplashActivity" + + // 首页 + const val MainActivity = "/Lib_Main/MainActivity" + + // 翻译 + const val TranslationActivity = "/Lib_Translation/TranslationActivity" +} \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/net/NetRequest.kt b/Lib_Common/src/main/java/com/quyunshuo/common/net/NetRequest.kt index 47df493..d819225 100644 --- a/Lib_Common/src/main/java/com/quyunshuo/common/net/NetRequest.kt +++ b/Lib_Common/src/main/java/com/quyunshuo/common/net/NetRequest.kt @@ -1,6 +1,7 @@ package com.quyunshuo.common.net import com.quyunshuo.common.net.api.ApiCommonService +import com.quyunshuo.common.net.api.ApiBaiDuTranslationService /** * @Author: QuYunShuo @@ -14,4 +15,9 @@ object NetRequest { val commonService by lazy(mode = LazyThreadSafetyMode.NONE) { NetServiceCreator.create(ApiCommonService::class.java) } + + // 百度翻译接口 + val translationService by lazy(mode = LazyThreadSafetyMode.NONE) { + NetServiceCreator.createBaiDu(ApiBaiDuTranslationService::class.java) + } } \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/net/NetServiceCreator.kt b/Lib_Common/src/main/java/com/quyunshuo/common/net/NetServiceCreator.kt index e825aa0..21cf032 100644 --- a/Lib_Common/src/main/java/com/quyunshuo/common/net/NetServiceCreator.kt +++ b/Lib_Common/src/main/java/com/quyunshuo/common/net/NetServiceCreator.kt @@ -2,6 +2,7 @@ package com.quyunshuo.common.net import com.quyunshuo.base.BaseApplication import com.quyunshuo.base.BuildConfig +import com.quyunshuo.common.constant.NetUrl import com.readystatesoftware.chuck.ChuckInterceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -39,14 +40,30 @@ object NetServiceCreator { .build() } + // App自己的后台 private val retrofit by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { Retrofit.Builder() .baseUrl("") - .addConverterFactory(GsonConverterFactory.create()) // Gson转换器 + .addConverterFactory(GsonConverterFactory.create()) // Gson转换器 .client(okHttpClient) .build() } + // 百度翻译 + private val baiDuTranslationRetrofit by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + Retrofit.Builder() + .baseUrl(NetUrl.translationBaseUrl) + .addConverterFactory(GsonConverterFactory.create()) // Gson转换器 + .client(okHttpClient) + .build() + } + + /** + * 获取百度翻译service动态代理对象 + * @param serviceClass 接口Class对象 + */ + fun createBaiDu(serviceClass: Class): T = baiDuTranslationRetrofit.create(serviceClass) + /** * 获取service动态代理对象 * @param serviceClass 接口Class对象 diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/net/api/ApiBaiDuTranslationService.kt b/Lib_Common/src/main/java/com/quyunshuo/common/net/api/ApiBaiDuTranslationService.kt new file mode 100644 index 0000000..e9de3bd --- /dev/null +++ b/Lib_Common/src/main/java/com/quyunshuo/common/net/api/ApiBaiDuTranslationService.kt @@ -0,0 +1,33 @@ +package com.quyunshuo.common.net.api + +import com.quyunshuo.common.bean.TranslationResponse +import retrofit2.http.GET +import retrofit2.http.Query + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: ApiTranslationService + * @Remark: 百度翻译接口 + */ +interface ApiBaiDuTranslationService { + + /** + * 百度翻译 + * @param translation 需要翻译的文本 + * @param original 源语言 (auto 自动识别) + * @param target 目标语言 + * @param appId 翻译sdk的appId + * @param salt 随机数 + * @param sign 签名 (规则: appId + q + salt + 密钥的MD5值) + */ + @GET("api/trans/vip/translate?") + suspend fun sendBaiDuTranslation( + @Query("q") translation: String, + @Query("from") original: String, + @Query("to") target: String, + @Query("appid") appId: String, + @Query("salt") salt: String, + @Query("sign") sign: String + ): TranslationResponse +} \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/ui/BaseActivity.kt b/Lib_Common/src/main/java/com/quyunshuo/common/ui/BaseActivity.kt index 02ed1cd..ce9039f 100644 --- a/Lib_Common/src/main/java/com/quyunshuo/common/ui/BaseActivity.kt +++ b/Lib_Common/src/main/java/com/quyunshuo/common/ui/BaseActivity.kt @@ -1,7 +1,9 @@ package com.quyunshuo.common.ui +import androidx.annotation.ColorInt import androidx.lifecycle.ViewModel import androidx.viewbinding.ViewBinding +import com.jaeger.library.StatusBarUtil import com.quyunshuo.base.mvvm.v.BaseFrameActivity /** @@ -10,4 +12,12 @@ import com.quyunshuo.base.mvvm.v.BaseFrameActivity * @Class: BaseActivity * @Remark: 项目相关的Activity基类 */ -abstract class BaseActivity : BaseFrameActivity() \ No newline at end of file +abstract class BaseActivity : BaseFrameActivity() { + + /** + * 设置状态栏颜色 + */ + protected fun setStatusBarColor(@ColorInt color: Int) { + StatusBarUtil.setColor(this, color, 0) + } +} \ No newline at end of file diff --git a/Lib_Common/src/main/java/com/quyunshuo/common/utils/MD5.kt b/Lib_Common/src/main/java/com/quyunshuo/common/utils/MD5.kt new file mode 100644 index 0000000..7e22eb0 --- /dev/null +++ b/Lib_Common/src/main/java/com/quyunshuo/common/utils/MD5.kt @@ -0,0 +1,35 @@ +package com.quyunshuo.common.utils + +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: MD5 + * @Remark:百度翻译MD5加密 + */ +object MD5 { + + fun encode(password: String): String { + try { + val instance: MessageDigest = MessageDigest.getInstance("MD5") // 获取md5加密对象 + val digest: ByteArray = + instance.digest(password.toByteArray()) // 对字符串加密,返回字节数组 + val sb = StringBuffer() + for (b in digest) { + val i: Int = b.toInt() and 0xff // 获取低八位有效值 + var hexString = Integer.toHexString(i) // 将整数转化为16进制 + if (hexString.length < 2) { + hexString = "0$hexString" // 如果是一位的话,补0 + } + sb.append(hexString) + } + return sb.toString() + + } catch (e: NoSuchAlgorithmException) { + e.printStackTrace() + } + return "" + } +} diff --git a/Lib_Common/src/main/res/drawable/common_btn.xml b/Lib_Common/src/main/res/drawable/common_btn.xml new file mode 100644 index 0000000..e0cee10 --- /dev/null +++ b/Lib_Common/src/main/res/drawable/common_btn.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Lib_Common/src/main/res/drawable/common_layout_bg.xml b/Lib_Common/src/main/res/drawable/common_layout_bg.xml new file mode 100644 index 0000000..e482ea2 --- /dev/null +++ b/Lib_Common/src/main/res/drawable/common_layout_bg.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Lib_Common/src/main/res/drawable/common_sheet.xml b/Lib_Common/src/main/res/drawable/common_sheet.xml new file mode 100644 index 0000000..b25e244 --- /dev/null +++ b/Lib_Common/src/main/res/drawable/common_sheet.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Lib_Common/src/main/res/drawable/common_translation_btn.xml b/Lib_Common/src/main/res/drawable/common_translation_btn.xml new file mode 100644 index 0000000..7437338 --- /dev/null +++ b/Lib_Common/src/main/res/drawable/common_translation_btn.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Lib_Common/src/main/res/layout/common_loading_layout.xml b/Lib_Common/src/main/res/layout/common_loading_layout.xml new file mode 100644 index 0000000..dbefbe7 --- /dev/null +++ b/Lib_Common/src/main/res/layout/common_loading_layout.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/Lib_Common/src/main/res/values/colors.xml b/Lib_Common/src/main/res/values/colors.xml new file mode 100644 index 0000000..c0fa684 --- /dev/null +++ b/Lib_Common/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #00CFEB + \ No newline at end of file diff --git a/Lib_Common/src/main/res/values/strings.xml b/Lib_Common/src/main/res/values/strings.xml new file mode 100644 index 0000000..e5f8fdc --- /dev/null +++ b/Lib_Common/src/main/res/values/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Lib_Main/.gitignore b/Lib_Main/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/Lib_Main/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/Lib_Main/build.gradle b/Lib_Main/build.gradle new file mode 100644 index 0000000..0e08090 --- /dev/null +++ b/Lib_Main/build.gradle @@ -0,0 +1,5 @@ +apply from: '../moduleBase.gradle' + +android { + resourcePrefix "main_" +} \ No newline at end of file diff --git a/Lib_Main/consumer-rules.pro b/Lib_Main/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/Lib_Main/proguard-rules.pro b/Lib_Main/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/Lib_Main/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/Lib_Main/src/androidTest/java/com/quyunshuo/main/ExampleInstrumentedTest.kt b/Lib_Main/src/androidTest/java/com/quyunshuo/main/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..b670c36 --- /dev/null +++ b/Lib_Main/src/androidTest/java/com/quyunshuo/main/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.quyunshuo.main + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.quyunshuo.main.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/Lib_Main/src/main/AndroidManifest.xml b/Lib_Main/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3121d2d --- /dev/null +++ b/Lib_Main/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainActivity.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainActivity.kt new file mode 100644 index 0000000..ecd6fac --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainActivity.kt @@ -0,0 +1,46 @@ +package com.quyunshuo.main.ui.main + +import com.alibaba.android.arouter.facade.annotation.Route +import com.alibaba.android.arouter.launcher.ARouter +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.quyunshuo.common.constant.RouteUrl +import com.quyunshuo.common.ui.BaseActivity +import com.quyunshuo.main.R +import com.quyunshuo.main.databinding.MainActivityMainBinding + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: MainActivity + * @Remark: 首页 + */ +@Route(path = RouteUrl.MainActivity) +class MainActivity : BaseActivity() { + + override fun MainActivityMainBinding.initView() { + setStatusBarColor(resources.getColor(R.color.common_theme_color)) + val sheetBehavior = + BottomSheetBehavior.from(mBinding.mSelectFunctionLayout.mBottomSheetLayout).apply { + state = BottomSheetBehavior.STATE_HIDDEN + isHideable = true + } + mBinding.mSelectFunctionBtn.setOnClickListener { + if (sheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { + sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + } else { + sheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + } + } + mBinding.mSelectFunctionLayout.mTranslationTv.setOnClickListener { + // 跳转到翻译模块 + ARouter.getInstance() + .build(RouteUrl.TranslationActivity) + .navigation() + sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + } + } + + override fun initLiveDataObserve() {} + + override fun initRequestData() {} +} \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainRepository.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainRepository.kt new file mode 100644 index 0000000..e734316 --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainRepository.kt @@ -0,0 +1,11 @@ +package com.quyunshuo.main.ui.main + +import com.quyunshuo.base.mvvm.m.BaseRepository + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: MainRepository + * @Remark: + */ +class MainRepository : BaseRepository() \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainViewModel.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainViewModel.kt new file mode 100644 index 0000000..c9afa4d --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/main/MainViewModel.kt @@ -0,0 +1,14 @@ +package com.quyunshuo.main.ui.main + +import com.quyunshuo.base.mvvm.vm.BaseViewModel + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: MainViewModel + * @Remark: + */ +class MainViewModel : BaseViewModel() { + + override fun initRepository() = MainRepository() +} \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashActivity.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashActivity.kt new file mode 100644 index 0000000..4465506 --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashActivity.kt @@ -0,0 +1,44 @@ +package com.quyunshuo.main.ui.splash + +import androidx.lifecycle.lifecycleScope +import com.alibaba.android.arouter.facade.annotation.Route +import com.alibaba.android.arouter.launcher.ARouter +import com.quyunshuo.common.constant.RouteUrl +import com.quyunshuo.common.ui.BaseActivity +import com.quyunshuo.main.databinding.MainActivitySplashBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import me.jessyan.autosize.internal.CancelAdapt + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: + * @Remark: + */ +@Route(path = RouteUrl.SplashActivity) +class SplashActivity : BaseActivity(), CancelAdapt { + + override fun MainActivitySplashBinding.initView() { + jumpMain() + } + + /** + * 延时跳转到首页 + */ + private fun jumpMain() { + lifecycleScope.launch(Dispatchers.Default) { + delay(1000L) + ARouter.getInstance() + .build(RouteUrl.MainActivity) + .navigation() + delay(100L) + finish() + } + } + + override fun initLiveDataObserve() {} + + override fun initRequestData() {} +} \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashRepository.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashRepository.kt new file mode 100644 index 0000000..fcbe1ab --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashRepository.kt @@ -0,0 +1,11 @@ +package com.quyunshuo.main.ui.splash + +import com.quyunshuo.base.mvvm.m.BaseRepository + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: SplashRepository + * @Remark: + */ +class SplashRepository : BaseRepository() \ No newline at end of file diff --git a/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashViewModel.kt b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashViewModel.kt new file mode 100644 index 0000000..9b7f58d --- /dev/null +++ b/Lib_Main/src/main/java/com/quyunshuo/main/ui/splash/SplashViewModel.kt @@ -0,0 +1,14 @@ +package com.quyunshuo.main.ui.splash + +import com.quyunshuo.base.mvvm.vm.BaseViewModel + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: SplashViewModel + * @Remark: + */ +class SplashViewModel : BaseViewModel() { + + override fun initRepository() = SplashRepository() +} \ No newline at end of file diff --git a/Lib_Main/src/main/java/debug/AndroidManifest.xml b/Lib_Main/src/main/java/debug/AndroidManifest.xml new file mode 100644 index 0000000..f36e6e0 --- /dev/null +++ b/Lib_Main/src/main/java/debug/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/java/debug/MainApplication.kt b/Lib_Main/src/main/java/debug/MainApplication.kt new file mode 100644 index 0000000..e45ef83 --- /dev/null +++ b/Lib_Main/src/main/java/debug/MainApplication.kt @@ -0,0 +1,11 @@ +package debug + +import com.quyunshuo.common.CommonApplication + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: MainApplication + * @Remark: Main模块作为App时的Application + */ +class MainApplication : CommonApplication() \ No newline at end of file diff --git a/Lib_Main/src/main/res/drawable-xxhdpi/main_splash_bg_img.png b/Lib_Main/src/main/res/drawable-xxhdpi/main_splash_bg_img.png new file mode 100644 index 0000000..4ba6a5d Binary files /dev/null and b/Lib_Main/src/main/res/drawable-xxhdpi/main_splash_bg_img.png differ diff --git a/Lib_Main/src/main/res/drawable/main_splash_bg.xml b/Lib_Main/src/main/res/drawable/main_splash_bg.xml new file mode 100644 index 0000000..dcdb39c --- /dev/null +++ b/Lib_Main/src/main/res/drawable/main_splash_bg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/res/layout/main_activity_main.xml b/Lib_Main/src/main/res/layout/main_activity_main.xml new file mode 100644 index 0000000..fe38ec4 --- /dev/null +++ b/Lib_Main/src/main/res/layout/main_activity_main.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/res/layout/main_activity_splash.xml b/Lib_Main/src/main/res/layout/main_activity_splash.xml new file mode 100644 index 0000000..7a931ae --- /dev/null +++ b/Lib_Main/src/main/res/layout/main_activity_splash.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/res/layout/main_bottom_sheet_layout.xml b/Lib_Main/src/main/res/layout/main_bottom_sheet_layout.xml new file mode 100644 index 0000000..4837ab1 --- /dev/null +++ b/Lib_Main/src/main/res/layout/main_bottom_sheet_layout.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/res/values-v21/styles.xml b/Lib_Main/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000..2cdadc9 --- /dev/null +++ b/Lib_Main/src/main/res/values-v21/styles.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/Lib_Main/src/main/res/values/strings.xml b/Lib_Main/src/main/res/values/strings.xml new file mode 100644 index 0000000..1799bd8 --- /dev/null +++ b/Lib_Main/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + Lib_Main + Welcome to AndroidBaseFrameMVVM! + 选择功能 + Translation + \ No newline at end of file diff --git a/Lib_Main/src/main/res/values/styles.xml b/Lib_Main/src/main/res/values/styles.xml new file mode 100644 index 0000000..40d21cf --- /dev/null +++ b/Lib_Main/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/Lib_Main/src/test/java/com/quyunshuo/main/ExampleUnitTest.kt b/Lib_Main/src/test/java/com/quyunshuo/main/ExampleUnitTest.kt new file mode 100644 index 0000000..e2357c0 --- /dev/null +++ b/Lib_Main/src/test/java/com/quyunshuo/main/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.quyunshuo.main + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/Lib_Translation/.gitignore b/Lib_Translation/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/Lib_Translation/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/Lib_Translation/build.gradle b/Lib_Translation/build.gradle new file mode 100644 index 0000000..f6a21c6 --- /dev/null +++ b/Lib_Translation/build.gradle @@ -0,0 +1,5 @@ +apply from: '../moduleBase.gradle' + +android { + resourcePrefix "translation_" +} \ No newline at end of file diff --git a/Lib_Translation/consumer-rules.pro b/Lib_Translation/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/Lib_Translation/proguard-rules.pro b/Lib_Translation/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/Lib_Translation/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/Lib_Translation/src/androidTest/java/com/quyunshuo/translation/ExampleInstrumentedTest.kt b/Lib_Translation/src/androidTest/java/com/quyunshuo/translation/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..527a77b --- /dev/null +++ b/Lib_Translation/src/androidTest/java/com/quyunshuo/translation/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.quyunshuo.translation + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.quyunshuo.translation.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/Lib_Translation/src/main/AndroidManifest.xml b/Lib_Translation/src/main/AndroidManifest.xml new file mode 100644 index 0000000..55c2034 --- /dev/null +++ b/Lib_Translation/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationActivity.kt b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationActivity.kt new file mode 100644 index 0000000..28270e1 --- /dev/null +++ b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationActivity.kt @@ -0,0 +1,65 @@ +package com.quyunshuo.translation + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.text.InputType +import com.alibaba.android.arouter.facade.annotation.Route +import com.quyunshuo.base.ktx.gone +import com.quyunshuo.base.ktx.toast +import com.quyunshuo.base.ktx.visible +import com.quyunshuo.common.constant.RouteUrl +import com.quyunshuo.common.ui.BaseActivity +import com.quyunshuo.translation.databinding.TranslationActivityTranslationBinding +import kotlinx.android.synthetic.main.translation_activity_translation.* + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: TranslationActivity + * @Remark: 翻译主页 + */ +@Route(path = RouteUrl.TranslationActivity) +class TranslationActivity : + BaseActivity() { + + override fun TranslationActivityTranslationBinding.initView() { + // 设置EditText + mBinding.mEdit.run { + inputType = InputType.TYPE_TEXT_FLAG_MULTI_LINE + isSingleLine = false + setHorizontallyScrolling(false) + } + // 拷贝 + mBinding.mCopyImg.setOnClickListener { + val clipboardManager: ClipboardManager = + getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboardManager.setPrimaryClip(ClipData.newPlainText(mShowTv.text, mShowTv.text)) + toast("已复制") + } + // 清空输入框 + mBinding.mCleanImg.setOnClickListener { mBinding.mEdit.setText("") } + // 翻译按钮监听 + mBinding.mTranslationBtn.setOnClickListener { + if (mEdit.text.toString().isNotEmpty()) { + // 请求翻译 + mViewModel.requestTranslation(mEdit.text.toString()) + } + } + } + + override fun initLiveDataObserve() { + // 观察 ViewModel 的 translationLiveData,当其发生改变时,做出响应 + mViewModel.translationLiveData.observe(this, { mBinding.mShowTv.text = it }) + // Loading 图 + mViewModel.isLoading.observe(this, { + if (it) { + mBinding.mLoadingLayout.visible() + } else { + mBinding.mLoadingLayout.gone() + } + }) + } + + override fun initRequestData() {} +} \ No newline at end of file diff --git a/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationRepository.kt b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationRepository.kt new file mode 100644 index 0000000..c92a543 --- /dev/null +++ b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationRepository.kt @@ -0,0 +1,36 @@ +package com.quyunshuo.translation + +import com.quyunshuo.base.mvvm.m.BaseRepository +import com.quyunshuo.common.constant.AppConstant +import com.quyunshuo.common.net.NetRequest +import com.quyunshuo.common.utils.MD5 + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: TranslationRepository + * @Remark: + */ +class TranslationRepository : BaseRepository() { + + /** + * 获取翻译结果 + * @param original 需要翻译的文本 + */ + fun getTranslation(original: String) = + flowRequest { + // 以当前时间做为随机数 + val sign = System.currentTimeMillis().toString() + // 发起请求 + val response = NetRequest.translationService.sendBaiDuTranslation( + original, + "auto", + "en", + AppConstant.translationAppId, + sign, + MD5.encode("${AppConstant.translationAppId}${original}${sign}${AppConstant.translationSecurityKry}") + ) + // 将翻译结果发射出去 + emit(response.trans_result[0].dst) + } +} \ No newline at end of file diff --git a/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationViewModel.kt b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationViewModel.kt new file mode 100644 index 0000000..157ddc7 --- /dev/null +++ b/Lib_Translation/src/main/java/com/quyunshuo/translation/TranslationViewModel.kt @@ -0,0 +1,54 @@ +package com.quyunshuo.translation + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.quyunshuo.base.mvvm.vm.BaseViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: TranslationViewModel + * @Remark: + */ +class TranslationViewModel : BaseViewModel() { + + override fun initRepository() = TranslationRepository() + + // 私有的可变 LiveData + private val _translationLiveData = MutableLiveData() + + // 对外暴露不可变的 LiveData + + val translationLiveData: LiveData = _translationLiveData + + /** + * 请求翻译 + * @param original 需要翻译的文本 + */ + fun requestTranslation(original: String) { + viewModelScope.launch(Dispatchers.IO) { + mRepository.getTranslation(original) + .onStart { + // 请求开始之前的操作 + isLoading.postValue(true) + } + .catch { + // 捕获并处理上游抛出的异常 + _translationLiveData.postValue("error") + isLoading.postValue(false) + } + .onCompletion { + // 已完成 + isLoading.postValue(false) + } + .collect { + // 获取结果 + _translationLiveData.postValue(it) + } + } + } +} diff --git a/Lib_Translation/src/main/java/debug/AndroidManifest.xml b/Lib_Translation/src/main/java/debug/AndroidManifest.xml new file mode 100644 index 0000000..761b86b --- /dev/null +++ b/Lib_Translation/src/main/java/debug/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib_Translation/src/main/java/debug/TranslationApplication.kt b/Lib_Translation/src/main/java/debug/TranslationApplication.kt new file mode 100644 index 0000000..c54bd64 --- /dev/null +++ b/Lib_Translation/src/main/java/debug/TranslationApplication.kt @@ -0,0 +1,11 @@ +package debug + +import com.quyunshuo.common.CommonApplication + +/** + * @Author: QuYunShuo + * @Time: 2020/8/31 + * @Class: TranslationApplication + * @Remark: Translation模块作为App时的Application + */ +class TranslationApplication : CommonApplication() \ No newline at end of file diff --git a/Lib_Translation/src/main/res/drawable-xxhdpi/translation_clean.png b/Lib_Translation/src/main/res/drawable-xxhdpi/translation_clean.png new file mode 100644 index 0000000..20dc202 Binary files /dev/null and b/Lib_Translation/src/main/res/drawable-xxhdpi/translation_clean.png differ diff --git a/Lib_Translation/src/main/res/drawable-xxhdpi/translation_copy.png b/Lib_Translation/src/main/res/drawable-xxhdpi/translation_copy.png new file mode 100644 index 0000000..618b8b6 Binary files /dev/null and b/Lib_Translation/src/main/res/drawable-xxhdpi/translation_copy.png differ diff --git a/Lib_Translation/src/main/res/layout/translation_activity_translation.xml b/Lib_Translation/src/main/res/layout/translation_activity_translation.xml new file mode 100644 index 0000000..4d72039 --- /dev/null +++ b/Lib_Translation/src/main/res/layout/translation_activity_translation.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + +