Browse Source

fix 导航组件使用优化

RobinTan1024 4 years ago
parent
commit
308fb6337f

+ 1 - 1
app/build.gradle

@@ -3,6 +3,7 @@ plugins {
     id 'kotlin-android'
     id 'kotlin-android-extensions'
     id 'kotlin-kapt'
+    id 'androidx.navigation.safeargs.kotlin'
 }
 
 android {
@@ -54,7 +55,6 @@ dependencies {
     def nav_version = "2.3.2"
     implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
     implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
-    // implementation "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
 
     implementation project(':waynelib_')
 

+ 0 - 23
app/src/main/java/com/doverfuelingsolutions/issp/api/ApiUtil.kt

@@ -1,23 +0,0 @@
-package com.doverfuelingsolutions.issp.api
-
-import com.doverfuelingsolutions.issp.api.dto.DFSResult
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.ResponseBody
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
-
-class ApiUtil {
-
-    companion object {
-
-        private val coroutineScope = CoroutineScope(Dispatchers.IO)
-
-        suspend fun parseResponse(responseBody: ResponseBody) = suspendCoroutine<String> {
-            coroutineScope.launch(Dispatchers.IO) {
-                it.resume(responseBody.string())
-            }
-        }
-    }
-}

+ 55 - 26
app/src/main/java/com/doverfuelingsolutions/issp/api/CloudApi.kt

@@ -21,22 +21,16 @@ import org.json.JSONArray
 import retrofit2.Call
 import retrofit2.Callback
 import retrofit2.Response
-import retrofit2.Retrofit
 import java.io.File
 import kotlin.coroutines.resume
 import kotlin.coroutines.suspendCoroutine
 
 object CloudApi {
 
-    private val retrofit: Retrofit by lazyOf(RetrofitUtil.getGsonBuilder().baseUrl(WayneApiConfig.HOST_BASE).build())
-    private val retrofitAuthBase: Retrofit by lazyOf(RetrofitUtil.getAuthBuilder().baseUrl(WayneApiConfig.HOST_BASE).build())
-    private val retrofitAuthTrx: Retrofit by lazyOf(RetrofitUtil.getAuthBuilder().baseUrl(WayneApiConfig.HOST_TRX).build())
-    private val retrofitAuthConfig: Retrofit by lazyOf(RetrofitUtil.getAuthBuilder().baseUrl(WayneApiConfig.HOST_CONFIG).build())
-
-    private val serviceLogin: ServiceLogin by lazyOf(retrofit.create(ServiceLogin::class.java))
-    private val serviceBase: ServiceBase by lazyOf(retrofitAuthBase.create(ServiceBase::class.java))
-    private val serviceTrx: ServiceTrx by lazyOf(retrofitAuthTrx.create(ServiceTrx::class.java))
-    private val serviceConfig: ServiceConfig by lazyOf(retrofitAuthConfig.create(ServiceConfig::class.java))
+    private var serviceLogin = makeLoginService()
+    private var serviceBase = makeBaseService()
+    private var serviceTrx = makeTrxService()
+    private var serviceConfig = makeConfigService()
 
     suspend fun login(accountName: String, password: String): DFSResult<*> {
         val resultLogin = loginOnly(accountName, password)
@@ -49,6 +43,25 @@ object CloudApi {
         }
     }
 
+    suspend fun barcodeName(id: Int) = suspendCoroutine<DFSResult<ResultBarcode>> {
+        serviceBase.barcodeInfo(id).enqueue(object : Callback<ResultBarcode> {
+            override fun onResponse(call: Call<ResultBarcode>, response: Response<ResultBarcode>) {
+                val code = response.code()
+                val body = response.body()
+                if (code == 200 && body != null) {
+                    it.resume(DFSResult.success(body))
+                    return
+                }
+                it.resume(DFSResult.fail(R.string.req_fail))
+            }
+
+            override fun onFailure(call: Call<ResultBarcode>, t: Throwable) {
+                DFSLog.e(t)
+                it.resume(DFSResult.fail(t.message.toString()))
+            }
+        })
+    }
+
     private suspend fun loginOnly(accountName: String, password: String) = suspendCoroutine<DFSResult<ResultLogin>> {
         serviceLogin.login(accountName, password).enqueue(object : Callback<ResultLogin> {
 
@@ -192,22 +205,38 @@ object CloudApi {
         return DFSResult.fail(R.string.req_fail)
     }
 
-    suspend fun barcodeName(id: Int) = suspendCoroutine<DFSResult<ResultBarcode>> {
-        serviceBase.barcodeInfo(id).enqueue(object : Callback<ResultBarcode> {
-            override fun onResponse(call: Call<ResultBarcode>, response: Response<ResultBarcode>) {
-                val code = response.code()
-                val body = response.body()
-                if (code == 200 && body != null) {
-                    it.resume(DFSResult.success(body))
-                    return
-                }
-                it.resume(DFSResult.fail(R.string.req_fail))
-            }
+    private fun makeLoginService(): ServiceLogin {
+        return RetrofitUtil.getGsonBuilder()
+            .baseUrl(WayneApiConfig.HOST_BASE)
+            .build()
+            .create(ServiceLogin::class.java)
+    }
 
-            override fun onFailure(call: Call<ResultBarcode>, t: Throwable) {
-                DFSLog.e(t)
-                it.resume(DFSResult.fail(t.message.toString()))
-            }
-        })
+    private fun makeBaseService(): ServiceBase {
+        return RetrofitUtil.getAuthBuilder()
+            .baseUrl(WayneApiConfig.HOST_BASE)
+            .build()
+            .create(ServiceBase::class.java)
+    }
+
+    private fun makeTrxService(): ServiceTrx {
+        return RetrofitUtil.getAuthBuilder()
+            .baseUrl(WayneApiConfig.HOST_TRX)
+            .build()
+            .create(ServiceTrx::class.java)
+    }
+
+    private fun makeConfigService(): ServiceConfig {
+        return RetrofitUtil.getAuthBuilder()
+            .baseUrl(WayneApiConfig.HOST_CONFIG)
+            .build()
+            .create(ServiceConfig::class.java)
+    }
+
+    fun regenerateAllService() {
+        serviceLogin = makeLoginService()
+        serviceBase = makeBaseService()
+        serviceTrx = makeTrxService()
+        serviceConfig = makeConfigService()
     }
 }

+ 3 - 4
app/src/main/java/com/doverfuelingsolutions/issp/api/WayneApiConfig.kt

@@ -19,10 +19,10 @@ class WayneApiConfig {
         // 默认值 - 云端
         const val DOMAIN_DEFAULT = "http://ipos.biz"
         const val PORT_BASE_DEFAULT = "8698"
-        private const val HOST_BASE_DEFAULT = "$DOMAIN_DEFAULT:$PORT_BASE_DEFAULT"
         const val PORT_TRX_DEFAULT = "8699"
-        private const val HOST_TRX_DEFAULT = "$DOMAIN_DEFAULT:$PORT_TRX_DEFAULT"
         const val PORT_CONFIG_DEFAULT = "8889"
+        private const val HOST_BASE_DEFAULT = "$DOMAIN_DEFAULT:$PORT_BASE_DEFAULT"
+        private const val HOST_TRX_DEFAULT = "$DOMAIN_DEFAULT:$PORT_TRX_DEFAULT"
         private const val HOST_CONFIG_DEFAULT = "$DOMAIN_DEFAULT:$PORT_CONFIG_DEFAULT"
         // 默认值 - 中控
         const val MIDDLE_IP_DEFAULT = "192.168.1.80"
@@ -32,18 +32,17 @@ class WayneApiConfig {
         const val FUEL_IP_DEFAULT = "192.168.1.88"
         const val FUEL_PORT_DEFAULT = "8384"
 
+        // 实时值
         val HOST_BASE: String get() {
             val domain = SPUtil.getString(SPKeys.SERVER_DOMAIN)
             val port = SPUtil.getString(SPKeys.SERVER_PORT_BASE)
             return if (domain.isEmpty() && port.isEmpty()) HOST_BASE_DEFAULT else "$domain:$port"
         }
-
         val HOST_TRX: String get() {
             val domain = SPUtil.getString(SPKeys.SERVER_DOMAIN)
             val port = SPUtil.getString(SPKeys.SERVER_PORT_TRX)
             return if (domain.isEmpty() && port.isEmpty()) HOST_TRX_DEFAULT else "$domain:$port"
         }
-
         val HOST_CONFIG: String get() {
             val domain = SPUtil.getString(SPKeys.SERVER_DOMAIN)
             val port = SPUtil.getString(SPKeys.SERVER_PORT_CONFIG)

+ 1 - 1
app/src/main/java/com/doverfuelingsolutions/issp/api/dto/DFSResult.kt

@@ -19,7 +19,7 @@ data class DFSResult<T> constructor(
 
         fun <T> fail(msg: String): DFSResult<T> {
             return DFSResult(false, null, when {
-                msg.contains("No address associated with hostname", true) -> StringUtil.get(R.string.network_error)
+                msg.contains("No address associated with hostname", true) -> StringUtil.get(R.string.network_error_host_error)
                 else -> msg
             })
         }

+ 2 - 1
app/src/main/java/com/doverfuelingsolutions/issp/utils/ValidateUtil.kt

@@ -9,7 +9,8 @@ class ValidateUtil {
         private val regexUrl: Regex by lazyOf(Regex("^(https?|ftp|file)://([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)*/?\$"))
 
         fun isIP(ip: String): Boolean = regexIP.matches(ip)
-        fun isPositiveInt(num: String): Boolean = regexPositiveInt.matches(num)
+        private fun isPositiveInt(num: String): Boolean = regexPositiveInt.matches(num)
         fun isUrl(url: String): Boolean = regexUrl.matches(url)
+        fun isPort(port: String): Boolean = isPositiveInt(port) && port.toInt() < 65535
     }
 }

+ 14 - 4
app/src/main/java/com/doverfuelingsolutions/issp/view/MainActivity.kt

@@ -1,8 +1,11 @@
 package com.doverfuelingsolutions.issp.view
 
+import android.content.Context
 import android.os.Bundle
+import android.view.inputmethod.InputMethodManager
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.widget.Toolbar
+import androidx.databinding.DataBindingUtil
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.navigation.NavController
@@ -14,11 +17,11 @@ import androidx.navigation.ui.AppBarConfiguration
 import androidx.navigation.ui.setupWithNavController
 import com.doverfuelingsolutions.issp.R
 import com.doverfuelingsolutions.issp.data.DataStore
+import com.doverfuelingsolutions.issp.databinding.ActivityMainBinding
 import com.doverfuelingsolutions.issp.utils.ActivityUtil
 import com.doverfuelingsolutions.issp.utils.PermissionUtil
 import com.doverfuelingsolutions.issp.utils.StringUtil
 import com.doverfuelingsolutions.issp.utils.log.DFSLog
-import kotlinx.android.synthetic.main.activity_main.*
 
 class MainActivity : AppCompatActivity(), NavController.OnDestinationChangedListener {
 
@@ -29,16 +32,18 @@ class MainActivity : AppCompatActivity(), NavController.OnDestinationChangedList
         navHostFragment.navController
     }
 
+    private lateinit var binding: ActivityMainBinding
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        setContentView(R.layout.activity_main)
+        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
 
         PermissionUtil.requestPermissions(this)
 
-        setSupportActionBar(materialToolbar)
+        setSupportActionBar(binding.materialToolbar)
         mNavController.addOnDestinationChangedListener(this)
         val appBarConfiguration = AppBarConfiguration(mNavController.graph)
-        materialToolbar.setupWithNavController(mNavController, appBarConfiguration)
+        binding.materialToolbar.setupWithNavController(mNavController, appBarConfiguration)
     }
 
     override fun onResume() {
@@ -62,6 +67,11 @@ class MainActivity : AppCompatActivity(), NavController.OnDestinationChangedList
         } else {
             supportActionBar?.show()
         }
+
+        val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+        if (inputMethodManager.isActive) {
+            inputMethodManager.hideSoftInputFromWindow(binding.root.windowToken, 0)
+        }
     }
 
     class GlobalViewModel : ViewModel() {

+ 12 - 11
app/src/main/java/com/doverfuelingsolutions/issp/view/fragment/FragmentLogin.kt

@@ -7,6 +7,7 @@ import android.view.ViewGroup
 import androidx.databinding.DataBindingUtil
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.viewModels
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.lifecycleScope
@@ -28,7 +29,7 @@ class FragmentLogin : Fragment(), View.OnClickListener {
     }
 
     private val globalViewModel: MainActivity.GlobalViewModel by activityViewModels()
-    private val loginViewModel = LoginViewModel()
+    private val loginViewModel: LoginViewModel by viewModels()
 
     private lateinit var binding: FragmentLoginBinding
     private val snackbar: Snackbar by lazy {
@@ -43,17 +44,17 @@ class FragmentLogin : Fragment(), View.OnClickListener {
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
-        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)
-        binding.lifecycleOwner = this
-        binding.viewModel = loginViewModel
-        return binding.root
-    }
+        if (!this::binding.isInitialized) {
+            binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)
+            binding.lifecycleOwner = this
+            binding.viewModel = loginViewModel
 
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        binding.buttonLogin.setOnClickListener(this)
-        binding.buttonPreference.setOnClickListener(this)
-        loginViewModel.accountName.value = DataStore.accountName
-        loginViewModel.password.value = DataStore.password
+            loginViewModel.accountName.value = DataStore.accountName
+            loginViewModel.password.value = DataStore.password
+            binding.buttonLogin.setOnClickListener(this)
+            binding.buttonPreference.setOnClickListener(this)
+        }
+        return binding.root
     }
 
     override fun onClick(v: View?) {

+ 18 - 5
app/src/main/java/com/doverfuelingsolutions/issp/view/fragment/FragmentPreference.kt

@@ -3,19 +3,21 @@ package com.doverfuelingsolutions.issp.view.fragment
 import android.os.Bundle
 import android.text.InputType
 import android.widget.EditText
+import android.widget.Toast
 import androidx.preference.EditTextPreference
 import androidx.preference.Preference
 import androidx.preference.PreferenceFragmentCompat
 import com.doverfuelingsolutions.issp.R
+import com.doverfuelingsolutions.issp.api.CloudApi
+import com.doverfuelingsolutions.issp.utils.StringUtil
 import com.doverfuelingsolutions.issp.utils.ValidateUtil
 import com.doverfuelingsolutions.issp.utils.log.DFSLog
 import com.doverfuelingsolutions.issp.utils.sp.SPKeys
+import com.doverfuelingsolutions.issp.utils.sp.SPUtil
 import com.google.android.material.snackbar.Snackbar
 
 class FragmentPreference : PreferenceFragmentCompat(), EditTextPreference.OnBindEditTextListener, Preference.OnPreferenceChangeListener {
 
-    private val snackbar: Snackbar by lazy { Snackbar.make(requireView(), R.string.blank, 4000) }
-
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
         setPreferencesFromResource(R.xml.root_preferences, rootKey)
 
@@ -35,23 +37,34 @@ class FragmentPreference : PreferenceFragmentCompat(), EditTextPreference.OnBind
     }
 
     override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
+        if (preference == null || newValue == null) return false
+
         val value = newValue.toString()
-        val result = when (preference?.key) {
+        val key = preference.key
+        val result = when (key) {
             SPKeys.SERVER_PORT_BASE,
             SPKeys.SERVER_PORT_TRX,
             SPKeys.SERVER_PORT_CONFIG,
             SPKeys.MIDDLE_PORT,
             SPKeys.MIDDLE_WORKSTATION_ID,
-            SPKeys.FUEL_PORT -> ValidateUtil.isPositiveInt(value)
+            SPKeys.FUEL_PORT -> ValidateUtil.isPort(value)
             SPKeys.FUEL_IP,
             SPKeys.MIDDLE_IP -> ValidateUtil.isIP(value)
             SPKeys.SERVER_DOMAIN -> ValidateUtil.isUrl(value)
             else -> false
         }
-        if (!result) snackbar.setText(R.string.input_not_right).show()
+        if (!result) {
+            Toast.makeText(requireContext(), StringUtil.get(R.string.input_not_right), Toast.LENGTH_LONG).show()
+        }
         return result
     }
 
+    override fun onDetach() {
+        super.onDetach()
+
+        CloudApi.regenerateAllService()
+    }
+
     private fun setNumberInput(key: String): EditTextPreference? {
         val fragment = this@FragmentPreference
         return findPreference<EditTextPreference>(key)?.apply {

+ 37 - 30
app/src/main/res/layout/activity_main.xml

@@ -1,36 +1,43 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    style="@style/match"
-    android:layout_weight="1"
-    android:background="@mipmap/activity_background"
-    android:orientation="vertical"
-    tools:context=".view.MainActivity">
+    xmlns:tools="http://schemas.android.com/tools">
 
-    <com.google.android.material.appbar.AppBarLayout
-        style="@style/fullWidth"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
+    <data>
 
-        <com.google.android.material.appbar.MaterialToolbar
-            android:id="@+id/materialToolbar"
-            style="@style/Widget.MaterialComponents.Toolbar.Primary"
-            android:layout_width="match_parent"
-            android:layout_height="?attr/actionBarSize" />
+    </data>
+
+    <androidx.appcompat.widget.LinearLayoutCompat
+        style="@style/match"
+        android:weightSum="1"
+        android:background="@mipmap/activity_background"
+        android:orientation="vertical"
+        tools:context=".view.MainActivity">
+
+        <com.google.android.material.appbar.AppBarLayout
+            style="@style/fullWidth"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent">
 
-    </com.google.android.material.appbar.AppBarLayout>
+            <com.google.android.material.appbar.MaterialToolbar
+                android:id="@+id/materialToolbar"
+                style="@style/Widget.MaterialComponents.Toolbar.Primary"
+                android:layout_width="match_parent"
+                android:layout_height="?attr/actionBarSize" />
 
-    <androidx.fragment.app.FragmentContainerView
-        android:id="@+id/navActivity"
-        android:name="androidx.navigation.fragment.NavHostFragment"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        app:defaultNavHost="true"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:navGraph="@navigation/nav_main" />
-</androidx.appcompat.widget.LinearLayoutCompat>
+        </com.google.android.material.appbar.AppBarLayout>
+
+        <androidx.fragment.app.FragmentContainerView
+            android:id="@+id/navActivity"
+            android:name="androidx.navigation.fragment.NavHostFragment"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            app:defaultNavHost="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:navGraph="@navigation/nav_main" />
+    </androidx.appcompat.widget.LinearLayoutCompat>
+</layout>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -19,6 +19,7 @@
     <string name="login_tip_detail">请先登录</string>
     <string name="input_not_right">填写数据不正确</string>
     <string name="network_error">网络异常</string>
+    <string name="network_error_host_error">网络异常或者域名不正确</string>
     <string name="data_null">数据为空</string>
     <string name="return_data_error">请求返回数据不正确</string>
     <string name="account_name_password_error">账号名或密码错误</string>

+ 4 - 0
build.gradle

@@ -1,4 +1,5 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
+
 buildscript {
     ext.kotlin_version = "1.4.10"
     repositories {
@@ -9,6 +10,9 @@ buildscript {
         classpath "com.android.tools.build:gradle:4.1.0"
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
+        def nav_version = "2.3.2"
+        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
+
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }