Browse Source

A-Z需求,鸡蛋需求,和其他bug,wifiBug修复提交

zhangshenjie 1 year ago
parent
commit
de7013fbdf
54 changed files with 1565 additions and 116 deletions
  1. 4 0
      BusinessAirFryer/src/main/java/com/develop/airfryer/ui/DevModeView.kt
  2. 2 0
      BusinessCommon/src/main/AndroidManifest.xml
  3. 8 1
      BusinessCommon/src/main/java/com/develop/common/bean/WorkMode.kt
  4. 38 2
      BusinessCommon/src/main/java/com/develop/common/data_repo/db/dao/FoodRecipeDao.kt
  5. 8 1
      BusinessCommon/src/main/java/com/develop/common/ui/CommonBindingActivity.kt
  6. 2 1
      BusinessCommon/src/main/java/com/develop/common/utils/ConfigUtils.kt
  7. 19 0
      BusinessCommon/src/main/java/com/develop/common/utils/StringUtils.java
  8. 12 0
      BusinessCommon/src/main/java/com/develop/common/utils/TimeUtil.kt
  9. 67 0
      BusinessCommon/src/main/java/com/develop/common/widget/EggsItemLayout.kt
  10. 160 0
      BusinessCommon/src/main/java/com/develop/common/widget/EggsSelectorLayout.kt
  11. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_bulb.webp
  12. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_close.webp
  13. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_hard.webp
  14. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_lareg.webp
  15. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_medium.webp
  16. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_small.webp
  17. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_soft.webp
  18. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_waxy_soft.webp
  19. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_hard.webp
  20. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_lareg.webp
  21. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_medium.webp
  22. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_small.webp
  23. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_soft.webp
  24. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_waxy_soft.webp
  25. BIN
      BusinessCommon/src/main/res/drawable-xxxhdpi/ic_egg.webp
  26. 7 0
      BusinessCommon/src/main/res/drawable/bg_grey_button_round20px.xml
  27. 7 0
      BusinessCommon/src/main/res/drawable/bg_red_button_round20px.xml
  28. 7 0
      BusinessCommon/src/main/res/drawable/bg_red_button_round60px.xml
  29. 6 0
      BusinessCommon/src/main/res/drawable/eggs_selector.xml
  30. 36 0
      BusinessCommon/src/main/res/layout/eggs_item_layout.xml
  31. 1 0
      BusinessCommon/src/main/res/layout/home_function_top_bar_view.xml
  32. 21 8
      BusinessCommon/src/main/res/layout/item_home_header.xml
  33. 189 0
      BusinessCommon/src/main/res/layout/pop_eggs_view.xml
  34. 0 1
      BusinessCommon/src/main/res/layout/pop_filter_view.xml
  35. 1 0
      BusinessCommon/src/main/res/values/colors.xml
  36. 2 0
      BusinessCommon/src/main/res/values/dimens.xml
  37. 10 0
      BusinessCommon/src/main/res/values/strings.xml
  38. 65 0
      BusinessMain/src/main/java/com/develop/main/adapter/LetterTextAdapter.kt
  39. 47 24
      BusinessMain/src/main/java/com/develop/main/ui/ModesFragment.kt
  40. 58 1
      BusinessMain/src/main/java/com/develop/main/ui/RecipesFragment.kt
  41. 28 3
      BusinessMain/src/main/java/com/develop/main/viewmodel/HomeViewModel.kt
  42. 22 0
      BusinessMain/src/main/res/layout/item_letter_text.xml
  43. 26 7
      BusinessSetting/src/main/java/com/develop/setting/ui/WifiListActivity.kt
  44. 267 53
      BusinessStep/src/main/java/com/develop/step/ui/ModesDetailActivity.kt
  45. 5 2
      BusinessStep/src/main/java/com/develop/step/ui/recipes_detail/CookDetailDescFragment.kt
  46. 8 1
      BusinessStep/src/main/res/layout/activity_mode_detail.xml
  47. 4 1
      BusinessStep/src/main/res/layout/fragment_detail_cook_desc.xml
  48. 4 1
      app/src/main/java/com/develop/foodcooking/MainActivity.kt
  49. 1 0
      libBase/src/main/AndroidManifest.xml
  50. 2 4
      libBase/src/main/java/com/develop/base/ext/GlobaExt.kt
  51. 284 0
      libBase/src/main/java/com/develop/base/manager/ConnectWifiUtils.java
  52. 134 5
      libBase/src/main/java/com/develop/base/manager/WifiHelp.kt
  53. 1 0
      libBase/src/main/java/com/develop/base/widgets/CommonPopupWindow.java
  54. 2 0
      libBase/src/main/res/values/dimens.xml

+ 4 - 0
BusinessAirFryer/src/main/java/com/develop/airfryer/ui/DevModeView.kt

@@ -3,6 +3,7 @@ package com.develop.airfryer.ui
 import android.content.Context
 import android.content.Intent
 import android.util.AttributeSet
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import androidx.constraintlayout.widget.ConstraintLayout
@@ -14,6 +15,7 @@ import com.kuyuntech.cofarcooking.device.sdk.constant.core.CommonEventTypes
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevModes
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.PotStatus
 import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevCommonEvent
+import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevPromptEvent
 import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevStatusEvent
 import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
 import org.greenrobot.eventbus.Subscribe
@@ -48,6 +50,8 @@ class DevModeView(context: Context, attrs: AttributeSet) : ConstraintLayout(cont
         }
     }
 
+
+
     @Subscribe
     fun onDevModeChange(event: DevCommonEvent){
             if(CommonEventTypes.DEV_MODE_CHANGE == event.type){

+ 2 - 0
BusinessCommon/src/main/AndroidManifest.xml

@@ -2,5 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.develop.common">
 
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.REBOOT" />
 </manifest>

+ 8 - 1
BusinessCommon/src/main/java/com/develop/common/bean/WorkMode.kt

@@ -1,3 +1,10 @@
 package com.develop.common.bean
 
-data class WorkMode(val name: String?, val type: String, val icon: String?,val bg: String?,val devMode:String?,val listShow:Boolean?)
+data class WorkMode(
+    val name: String?,
+    val type: String,
+    val icon: String?,
+    val bg: String?,
+    val devMode: String?,
+    val listShow: Boolean?
+)

+ 38 - 2
BusinessCommon/src/main/java/com/develop/common/data_repo/db/dao/FoodRecipeDao.kt

@@ -16,6 +16,18 @@ interface FoodRecipeDao {
         language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
     ): List<DevRecipe>
 
+
+//    @Query("select * from cc_dev_recipe where lang = :language order by (CASE WHEN name LIKE  :letter  || '%' THEN 1    END)")
+    @Query("select * from cc_dev_recipe where lang = :language  and   name LIKE  :letter  || '%' ")
+    fun queryAllRecipeStartLetter(
+        letter: String,
+        language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
+    ): List<DevRecipe>
+    @Query("select * from cc_dev_recipe where lang = :language and name LIKE '%' || :letter  || '%'")
+    fun queryAllRecipeLetter(
+        letter: String,
+        language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
+    ): List<DevRecipe>
     @Query("select * from cc_dev_recipe where number = :recipeNumber and lang = :language")
     fun queryRecipe(
         recipeNumber: String,
@@ -27,14 +39,38 @@ interface FoodRecipeDao {
        devRecipe: DevRecipe
     )
 
+    @Query("select * from cc_dev_recipe where name LIKE '%' || :name || '%' and lang =:language")
+    fun queryRecipeByName(
+        name: String,
+        language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
+    ): List<DevRecipe>
+
+
     @Query("select * from cc_dev_recipe where recipe_category_number = :categoryNumber and lang = :language ")
     fun queryRecipesByCategory(
         categoryNumber: String,
         language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
     ): List<DevRecipe>
 
-    @Query("select * from cc_dev_recipe where name LIKE '%' || :name || '%' and lang =:language")
-    fun queryRecipeByName(
+
+    @Query("select * from cc_dev_recipe where recipe_category_number = :categoryNumber and lang = :language and   name LIKE  :letter  || '%'")
+    fun queryRecipesByCategoryStartLetter(
+        categoryNumber: String,
+        letter:String,
+        language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
+    ): List<DevRecipe>
+    @Query("select * from cc_dev_recipe where recipe_category_number = :categoryNumber and lang = :language and name LIKE '%' || :letter  || '%'")
+    fun queryRecipesByCategoryLetter(
+        categoryNumber: String,
+        letter:String,
+        language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
+    ): List<DevRecipe>
+//    @Query("select * from cc_dev_recipe where name LIKE '%' || :name || '%' and lang =:language " +
+//            "order by (CASE WHEN name LIKE '%' || :name || '%' THEN 1 WHEN name LIKE '%' || :name || '%' THEN 2 WHEN name LIKE '%' || :name || '%' THEN 3 ELSE 4 END)")
+
+
+    @Query("select * from cc_dev_recipe where name LIKE '%' || :name || '%' and lang =:language order by (CASE WHEN name LIKE  :name  || '%' THEN 1 WHEN name LIKE '%' || :name || '%' THEN 2  ELSE 3 END)")
+    fun queryRecipeName(
         name: String,
         language: String = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN"
     ): List<DevRecipe>

+ 8 - 1
BusinessCommon/src/main/java/com/develop/common/ui/CommonBindingActivity.kt

@@ -269,13 +269,20 @@ abstract class CommonBindingActivity<T : ViewBinding> : BaseBindingActivity<T>()
     @Subscribe
     fun onCookDevMsgEvent(event: DevPromptEvent) {
         Log.d(
-            "设备返回",
+            "TAG 设备返回",
             "msg=>${event.msg}==action=>${event.action}==errorCode=>${CofarSDK.devInfo().errCode}" +
                     "==mode=>${CofarSDK.devInfo().mode.mode}"
         )
+
+        // 打开锅盖锅 msg=>error_pot_clover_tips==action=>show==errorCode=>10==mode=>ADAPTED_COOKING
+
         if (!this.equals(TopResumedAtyHolder.getCurrentActivity())) {
             return
         }
+        //所有模式程序运行结束时没有响三声蜂鸣声提示结果程序
+        if (event.msg == "dev_end_of_run_tips"){
+            CofarSDK.cfgBeep(0,3)
+        }
         //当前errcode不是0,并且提示是程序完成的提示不需要显示
         if (CofarSDK.devInfo().errCode.toInt() != 0 && event.msg == "dev_end_of_run_tips") {
             return

+ 2 - 1
BusinessCommon/src/main/java/com/develop/common/utils/ConfigUtils.kt

@@ -29,12 +29,13 @@ object ConfigUtils {
 
             val fileList = GlobalApp().assets.list("") ?: arrayOf()
             var inputStream: InputStream? = null
+
             if(fileList.contains("config_${brandNum}.json")){
                 inputStream = GlobalApp().assets.open("config_${brandNum}.json")
             }else{
                 inputStream = GlobalApp().assets.open("config.json")
             }
-
+//            inputStream = GlobalApp().assets.open("config_036.json")
 
             val size = inputStream.available()
             val buffer = ByteArray(size)

+ 19 - 0
BusinessCommon/src/main/java/com/develop/common/utils/StringUtils.java

@@ -0,0 +1,19 @@
+package com.develop.common.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StringUtils {
+    //换行处理
+    public static  String getStringWrap(String str){
+        if (str.contains("\n\n")){
+            return str;
+
+        }else {
+            return str.replace("\n", "\n\n");
+
+        }
+    }
+
+
+}

+ 12 - 0
BusinessCommon/src/main/java/com/develop/common/utils/TimeUtil.kt

@@ -21,4 +21,16 @@ object TimeUtil {
             "$mStr:$sStr"
         }
     }
+
+    //获取A-Z的数组
+    fun forLetterList():MutableList<String>{
+        var list = mutableListOf<String>()
+        var input: Char
+        input = 'A'
+        while ( input <= 'Z') {
+            list.add("$input")
+            ++input
+        }
+        return  list
+    }
 }

+ 67 - 0
BusinessCommon/src/main/java/com/develop/common/widget/EggsItemLayout.kt

@@ -0,0 +1,67 @@
+package com.develop.common.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import com.develop.common.R
+import com.develop.common.databinding.EggsItemLayoutBinding
+
+class EggsItemLayout : RelativeLayout {
+    private var binding: EggsItemLayoutBinding
+    private var srcTrue: Int = -1
+    private var srcFalse: Int = -1
+    private var textColorTrue = -1
+    private var textColorFalse = -1
+    private var itemCheck:ItemCheck? = null
+
+    constructor(context: Context?) : super(context) {}
+    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
+    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
+        context,
+        attrs,
+        defStyleAttr
+    )
+
+
+    init {
+        val root = View.inflate(context, R.layout.eggs_item_layout, this)
+        binding = EggsItemLayoutBinding.bind(root)
+
+
+    }
+
+
+    public fun setItemDate(text: String, srcFalse: Int, srcTrue: Int,itemCheck: ItemCheck) {
+        this.srcFalse = srcFalse
+        this.srcTrue = srcTrue
+        this.itemCheck = itemCheck
+        textColorTrue = context.resources.getColor(R.color.white)
+        textColorFalse = context.resources.getColor(R.color.egg_red)
+        binding.eggsItemText.text = text
+        binding.eggsItemImage.setImageResource(srcFalse)
+        binding.eggsItemCheck.setOnCheckedChangeListener { compoundButton, b ->
+                itemCheck.onItemCheck(b)
+        }
+
+    }
+
+    public fun setItemCheck(isCheck: Boolean) {
+        if (isCheck) {
+            binding.eggsItemImage.setImageResource(srcTrue)
+            binding.eggsItemText.setTextColor(textColorTrue)
+        } else {
+            binding.eggsItemImage.setImageResource(srcFalse)
+            binding.eggsItemText.setTextColor(textColorFalse)
+
+        }
+        binding.eggsItemCheck.isChecked = isCheck
+
+    }
+
+    interface ItemCheck{
+        fun onItemCheck(isCheck: Boolean)
+    }
+
+}

+ 160 - 0
BusinessCommon/src/main/java/com/develop/common/widget/EggsSelectorLayout.kt

@@ -0,0 +1,160 @@
+package com.develop.common.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.widget.RadioButton
+import android.widget.RelativeLayout
+import com.develop.common.R
+import com.develop.common.databinding.PopEggsViewBinding
+
+class EggsSelectorLayout : RelativeLayout {
+    private var binding: PopEggsViewBinding
+    private  var  sizelayoutInt : Int = -1
+    private var hardnessInt :Int = -1
+
+    constructor(context: Context?) : super(context) {}
+    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
+    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
+        context,
+        attrs,
+        defStyleAttr
+    )
+
+    init {
+        val root = View.inflate(context, R.layout.pop_eggs_view, this)
+        binding = PopEggsViewBinding.bind(root)
+        var layoutResources = context.resources
+
+        binding.eggsSmall.apply {
+            setItemDate (
+                    layoutResources.getString(R.string.small),
+            R.drawable.eggs_false_small,
+            R.drawable.eggs_true_small,
+            object : EggsItemLayout.ItemCheck {
+                override fun onItemCheck(isCheck: Boolean) {
+                    //radiobutton 选中和不选中回调
+                    if (isCheck){
+                        sizelayoutInt = 1
+                        binding.eggsSmall.setItemCheck(true)
+                        binding.eggsMedium.setItemCheck(false)
+                        binding.eggsLareg.setItemCheck(false)
+                    }
+                }
+
+            })
+        }
+        binding.eggsMedium.apply {
+            setItemDate(
+                layoutResources.getString(R.string.medium),
+                R.drawable.eggs_false_medium,
+                R.drawable.eggs_true_medium,
+                object : EggsItemLayout.ItemCheck {
+                    override fun onItemCheck(isCheck: Boolean) {
+                        //radiobutton 选中和不选中回调
+                        if (isCheck){
+                            sizelayoutInt = 2
+                            binding.eggsSmall.setItemCheck(false)
+                            binding.eggsMedium.setItemCheck(true)
+                            binding.eggsLareg.setItemCheck(false)
+                        }
+                    }
+
+                })
+        }
+        binding.eggsLareg.apply {
+            setItemDate(
+                layoutResources.getString(R.string.lareg),
+                R.drawable.eggs_false_lareg,
+                R.drawable.eggs_true_lareg,
+                object : EggsItemLayout.ItemCheck {
+                    override fun onItemCheck(isCheck: Boolean) {
+                        //radiobutton 选中和不选中回调
+                        if (isCheck){
+                            sizelayoutInt = 3
+                            binding.eggsSmall.setItemCheck(false)
+                            binding.eggsMedium.setItemCheck(false)
+                            binding.eggsLareg.setItemCheck(true)
+                        }
+
+                    }
+
+                })
+        }
+
+        binding.eggsSoft.apply {
+            setItemDate(
+                layoutResources.getString(R.string.soft),
+                R.drawable.eggs_false_soft,
+                R.drawable.eggs_true_soft,
+                object : EggsItemLayout.ItemCheck {
+                    override fun onItemCheck(isCheck: Boolean) {
+                        //radiobutton 选中和不选中回调
+                        if (isCheck){
+                            hardnessInt = 1
+                            binding.eggsSoft.setItemCheck(true)
+                            binding.eggsWaxySoft.setItemCheck(false)
+                            binding.eggsHard.setItemCheck(false)
+                        }
+
+                    }
+
+                })
+        }
+        binding.eggsWaxySoft.apply {
+            setItemDate(
+                layoutResources.getString(R.string.waxy_soft),
+                R.drawable.eggs_false_waxy_soft,
+                R.drawable.eggs_true_waxy_soft,
+                object : EggsItemLayout.ItemCheck {
+                    override fun onItemCheck(isCheck: Boolean) {
+                        //radiobutton 选中和不选中回调
+                        if (isCheck){
+                            hardnessInt = 2
+                            binding.eggsSoft.setItemCheck(false)
+                            binding.eggsWaxySoft.setItemCheck(true)
+                            binding.eggsHard.setItemCheck(false)
+                        }
+
+                    }
+
+                })
+        }
+        binding.eggsHard.apply {
+            setItemDate(
+                layoutResources.getString(R.string.hard),
+                R.drawable.eggs_false_hard,
+                R.drawable.eggs_true_hard,
+                object : EggsItemLayout.ItemCheck {
+                    override fun onItemCheck(isCheck: Boolean) {
+                        //radiobutton 选中和不选中回调
+                        if (isCheck){
+                            hardnessInt = 3
+                            binding.eggsSoft.setItemCheck(false)
+                            binding.eggsWaxySoft.setItemCheck(false)
+                            binding.eggsHard.setItemCheck(true)
+                        }
+
+                    }
+
+                })
+        }
+        binding.eggsBulb.setOnClickListener {
+            binding.eggsMsgLayout.visibility = VISIBLE
+            binding.eggBtnConfirm.visibility = INVISIBLE
+            binding.popEggsLayout.visibility = INVISIBLE
+        }
+        binding.eggsClose.setOnClickListener {
+            binding.eggsMsgLayout.visibility = INVISIBLE
+
+            binding.eggBtnConfirm.visibility = VISIBLE
+            binding.popEggsLayout.visibility = VISIBLE
+        }
+    }
+    public fun getSizeCheckType():Int{
+        return  sizelayoutInt
+    }
+    public fun getHardnessCheckType():Int{
+        return  hardnessInt
+    }
+}

BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_bulb.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_close.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_hard.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_lareg.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_medium.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_small.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_soft.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_false_waxy_soft.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_hard.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_lareg.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_medium.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_small.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_soft.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/eggs_true_waxy_soft.webp


BIN
BusinessCommon/src/main/res/drawable-xxxhdpi/ic_egg.webp


+ 7 - 0
BusinessCommon/src/main/res/drawable/bg_grey_button_round20px.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="@dimen/convert_20px"/>
+    <solid android:color="#F6F0F0"/>
+
+</shape>

+ 7 - 0
BusinessCommon/src/main/res/drawable/bg_red_button_round20px.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="@dimen/convert_20px"/>
+    <solid android:color="@color/egg_red"/>
+
+</shape>

+ 7 - 0
BusinessCommon/src/main/res/drawable/bg_red_button_round60px.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="@dimen/convert_60px"/>
+    <solid android:color="@color/egg_red"/>
+
+</shape>

+ 6 - 0
BusinessCommon/src/main/res/drawable/eggs_selector.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/bg_white_button_round20px" android:state_checked="false" />
+
+    <item android:drawable="@drawable/bg_red_button_round20px" android:state_checked="true" />
+</selector>

+ 36 - 0
BusinessCommon/src/main/res/layout/eggs_item_layout.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tool="http://schemas.android.com/tools"
+    android:id="@+id/eggs_item"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/convert_220px">
+    <RadioButton
+        android:id="@+id/eggs_item_check"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:checked="false"
+        android:background="@drawable/eggs_selector"
+        android:button="@null"
+        >
+    </RadioButton>
+
+    <ImageView
+        android:id="@+id/eggs_item_image"
+        android:layout_width="@dimen/convert_50px"
+        android:layout_height="@dimen/convert_50px"
+        android:layout_centerInParent="true"
+        android:scaleType="center"
+        android:src="@drawable/eggs_false_medium" />
+        <TextView
+            android:id="@+id/eggs_item_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/small"
+            android:textSize="@dimen/convert_20px"
+            android:textColor="@color/egg_red"
+            android:layout_below="@+id/eggs_item_image"
+            android:layout_centerHorizontal="true"
+            />
+</RelativeLayout >

+ 1 - 0
BusinessCommon/src/main/res/layout/home_function_top_bar_view.xml

@@ -101,6 +101,7 @@
         android:textSize="@dimen/convert_30px" />
 
     <com.develop.airfryer.ui.DevModeView
+        android:id="@+id/dev_mode_view"
         android:layout_centerVertical="true"
         android:layout_toStartOf="@id/user_layout"
         android:layout_width="wrap_content"

+ 21 - 8
BusinessCommon/src/main/res/layout/item_home_header.xml

@@ -9,14 +9,27 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <androidx.appcompat.widget.AppCompatTextView
-        android:id="@+id/tv_food_category_name"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/convert_24px"
-        android:layout_marginBottom="@dimen/convert_24px"
-        android:textColor="@color/home_category_title"
-        android:textSize="@dimen/convert_36px" />
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_food_category_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/convert_24px"
+            android:layout_marginBottom="@dimen/convert_24px"
+            android:textColor="@color/home_category_title"
+            android:textSize="@dimen/convert_36px" />
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/letter_rv"
+            android:layout_toRightOf="@+id/tv_food_category_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="@dimen/convert_50px"
+            />
+    </RelativeLayout>
+
 
     <com.develop.common.widget.CommonSearchLayout
         android:id="@+id/common_search_view"

+ 189 - 0
BusinessCommon/src/main/res/layout/pop_eggs_view.xml

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/pop_eggs_all_layout"
+    android:layout_width="wrap_content"
+    android:layout_height="@dimen/convert_710px">
+
+    <LinearLayout
+        android:id="@+id/pop_eggs_layout"
+        android:layout_width="@dimen/convert_880px"
+        android:layout_height="@dimen/convert_660px"
+        android:background="@drawable/bg_grey_button_round20px"
+        android:orientation="vertical"
+        android:visibility="visible">
+
+        <ImageView
+            android:id="@+id/eggs_bulb"
+            android:layout_width="@dimen/convert_40px"
+            android:layout_height="@dimen/convert_40px"
+            android:layout_gravity="right"
+            android:layout_marginTop="@dimen/convert_20px"
+            android:layout_marginRight="@dimen/convert_20px"
+            android:src="@drawable/eggs_bulb" />
+
+        <LinearLayout
+            android:layout_width="@dimen/convert_720px"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/convert_10px"
+                android:text="@string/size_of_the_eggs"
+                android:textColor="@color/auth_rest_pwd"
+                android:textSize="@dimen/convert_28px"
+
+                />
+
+            <LinearLayout
+                android:id="@+id/MapType"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingLeft="@dimen/convert_10px"
+                android:paddingRight="@dimen/convert_10px">
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_small"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1.1" />
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_medium"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1.1" />
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_lareg"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/convert_10px"
+                android:layout_marginTop="@dimen/convert_20px"
+                android:text="@string/how_would_you_like_them"
+                android:textColor="@color/auth_rest_pwd"
+                android:textSize="@dimen/convert_28px"
+
+                />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingLeft="@dimen/convert_10px"
+                android:paddingRight="@dimen/convert_10px">
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_soft"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1.1" />
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_waxy_soft"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1.1" />
+
+                <com.develop.common.widget.EggsItemLayout
+                    android:id="@+id/eggs_hard"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/convert_220px"
+                    android:layout_weight="0.8" />
+            </LinearLayout>
+
+        </LinearLayout>
+
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/eggs_msg_layout"
+        android:layout_width="@dimen/convert_880px"
+        android:layout_height="@dimen/convert_660px"
+        android:orientation="vertical"
+        android:background="@drawable/bg_grey_button_round20px"
+        android:visibility="invisible">
+
+        <ImageView
+            android:id="@+id/eggs_close"
+            android:layout_width="@dimen/convert_30px"
+            android:layout_height="@dimen/convert_30px"
+            android:layout_gravity="right"
+            android:layout_marginTop="@dimen/convert_20px"
+            android:layout_marginRight="@dimen/convert_20px"
+            android:src="@drawable/eggs_close" />
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="@dimen/convert_40px"
+            android:layout_marginTop="@dimen/convert_20px"
+            android:layout_marginRight="@dimen/convert_40px"
+            android:layout_marginBottom="@dimen/convert_10px">
+
+            <TextView
+                android:id="@+id/tv_step_detail"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:lineSpacingExtra="@dimen/convert_30px"
+                android:paddingBottom="@dimen/convert_5px"
+                android:text="MAKES 2 JARS (300 ML EACH) MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)
+
+MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)MAKES 2 JARS (300 ML EACH)"
+                android:textColor="@color/step_detail"
+                android:textSize="@dimen/convert_28px"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+
+                />
+
+        </ScrollView>
+
+    </LinearLayout>
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/egg_btn_confirm"
+        android:layout_width="@dimen/convert_400px"
+        android:layout_height="@dimen/convert_78px"
+        android:background="@drawable/bg_red_button_round60px"
+        android:gravity="center"
+        android:text="@string/confirm"
+        android:textColor="#ffffff"
+        android:textSize="@dimen/convert_28px"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="@dimen/convert_40px_negative"
+        android:layout_alignBottom="@+id/pop_eggs_layout"
+        />
+
+
+</RelativeLayout>

+ 0 - 1
BusinessCommon/src/main/res/layout/pop_filter_view.xml

@@ -9,7 +9,6 @@
         android:id="@+id/triangle"
         android:layout_width="@dimen/convert_70px"
         android:layout_height="@dimen/convert_40px"
-
         android:background="@drawable/sanjiaoxing" />
 
     <androidx.recyclerview.widget.RecyclerView

+ 1 - 0
BusinessCommon/src/main/res/values/colors.xml

@@ -155,4 +155,5 @@
     <color name="view_change">#EE8F08</color>
     <color name="text_hit">#B1B2B2</color>
     <color name="direction_color">#ffffff</color>
+    <color name="egg_red">#B83546</color>
 </resources>

+ 2 - 0
BusinessCommon/src/main/res/values/dimens.xml

@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources>
+    <dimen name="convert_78px_negative">-39.0dp</dimen>
+    <dimen name="convert_40px_negative">-20.0dp</dimen>
     <dimen name="convert_0px">0.0dp</dimen>
     <dimen name="convert_1px">0.5dp</dimen>
     <dimen name="convert_2px">1.0dp</dimen>

+ 10 - 0
BusinessCommon/src/main/res/values/strings.xml

@@ -321,4 +321,14 @@ Nanfang plus client is an online information platform developed and operated by
     <string name="none">None</string>
 
     <string name="please_fill_in_nickname">Please fill in nickname</string>
+    <string name="size_of_the_eggs">SIZE OF THE EGGS</string>
+    <string name="how_would_you_like_them">HOW WOULD YOU LIKE THEM?</string>
+    <string name="small">SMALL</string>
+    <string name="medium">MEDIUM</string>
+    <string name="lareg">LAREG</string>
+    <string name="soft">SOFT</string>
+    <string name="waxy_soft">WAXY SOFT</string>
+    <string name="hard">HARD</string>
+    
+    
 </resources>

+ 65 - 0
BusinessMain/src/main/java/com/develop/main/adapter/LetterTextAdapter.kt

@@ -0,0 +1,65 @@
+package com.develop.main.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.Log
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.develop.main.R
+class LetterTextAdapter:  RecyclerView.Adapter<RecyclerView.ViewHolder>() {
+    private var mDataList = mutableListOf<String>()
+    private lateinit var mContext: Context
+    private  var onIteminterface : onItem? = null;
+    private  var positions :Int = 0;
+    private var notificationPosition :Int = 0;
+    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+        val data = mDataList[position]
+        var text = holder.itemView.findViewById<TextView>(R.id.letter_textview)
+        text.text = data
+        if (position==positions){
+            text.textSize = mContext.resources.getDimension(com.develop.base.R.dimen.convert_20px)
+            text.setTextColor(mContext.resources.getColor(com.develop.common.R.color.color_EE8F08))
+        }else{
+            text.textSize = mContext.resources.getDimension(com.develop.base.R.dimen.convert_15px)
+            text.setTextColor(mContext.resources.getColor(com.develop.common.R.color.color_000000))
+        }
+        text.gravity=Gravity.CENTER
+
+//        holder.itemView.text = data
+        text.setOnClickListener {
+            if (positions!=position){
+                onIteminterface?.onClickStr(data,position)
+            }
+        }
+    }
+
+    fun setData(dataList: List<String>,position: Int,onitem: onItem) {
+        this.onIteminterface = onitem
+        this.positions = position
+        mDataList.clear()
+        mDataList.addAll(dataList)
+        notifyDataSetChanged()
+    }
+    fun  setPosition(position: Int){
+        this.positions = position
+    }
+
+    override fun getItemCount(): Int = mDataList.size
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        mContext = parent.context
+        val view = LayoutInflater.from(mContext).inflate(R.layout.item_letter_text, parent, false)
+        return ViewHolder(view)
+    }
+
+
+    class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!)
+
+    interface onItem{
+        fun onClickStr(str:String,position: Int)
+    }
+}

+ 47 - 24
BusinessMain/src/main/java/com/develop/main/ui/ModesFragment.kt

@@ -2,6 +2,7 @@ package com.develop.main.ui
 
 import android.content.Context
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import android.widget.ImageView
@@ -61,7 +62,7 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
 
     override fun onPostCreateView() {
         super.onPostCreateView()
-        if (isNightTheme()){
+        if (isNightTheme()) {
             binding.bottomView.setGone()
         } else {
             binding.bottomView.setVisible()
@@ -70,33 +71,39 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
     }
 
 
-
-
-
-
-
-
-
-
-
     private fun initView() {
 
         val configJson = ConfigUtils.loadConfig()
-        var modes = configJson?.workModes?.filter { it.devMode == CofarSDK.devInfo().devMode && it.listShow == true }
+        configJson?.workModes?.forEach {
+            Log.d("TAG ModesFragment", "ModesFragment :$it")
+        }
+        var modes =
+            configJson?.workModes?.filter { it.devMode == CofarSDK.devInfo().devMode && it.listShow == true }
 
 
         binding.galleryRecycle.apply {
 
             linear(RecyclerView.HORIZONTAL)
             setup {
-                if (isNightTheme()){
+                if (isNightTheme()) {
                     addType<WorkMode>(R.layout.item_night_mode_card_view)
                     onBind {
                         val model = getModel<WorkMode>()
-                        findView<ImageView>(R.id.iv_icon).background_drawable = resources.getIdentifier(model.icon,"drawable","com.develop.foodcooking")
+                        findView<ImageView>(R.id.iv_icon).background_drawable =
+                            resources.getIdentifier(
+                                model.icon,
+                                "drawable",
+                                "com.develop.foodcooking"
+                            )
                         model.name?.let { it1 ->
                             findView<AppCompatTextView>(R.id.tv_mode_name).updateText(
-                                resources.getString(resources.getIdentifier(it1,"string","com.develop.foodcooking"))
+                                resources.getString(
+                                    resources.getIdentifier(
+                                        it1,
+                                        "string",
+                                        "com.develop.foodcooking"
+                                    )
+                                )
                             )
                         }
                     }
@@ -105,7 +112,10 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
 
                         val devInfo = CofarSDK.devInfo();
 
-                        if( devInfo.status != DevStatus.STOP.toInt() && devInfo.runningInstId != modes?.get(absoluteAdapterPosition)?.type){
+                        if (devInfo.status != DevStatus.STOP.toInt() && devInfo.runningInstId != modes?.get(
+                                absoluteAdapterPosition
+                            )?.type
+                        ) {
                             runningWeightTips()
                             return@onClick
                         }
@@ -113,7 +123,6 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
                         navigateTo(Screens.Cook.COOK_MODES) {
 
 
-
                             val bundle = Bundle()
                             bundle.putString(MODE_TYPE, modes?.get(absoluteAdapterPosition)?.type)
                             with(bundle)
@@ -123,10 +132,21 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
                     addType<WorkMode>(R.layout.item_mode_card_view)
                     onBind {
                         val model = getModel<WorkMode>()
-                        findView<ImageView>(R.id.iv_icon).background_drawable = resources.getIdentifier(model.icon,"drawable","com.develop.foodcooking")
+                        findView<ImageView>(R.id.iv_icon).background_drawable =
+                            resources.getIdentifier(
+                                model.icon,
+                                "drawable",
+                                "com.develop.foodcooking"
+                            )
                         model.name?.let { it1 ->
                             findView<AppCompatTextView>(R.id.tv_mode_name).updateText(
-                                resources.getString(resources.getIdentifier(it1,"string","com.develop.foodcooking"))
+                                resources.getString(
+                                    resources.getIdentifier(
+                                        it1,
+                                        "string",
+                                        "com.develop.foodcooking"
+                                    )
+                                )
                             )
                         }
                     }
@@ -135,7 +155,10 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
 
                         val devInfo = CofarSDK.devInfo();
 
-                        if( devInfo.status != DevStatus.STOP.toInt() && devInfo.runningInstId != modes?.get(absoluteAdapterPosition)?.type){
+                        if (devInfo.status != DevStatus.STOP.toInt() && devInfo.runningInstId != modes?.get(
+                                absoluteAdapterPosition
+                            )?.type
+                        ) {
                             runningWeightTips()
                             return@onClick
                         }
@@ -143,7 +166,6 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
                         navigateTo(Screens.Cook.COOK_MODES) {
 
 
-
                             val bundle = Bundle()
                             bundle.putString(MODE_TYPE, modes?.get(absoluteAdapterPosition)?.type)
                             with(bundle)
@@ -181,19 +203,20 @@ class ModesFragment : CommonBVMFragment<FragmentModesBinding, HomeViewModel>() {
 
         }
     }
-    private  val runningTipsDialog: CancelConfirmDialog = CancelConfirmDialog()
 
+    private val runningTipsDialog: CancelConfirmDialog = CancelConfirmDialog()
 
 
-    fun runningWeightTips(){
+    fun runningWeightTips() {
         runningTipsDialog.dialog?.hide()
         runningTipsDialog.showCancel = false
-        runningTipsDialog.title =  getString(com.develop.common.R.string.running_block_tips)
+        runningTipsDialog.title = getString(com.develop.common.R.string.running_block_tips)
         runningTipsDialog.confirmStr = getString(com.develop.common.R.string.ok)
 
         TopResumedAtyHolder.getCurrentActivity()?.supportFragmentManager?.let {
             runningTipsDialog.showDialog(
-                it,"running_block_tips")
+                it, "running_block_tips"
+            )
         }
     }
 

+ 58 - 1
BusinessMain/src/main/java/com/develop/main/ui/RecipesFragment.kt

@@ -1,6 +1,7 @@
 package com.develop.main.ui
 
 
+import android.annotation.SuppressLint
 import android.graphics.Color
 import android.os.Bundle
 import android.util.Log
@@ -11,6 +12,7 @@ import android.widget.RelativeLayout
 import androidx.appcompat.widget.AppCompatTextView
 import androidx.databinding.ViewDataBinding
 import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import androidx.recyclerview.widget.SimpleItemAnimator
 import com.blankj.utilcode.util.NetworkUtils
@@ -37,8 +39,10 @@ import com.develop.common.event.RefreshStarDataEvent
 import com.develop.common.router.Screens
 import com.develop.common.tag.*
 import com.develop.common.ui.CommonBVMFragment
+import com.develop.common.utils.TimeUtil
 import com.develop.common.widget.*
 import com.develop.main.R
+import com.develop.main.adapter.LetterTextAdapter
 import com.develop.main.databinding.ItemFilterAndSortViewBinding
 import com.develop.main.viewmodel.HomeViewModel
 import com.drake.brv.BindingAdapter
@@ -59,7 +63,7 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
     private var categoryDataList = mutableListOf<DevRecipeCategory>()
     private var sortDataList = mutableListOf<FilterSortModel>()
     private var currentHotWord = ""
-
+    private var letterStringList = mutableListOf<String>()
 
     private val loadingDialog by lazy {
         LoadingDialog()
@@ -68,6 +72,8 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
 
     private var needRefresh = false
     private var fromRefreshEvent = false
+    private var letterStr = "A"
+    private var letterPosition  : Int = -1
 
     private val filterPopupWindow by lazy {
         CommonPopupWindow.ViewBuilder<FilterSortViewLayout>().width(dp417).height(dp549)
@@ -158,6 +164,9 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
 
     private fun initView() {
         sortDataList.addAll(DataFactory.genSortNameList(resources))
+        //添加字母A-Z
+        letterStringList.addAll(TimeUtil.forLetterList())
+
         binding.rv.apply {
             itemAnimator?.changeDuration = 0
             (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
@@ -209,6 +218,8 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
                                 filterSortSearchView?.setGone()
                             }
 
+
+
                             //分类名称
                             val categoryName = model.category
                             val tvCategoryName =
@@ -224,6 +235,41 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
                                 tvCategoryName.setGone()
                             }
 
+                            //20231120新需求 在食谱列表页面分类项所有项加上A-Z排序这一栏,A-Z翻译根据不同语言翻译显示
+                            /**
+                             * 由于刷新列表,需要在再走一遍创建,故写一个letterPosition 记录位置
+                             * */
+                            val letterRv =
+                                findView<RecyclerView>(com.develop.common.R.id.letter_rv)
+                            if (categoryName!=null){
+                                letterRv.setVisible()
+                                letterRv.apply {
+                                    letterRv.layoutManager = LinearLayoutManager(getContext(), RecyclerView.HORIZONTAL, false)
+                                    var letterTextAdapter  = LetterTextAdapter()
+                                    letterTextAdapter.setData(letterStringList, letterPosition,object : LetterTextAdapter.onItem{
+                                        override fun onClickStr(str: String,pos: Int) {
+                                            letterPosition = pos
+                                            viewModel.letter =  str
+                                            //分类数据
+                                            if (viewModel.categoryCode == "all") {
+                                                viewModel.queryLocalRecipes("")
+                                            } else {
+                                                viewModel.queryLocalRecipes(viewModel.categoryCode)
+                                            }
+                                            letterTextAdapter.setPosition(pos)
+                                            letterTextAdapter.notifyDataSetChanged()
+
+
+                                        }
+                                    })
+                                    letterRv.adapter = letterTextAdapter
+                                }
+                            }else{
+                                letterRv.setGone()
+                            }
+
+
+
                             //搜索
                             val commonSearchModel = model.commonSearchModel
                             val commonSearchLayout =
@@ -374,6 +420,7 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
             if (viewModel.recipesType == RecipesType.ONLINE) {
                 viewModel.getOnLineRecipeByHotWordsList(currentHotWord, CategoryType.All)
             } else {
+                //正常搜索
                 viewModel.queryRecipesByHotWord(currentHotWord, CategoryType.All)
             }
         }
@@ -481,6 +528,7 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
             }
             binding.itemLayout.setOnClickListener {
                 if (isFilter) {
+
                     val tempPosition = filterSelectedPos
                     filterSelectedPos = absoluteAdapterPosition
                     adapter.notifyItemChanged(filterSelectedPos)
@@ -693,6 +741,7 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
             }
         }
         if (viewModel.recipesType == RecipesType.ONLINE) {
+
             viewModel.categoryCode = devRecipeCategory.code
             isRefresh = true
             binding.page.resetNoMoreData()
@@ -701,6 +750,10 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
             viewModel.categoryCode = devRecipeCategory.number.toString()
             isRefresh = true
             binding.page.resetNoMoreData()
+            //排序需求,选择分类需要充值A-Z
+            letterPosition = -1
+            letterStr = ""
+            viewModel.letter=""
             if (viewModel.categoryCode == "all") {
                 viewModel.queryLocalRecipes("")
             } else {
@@ -742,9 +795,13 @@ class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewMode
         fromRefreshEvent = false
         viewModel.lastSortedPos = pos
         if (needRefresh) {
+
             if (viewModel.recipesType == RecipesType.ONLINE) {
+                Log.d("TAG updateSortName","ONLINE -:")
                 viewModel.getOnLineRecipeList(viewModel.categoryCode, "")
             } else {
+                Log.d("TAG updateSortName","updateSortName")
+
                 isRefresh = true
                 binding.page.resetNoMoreData()
                 viewModel.queryLocalRecipes(viewModel.categoryCode)

+ 28 - 3
BusinessMain/src/main/java/com/develop/main/viewmodel/HomeViewModel.kt

@@ -44,6 +44,7 @@ class HomeViewModel : BaseViewModel() {
 
     var currCategoryName = globalApp().getString(com.develop.common.R.string.all)
     var categoryCode: String = ""
+    var letter: String = ""
     var recipesType = RecipesType.LOCAL
     var isFromDownloadNewRecipesEntrance = false
     var currentPage = 1
@@ -129,15 +130,37 @@ class HomeViewModel : BaseViewModel() {
             localFavoriteRecipesList =
                 FoodDataProvider.getUserDatabase().userInfoDao().queryFavoriteRecipes(userId)
                     .toMutableList()
+
+            /**
+             * 2023.11.20新需求 A-Z排序 在食谱列表页面分类项所有项加上A-Z排序这一栏
+             * */
+
+
             //获取所有的分类
             totalLocalRecipes =
                 if (categoryNum == globalApp().getString(com.develop.common.R.string.all)) FoodDataProvider.getDatabase()
                     .recipeDao()
-                    .queryAllRecipe().toMutableList() else {
+                    .queryAllRecipeStartLetter(letter).toMutableList() else {
                     //获取当前分类
-                    FoodDataProvider.getDatabase().recipeDao().queryRecipesByCategory(categoryNum)
+                    FoodDataProvider.getDatabase().recipeDao().queryRecipesByCategoryStartLetter(categoryNum,letter)
                         .toMutableList()
                 }
+            totalLocalRecipes.forEach {
+                Log.d("TAG totalLocalRecipes","name :"+it.name)
+            }
+            //如果首字母没有的情况下,再获取包含
+            if (totalLocalRecipes.isEmpty()) {
+                totalLocalRecipes =
+                    if (categoryNum == globalApp().getString(com.develop.common.R.string.all)) FoodDataProvider.getDatabase()
+                        .recipeDao()
+                        .queryAllRecipeLetter(letter).toMutableList() else {
+                        //获取当前分类
+                        FoodDataProvider.getDatabase().recipeDao()
+                            .queryRecipesByCategoryLetter(categoryNum, letter)
+                            .toMutableList()
+                    }
+            }
+
             totalLocalRecipes.sortWith(Comparator { t, t2 ->
                 when (sortedType) {
                     SortedType.Popular -> {
@@ -271,7 +294,7 @@ class HomeViewModel : BaseViewModel() {
         lastSearchCategoryType = categoryType
         scope(Dispatchers.IO) {
             val recipeDao = FoodDataProvider.getDatabase().recipeDao()
-            val recipesList = recipeDao.queryRecipeByName(hotWord)
+            val recipesList = recipeDao.queryRecipeName(hotWord)
             val foodList = mutableListOf<DevRecipe>()
             recipeDao.queryFoodByFoodName(hotWord).forEach {
                 it.recipeNumber?.apply {
@@ -280,6 +303,8 @@ class HomeViewModel : BaseViewModel() {
                     }
                 }
             }
+
+
             recipeCount = recipesList.size
             foodCount = foodList.size
             totalSearchLocalRecipes.addAll(recipesList)

+ 22 - 0
BusinessMain/src/main/res/layout/item_letter_text.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:background="@color/white"
+    >
+
+    <TextView
+        android:id="@+id/letter_textview"
+        android:layout_width="@dimen/convert_55px"
+        android:layout_height="@dimen/convert_55px"
+        android:gravity="center"
+        android:textColor="@color/color_000000"
+        />
+
+
+
+
+</LinearLayout>

+ 26 - 7
BusinessSetting/src/main/java/com/develop/setting/ui/WifiListActivity.kt

@@ -3,6 +3,7 @@ package com.develop.setting.ui
 import android.graphics.Rect
 import android.net.wifi.WifiManager
 import android.os.Bundle
+import android.os.CountDownTimer
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
@@ -48,6 +49,9 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
     private var wifiDataList = mutableListOf<WifiData>()
 
     private var selectedPosition = -1
+
+    private var timer: CountDownTimer? = null
+
     override fun createViewBinding(inflater: LayoutInflater): ActivityWifiListBinding {
         return ActivityWifiListBinding.inflate(inflater)
     }
@@ -79,7 +83,7 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
     private fun initView() {
         isFromMainSetting = intent.extras?.getBoolean(WIFI_FROM_MAIN_SETTING) ?: false
 
-        if (isBrand036I()){
+        if (isBrand036I()) {
             binding.ivBanner.setBackgroundResource(com.develop.common.R.drawable.guide_bg_036i)
             binding.ivLogo.setVisible()
         }
@@ -125,7 +129,8 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
                     wifiContent.setWifiModel(model)
                     wifiContent.onOkClickListener = object : WifiContentView.OnOkClickListener {
                         override fun onOkClick(wifiData: WifiData) {
-                            wifiHelp.connect(wifiData, wifiData.password)
+//                            wifiHelp.connect(wifiData, wifiData.password)
+                            wifiHelp.connectNew(wifiData, wifiData.password)
                         }
 
                         override fun onContentClick(wifiData: WifiData) {
@@ -134,10 +139,10 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
                                 GlobalToast.showToast("connected successfully")
                             } else if (clickModel.password.isNotEmpty()) {
                                 showPlainDialog()
-                                wifiHelp.connect(clickModel, clickModel.password)
+                                wifiHelp.connectNew(clickModel, clickModel.password)
                             } else if (clickModel.isSavePwd) {
                                 showPlainDialog()
-                                wifiHelp.connect(clickModel)
+                                wifiHelp.connect(clickModel, true)
                             } else {
                                 updateSelectionPos(absoluteAdapterPosition)
                             }
@@ -156,6 +161,8 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
                 }
             }
         }.models = wifiDataList
+
+
     }
 
     private fun initListener() {
@@ -184,10 +191,10 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
             dismissPlainDialog()
             if (it == "ERROR") {
                 curWifiData?.apply {
-                    if (password.isNotEmpty()){
-                        wifiHelp.connect(this,password)
+                    if (password.isNotEmpty()) {
+                        wifiHelp.connectNew(this, password)
                     } else {
-                        wifiHelp.connect(this)
+                        wifiHelp.connect(this, true)
                     }
                 }
             } else {
@@ -199,7 +206,11 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
                 wifiDataList.addAll(it)
                 binding.wifiRecycler.models = wifiDataList
                 selectedPosition = -2
+                //重连机制
+//                countDownTimer()
             }
+
+
         }.setWifiStateChangedListener {
             dismissPlainDialog()
         }.setAlreadyConnectionCallback {
@@ -207,6 +218,8 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
         }.setNetworkStateChangedListener {
             dismissPlainDialog()
         }.build()
+
+
     }
 
 
@@ -222,6 +235,9 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
     override fun onDestroy() {
         super.onDestroy()
         wifiHelp.destroy()
+        if (timer != null) {
+            timer?.cancel()
+        }
     }
 
     override fun onResume() {
@@ -256,4 +272,7 @@ class WifiListActivity : CommonBindingActivity<ActivityWifiListBinding>(),
         val deltaHeight = height - viewBottom + requireDistance
         binding.wifiRecycler.scrollY = deltaHeight
     }
+
+
+
 }

+ 267 - 53
BusinessStep/src/main/java/com/develop/step/ui/ModesDetailActivity.kt

@@ -4,7 +4,9 @@ import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.BitmapFactory
 import android.os.Bundle
+import android.os.Handler
 import android.util.Log
+import android.view.Gravity
 import android.view.KeyEvent
 import android.view.KeyEvent.ACTION_DOWN
 import android.view.KeyEvent.ACTION_UP
@@ -12,7 +14,10 @@ import android.view.LayoutInflater
 import android.view.MotionEvent
 import android.view.View
 import android.widget.ImageView
+import android.widget.RelativeLayout
+import androidx.appcompat.widget.AppCompatTextView
 import androidx.core.graphics.drawable.DrawableCompat
+import androidx.databinding.ViewDataBinding
 import com.alibaba.android.arouter.facade.annotation.Route
 import com.bumptech.glide.Glide
 import com.develop.base.ext.background_drawable
@@ -22,8 +27,10 @@ import com.develop.base.ext.setGone
 import com.develop.base.ext.setVisible
 import com.develop.base.ext.src
 import com.develop.base.util.ThreadUtils
+import com.develop.base.widgets.CommonPopupWindow
 import com.develop.common.bean.TuyaEvent
 import com.develop.common.data_repo.db.ModesType
+import com.develop.common.data_repo.db.entity.DevRecipeCategory
 import com.develop.common.dialog.CancelConfirmDialog
 import com.develop.common.event.CookStepEvent
 import com.develop.common.food_sdk.FloatWindowManager
@@ -38,13 +45,17 @@ import com.develop.common.utils.CofarUtils
 import com.develop.common.utils.ConfigUtils
 import com.develop.common.utils.getTimeStr
 import com.develop.common.widget.DirectionView
+import com.develop.common.widget.EggsSelectorLayout
+import com.develop.common.widget.FilterSortViewLayout
 import com.develop.common.widget.RingControlView
 import com.develop.common.widget.TimePickerView
-import com.develop.step.BuildConfig
 import com.develop.step.CookSettingType
 import com.develop.step.R
 import com.develop.step.databinding.ActivityModeDetailBinding
 import com.develop.step.viewmodel.ModesViewMode
+import com.drake.brv.utils.linear
+import com.drake.brv.utils.models
+import com.drake.brv.utils.setup
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.CommonEventTypes
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevModes
 import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevStatus
@@ -99,13 +110,37 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
     private var modeName = ""
     private var opMode = "HAND"
     lateinit var ctx: Context
-
+    private var confirmType: Boolean = false
+    private var eggConfirm: AppCompatTextView? = null
     private val backRequestDialog by lazy {
         CancelConfirmDialog()
     }
     private val overrideModeDialog by lazy {
         CancelConfirmDialog()
     }
+    private val eggsPopupWindow by lazy {
+        CommonPopupWindow.ViewBuilder<EggsSelectorLayout>()
+            .width(RelativeLayout.LayoutParams.WRAP_CONTENT)
+            .height(RelativeLayout.LayoutParams.WRAP_CONTENT)
+            .outsideTouchable(true).focusable(true).alpha(0.5f).clippingEnabled(false)
+            .view(EggsSelectorLayout(this)).intercept { popupWindow, view ->
+            }.onShowBefore { popupWindow, view ->
+                var pop_eggs_all_layout: RelativeLayout =
+                    view.findViewById(com.develop.common.R.id.pop_eggs_all_layout)
+                pop_eggs_all_layout.setOnClickListener {
+//                    popupWindow.dismiss()
+                }
+                eggConfirm = view.findViewById(com.develop.common.R.id.egg_btn_confirm)
+                eggConfirm?.setOnClickListener {
+                    var size = view.getSizeCheckType()
+                    var hardness = view.getHardnessCheckType()
+                    setEggTime(size,hardness)
+                    popupWindow.dismiss()
+                }
+
+
+            }.build<ViewDataBinding>(this)
+    }
 
     override fun createViewModel(): ModesViewMode {
         return getViewModel(ModesViewMode::class.java)
@@ -121,9 +156,14 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
             //隐藏点击
             binding.clCookDirection.visibility = View.GONE;
             binding.clCookSpeed.visibility = View.GONE;
-            binding.clCookWater.visibility = View.VISIBLE
-            binding.ivTurbo.visibility = View.GONE
+            /**
+             * 2023.11.21 空炸部分把喷水功能隐藏
+             * */
+            if (lastModeType == "AF_AIR_FRYER") binding.clCookWater.visibility =
+                View.GONE else binding.clCookWater.visibility = View.VISIBLE
 
+//            binding.clCookWater.visibility = View.VISIBLE
+            binding.ivTurbo.visibility = View.GONE
 
         }
 
@@ -136,6 +176,16 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 
         }
 
+//        if (CofarSDK.devInfo().devMode=="AF_AIR_FRYER"){
+//            binding.clCookDirection.visibility = View.GONE;
+//            binding.clCookSpeed.visibility = View.GONE;
+//            /**
+//             * 2023.11.21 空炸部分把喷水功能隐藏
+//             * */
+//            binding.clCookWater.visibility = View.GONE
+//            binding.ivTurbo.visibility = View.GONE
+//        }
+
     }
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -155,10 +205,12 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         turnDevModeUI();
         viewModel.modeType = intent.extras?.getString(MODE_TYPE, ModesType.CHOP.name) ?: ""
         modeName = intent.extras?.getString("mode_name", "") ?: ""
-        opMode =  intent.extras?.getString("OP_MODE", "HAND") ?: "HAND"
+        opMode = intent.extras?.getString("OP_MODE", "HAND") ?: "HAND"
         viewModel.lastModeType = viewModel.modeType
         lastModeType = viewModel.modeType
         modeType = lastModeType
+
+        Log.d("TAG ModesDetail", "lastModeType :$lastModeType")
         //初始化模式数据
         initModeData(lastModeType)
         initData()
@@ -369,7 +421,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         }
         pressStartTime = -1L
 
-        if (viewModel.modeType  != ModesType.WIGHT.name && viewModel.modeType  != ModesType.TURBO.name && event.keyCode == PRESS_DOWN_KEY_CODE && canStart) {
+        if (viewModel.modeType != ModesType.WIGHT.name && viewModel.modeType != ModesType.TURBO.name && event.keyCode == PRESS_DOWN_KEY_CODE && canStart) {
             //非turbo模式
             if (userChanging && currDevInfo.status.toByte() != DevStatus.STOP) {
                 //用户调节中
@@ -384,7 +436,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                 }
             }
         }
-        if (viewModel.modeType  == ModesType.WIGHT.name) {
+        if (viewModel.modeType == ModesType.WIGHT.name) {
             weightClearClick();
         }
         canStart = true
@@ -393,27 +445,27 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 
 
     @Subscribe
-    fun onTuyaEvent(event:TuyaEvent){
-
-         if("start" == event.type){
-             if(DevStatus.PAUSE.toInt() == CofarSDK.devInfo().status){
-                 CofarSDK.confirm()
-                 resumeClick()
-             }else{
-                 startClick(false)
-             }
-         }
-
-        if("stop" == event.type){
+    fun onTuyaEvent(event: TuyaEvent) {
+
+        if ("start" == event.type) {
+            if (DevStatus.PAUSE.toInt() == CofarSDK.devInfo().status) {
+                CofarSDK.confirm()
+                resumeClick()
+            } else {
+                startClick(false)
+            }
+        }
+
+        if ("stop" == event.type) {
             stopClick(false)
         }
 
-        if("pause" == event.type){
+        if ("pause" == event.type) {
             pauseClick()
         }
 
 
-        if("change_time" == event.type){
+        if ("change_time" == event.type) {
 
             ThreadUtils.runOnMainThread {
                 //当前调节时间
@@ -464,14 +516,14 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                         ":${sec}"
                     }
                 }
-                rollTimeEvent(hour, min, sec, time, setByUser = true)
+                rollTimeEvent(hour, min, sec, time, setByUser = true, "change_time")
                 currDevInfo.apply {
                     updateTimeUI(
                         mode.minTime,
                         mode.maxTime,
                         remainTime,
                         targetTime.toLong(),
-                        true
+                        true, false, "change_time"
                     )
                 }
                 binding.clSetTime.setTimeInternal(
@@ -486,24 +538,23 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         }
 
 
-        if("change_temp" == event.type){
+        if ("change_temp" == event.type) {
 
-            ThreadUtils.runOnMainThread ({
+            ThreadUtils.runOnMainThread({
                 updateTempUI(
                     minTemp.toFloat(),
                     maxTemp.toFloat(),
                     if (currDevInfo.status == DevStatus.STOP.toInt()) currDevInfo.targetTemp.toInt()
                     else currDevInfo.temp.toInt(),
-                    if (currDevInfo.targetTempBuffer.toInt() != -1 ) currDevInfo.targetTempBuffer.toString() else currDevInfo.targetTemp.toString(),
+                    if (currDevInfo.targetTempBuffer.toInt() != -1) currDevInfo.targetTempBuffer.toString() else currDevInfo.targetTemp.toString(),
                     isTempChange,
                     focusUpdate = true
                 )
-            },500)
+            }, 500)
 
         }
 
 
-
     }
 
     //======================================烹饪设备回调监听==================================\\
@@ -516,16 +567,20 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         }
 
         ThreadUtils.runOnMainThread({
+            //currDevInfo.targetTime,
+            // currDevInfo.targetTime.toLong()
+
             if (CommonEventTypes.MOTOR_GEAR_RATHER_THEN_7 == event.type) {
                 CofarSDK.cfgTime((10 * 60))
                 currDevInfo.mode.apply {
                     updateTimeUI(
                         minTime,
                         maxTime,
-                        currDevInfo.targetTime,
-                        currDevInfo.targetTime.toLong(),
+                        if (currDevInfo.status == DevStatus.STOP.toInt()) if (currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer else currDevInfo.targetTime
+                        else currDevInfo.remainTime,
+                        if (currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer.toLong() else currDevInfo.targetTime.toLong(),
                         isTimeChange = true,
-                        focusUpdate = true
+                        focusUpdate = true, "onDevCommonEvent"
                     )
                 }
             }
@@ -575,16 +630,18 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                     maxTemp.toFloat(),
                     if (currDevInfo.status == DevStatus.STOP.toInt()) currDevInfo.targetTemp.toInt()
                     else currDevInfo.temp.toInt(),
-                    if (currDevInfo.targetTempBuffer.toInt() != -1 ) currDevInfo.targetTempBuffer.toString() else currDevInfo.targetTemp.toString(),
+                    if (currDevInfo.targetTempBuffer.toInt() != -1) currDevInfo.targetTempBuffer.toString() else currDevInfo.targetTemp.toString(),
                     isTempChange
                 )
+
+
                 updateTimeUI(
                     if (currDevInfo.status == DevStatus.STOP.toInt() || userChanging) minTime else 0,
                     maxTime,
-                    if (currDevInfo.status == DevStatus.STOP.toInt()) if(currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer else  currDevInfo.targetTime
+                    if (currDevInfo.status == DevStatus.STOP.toInt()) if (currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer else currDevInfo.targetTime
                     else currDevInfo.remainTime,
-                    if(currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer.toLong() else  currDevInfo.targetTime.toLong(),
-                    isTimeChange
+                    if (currDevInfo.targetTimeBuffer != -1) currDevInfo.targetTimeBuffer.toLong() else currDevInfo.targetTime.toLong(),
+                    isTimeChange, false, "onDevStateEvent"
                 )
                 var motorGear = currDevInfo.motorGear.toInt()
                 if (currDevInfo.motorGearBuffer.toInt() != -1) {
@@ -704,6 +761,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 
     private fun initModeData(type: String, keep: Boolean = false) {
 
+        Log.d("TAG initModeData", "viewModel.modeType:" + viewModel.modeType)
         viewModel.modeType.apply {
             val baseMode = CofarSDK.devMode(this)
             //显示对应模式UI
@@ -728,7 +786,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                 this@ModesDetailActivity.isMotorDirectionGearChange =
                     baseMode.isMotorDirectionChange
                 if (CofarSDK.devInfo().status != DevStatus.PAUSE.toInt() && CofarSDK.devInfo().status != DevStatus.RUNNING.toInt()) {
-
+                    Log.d("TAG initModeData", "baseMode :" + baseMode.toString())
                     var targetTemp = baseMode.defaultTemp.toShort()
                     var motorDirection = baseMode.motorDirection.toByte()
                     var motorGear = baseMode.defaultMotorGear.toByte()
@@ -758,6 +816,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 //                        targetTime = baseMode.defaultTime.toInt()
 //                    }
 
+                    Log.d("TAG initModeData", "baseMode class :" + baseMode.javaClass.name)
 
                     baseMode.apply {
                         currentTemp = targetTemp.toInt()
@@ -771,13 +830,14 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                         )
 
                         currTime = targetTime.toLong()
+
                         updateTimeUI(
                             minTime,
                             maxTime,
                             currTime.toInt(),
                             targetTime.toLong(),
                             isTimeChange,
-                            true
+                            true, "initModeData"
                         )
 
                         currentMotorGer = defaultMotorGear
@@ -826,6 +886,12 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 
         binding.ivTurbo.setOnClickListener {
             turboClick()
+
+
+        }
+        binding.ivEggs.setOnClickListener {
+            eggsPopupWindow.showAtLocation(binding.titleLayout, Gravity.CENTER, 0, 0)
+
         }
 
         binding.ivWeight.setOnClickListener {
@@ -977,7 +1043,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
             ) {
                 if (setByUser) {
                     //  currTime = time.toLong()
-                    rollTimeEvent(hours, minute, second, time, setByUser)
+                    rollTimeEvent(hours, minute, second, time, setByUser, "rCallback")
                 }
 
             }
@@ -1032,6 +1098,8 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         if (viewModel.modeType == ModesType.WIGHT.name || viewModel.modeType == ModesType.TURBO.name) {
             binding.ivWeight.visibility = View.GONE
             binding.ivTurbo.visibility = View.GONE
+            //设置鸡蛋
+            visibilityEgg(View.GONE)
             if (viewModel.modeType == ModesType.TURBO.name) {
                 Log.d("dddddd", "llTurboView===VISIBLE")
                 binding.llTurboView.visibility = View.VISIBLE
@@ -1040,6 +1108,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
 //            isWidget = true
             binding.ivWeight.visibility = View.VISIBLE
             binding.ivTurbo.visibility = View.VISIBLE
+            visibilityEgg(View.VISIBLE)
         }
         turnDevModeUI()
         changeTempSettingStep()
@@ -1052,6 +1121,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         isWidget = false
         binding.ivWeight.visibility = View.GONE
         binding.ivTurbo.visibility = View.GONE
+        visibilityEgg(View.GONE)
         binding.functionLayout.visibility = View.GONE
         binding.llWeightView.visibility = View.VISIBLE
         Log.d("dddddd", "llTurboView===GONE")
@@ -1067,6 +1137,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         isWidget = false
         binding.ivWeight.visibility = View.GONE
         binding.ivTurbo.visibility = View.GONE
+        visibilityEgg(View.GONE)
         binding.functionLayout.visibility = View.GONE
         Log.d("dddddd", "llTurboView===VISIBLE")
         binding.llTurboView.visibility = View.VISIBLE
@@ -1292,14 +1363,14 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                     ":${sec}"
                 }
             }
-            rollTimeEvent(hour, min, sec, time, setByUser = true)
+            rollTimeEvent(hour, min, sec, time, setByUser = true, "TimeChange")
             currDevInfo.apply {
                 updateTimeUI(
                     mode.minTime,
                     mode.maxTime,
                     remainTime,
                     targetTime.toLong(),
-                    true
+                    true, false, "TimeChange"
                 )
             }
             binding.clSetTime.setTimeInternal(
@@ -1381,9 +1452,12 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         remainTime: Int,
         targetTime: Long,
         isTimeChange: Boolean,
-        focusUpdate: Boolean = false,
+        focusUpdate: Boolean = false, type: String
     ) {
 
+
+//        Log.d("TAG updateTimeUI","minTime:$minTime   maxTime:$maxTime  remainTime:$remainTime  targetTime:$targetTime    type :$type")
+
         this.isTimeChange = isTimeChange
         this.maxTime = maxTime.toLong()
         this.minTime = minTime.toLong()
@@ -1392,15 +1466,28 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
             var hours = 0
             var minute = 0
             var sec = 0
-            if (remainTime > 3600) {
-                hours = remainTime / 3600
-                minute = remainTime % 3600 / 60
+
+            /**
+             * 由于速度大于7或等于7的时候 ,SDK会回调onDevCommonEvent方法,这个方法focusUpdate传入true,
+             * 就会调用下面if方法,故下面clSetTime.setTimeInternal,由于之前的minute  sec 方法计算错误,现特殊处理minute  sec 计算
+             * */
+            if (type == "onDevCommonEvent") {
+                minute = (targetTime / 60).toInt()
+                sec = (targetTime % 60).toInt()
             } else {
-                minute = remainTime / 60
-                sec = remainTime % 60
+                if (remainTime > 3600) {
+                    hours = remainTime / 3600
+                    minute = remainTime % 3600 / 60
+                } else {
+                    minute = remainTime / 60
+                    sec = remainTime % 60
+                }
             }
+
+
             clSetTime.isTimeCanChange(isTimeChange)
             clSetTime.setTimeRange(minTime, maxTime)
+
             if (!userChanging || focusUpdate) {
                 clCookTime.setConfigValue("--${getTimeStr(targetTime)}--")
                 clSetTime.setTimeInternal(hours, minute, sec, true)
@@ -1556,25 +1643,37 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
                 binding.apply {
                     ivWeight.visibility = View.GONE
                     ivTurbo.visibility = View.GONE
+                    ivEggs.visibility = View.GONE
                     btnStart.visibility = View.INVISIBLE
                     btnStop.visibility = View.VISIBLE
                     btnResume.visibility = View.INVISIBLE
                     btnPause.visibility = View.VISIBLE
                     btnReset.visibility = View.INVISIBLE
+                    //2023.11.21 运行过程中暂停,修改参数之后点一次就启动 处理标识
+                    confirmType = false
                 }
             }
 
             DevStatus.PAUSE -> {
+                /**
+                 * 2023.11.21 运行过程中暂停,修改参数之后点一次就启动
+                 * 由于调用resume 会触发 updateStatusBtn ,会导致按钮显示一下在隐藏
+                 * 故写一个confirmType来辨别是confirmClick 点击
+                 * 逻辑走后,需要在runing 重新设置 confirmType设置false
+                 * */
                 binding.apply {
                     ivWeight.visibility = View.VISIBLE
                     ivTurbo.visibility = View.GONE
                     btnStart.visibility = View.INVISIBLE
-                    btnResume.visibility = View.VISIBLE
+                    if (confirmType) btnResume.visibility =
+                        View.INVISIBLE else btnResume.visibility = View.VISIBLE
+//                    btnResume.visibility = View.VISIBLE
                     btnPause.visibility = View.INVISIBLE
                     btnStop.visibility = View.VISIBLE
                     btnCancel.visibility = View.INVISIBLE
                     btnConfirm.visibility = View.INVISIBLE
                     btnReset.visibility = View.INVISIBLE
+
                 }
             }
 
@@ -1618,23 +1717,30 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
     /**
      * 点击开始操作
      */
-    private fun startClick(showStopTips:Boolean=true) {
+    private fun startClick(showStopTips: Boolean = true) {
         if (mRunningInstId != mSettingInstId) {
             overrideModeDialog.showDialog(supportFragmentManager, "overrideModeDialog")
         } else {
+
+            //煮鸡蛋前需要设置时间,由于SDK没有设置转速,我这边用转速判断  COOK_EGGS 这里需要空格,sdk里面判断加了个空格
+            if ("COOK_EGGS " == viewModel.modeType && currDevInfo.motorGear.toInt() == 0) {
+                overrideModeDialog.showDialog(supportFragmentManager, "overrideModeDialog")
+                return
+            }
+
             userChanging = false
             CofarSDK.cancel()
             CofarSDK.devInfo().runningRecipeId = null
             var startConfig = HashMap<String, Any>()
-            startConfig.put("stopTips",showStopTips)
-            CofarSDK.startWithConfig(viewModel.modeType,startConfig)
+            startConfig.put("stopTips", showStopTips)
+            Log.e("TAG startClick", " viewModel.modeType:" + viewModel.modeType)
+            CofarSDK.startWithConfig(viewModel.modeType, startConfig)
             whereIndex = -1
             binding.clSetTime.stopAlphaAnim()
         }
     }
 
 
-
     /**
      * 点击恢复操作
      */
@@ -1666,6 +1772,20 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         CofarSDK.confirm()
         binding.btnCancel.visibility = View.GONE
         binding.btnConfirm.visibility = View.GONE
+
+        /**
+         * 2023.11.21 运行过程中暂停,修改参数之后点一次就启动
+         * 由于调用resume 会触发 updateStatusBtn ,会导致按钮显示一下在隐藏
+         * 故写一个confirmType来辨别是confirmClick 点击
+         * */
+        confirmType = true //确定是 confirm
+        binding.btnResume.visibility = View.INVISIBLE
+        userChanging = false
+        Handler().postDelayed({
+            CofarSDK.resume()
+        }, 200)
+
+
     }
 
     private fun resetConfigClick() {
@@ -1677,7 +1797,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
     /**
      * 点击停止操作
      */
-    private fun stopClick(tips:Boolean = true) {
+    private fun stopClick(tips: Boolean = true) {
         userChanging = false
         //结束
         CofarSDK.stop(tips)
@@ -1709,6 +1829,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         initModeData(viewModel.modeType)
         viewModel.changeStep(CookSettingType.WEIGHT)
         binding.ivTurbo.visibility = View.GONE
+        visibilityEgg(View.GONE)
         isWidget = false
         binding.ivWeight.visibility = View.GONE
         binding.tvModeName.text = viewModel.getModeTitle(resources)
@@ -1729,6 +1850,7 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         viewModel.changeStep(CookSettingType.TURBO)
         binding.tvModeName.text = viewModel.getModeTitle(resources)
         binding.ivTurbo.visibility = View.GONE
+        visibilityEgg(View.GONE)
         isWidget = false
         binding.ivWeight.visibility = View.GONE
         Log.d("dddddd", "llTurboView===VISIBLE")
@@ -1864,8 +1986,9 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
      * 滑动时间事件
      */
     private fun rollTimeEvent(
-        hours: Int, minute: Int, second: Int, time: String, setByUser: Boolean
+        hours: Int, minute: Int, second: Int, time: String, setByUser: Boolean, type: String
     ) {
+
         if (setByUser) {
             userChanging = true
             binding.clCookTime.setConfigValue("--${time}--")
@@ -1890,4 +2013,95 @@ class ModesDetailActivity : CommonBVMActivity<ActivityModeDetailBinding, ModesVi
         binding.ivTurboView.src = com.develop.common.R.drawable.ic_turbo_unselected
         viewModel.stopTurbo()
     }
+
+    private fun setEggTime(size: Int, hardness: Int) {
+        var time: Int = 0
+        when (size) {
+            1 -> {//小
+                when (hardness) {
+                    1 -> {//软
+                        time = 8*60
+                    }
+
+                    2 -> {//中
+                        time = 9*60
+                    }
+
+                    3 -> {//硬
+                        time = 15*60
+                    }
+
+                    else -> {
+                        time = 0
+                    }
+
+                }
+
+            }
+
+            2 -> {//中
+                when (hardness) {
+                    1 -> {//软
+                        time = 10*60
+
+                    }
+
+                    2 -> {//中
+                        time = 12*60
+                    }
+
+                    3 -> {//硬
+                        time = 18*60
+                    }
+
+                    else -> {
+                        time = 0
+                    }
+
+                }
+            }
+
+            3 -> {//大
+                when (hardness) {
+                    1 -> {//软
+                        time = 11*60
+                    }
+
+                    2 -> {//中
+                        time = 13*60
+                    }
+
+                    3 -> {//硬
+                        time = 18*60
+                    }
+
+                    else -> {
+                        time = 0
+                    }
+
+                }
+
+            }
+
+            else -> {
+                time = 0
+            }
+        }
+        if (time ==0){
+            return
+        }
+        //确认
+        userChanging = false
+
+        CofarSDK.cfgMotorGear(1)
+        CofarSDK.cfgTime(time)
+        CofarSDK.confirm()
+    }
+    private fun  visibilityEgg(visibility :Int){
+        if ("COOK_EGGS " == viewModel.modeType) {
+            binding.ivEggs.visibility = visibility
+        }else{
+            binding.ivEggs.visibility = View.GONE
+        }
+    }
 }

+ 5 - 2
BusinessStep/src/main/java/com/develop/step/ui/recipes_detail/CookDetailDescFragment.kt

@@ -1,9 +1,10 @@
 package com.develop.step.ui.recipes_detail
 
-import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import com.develop.common.ui.CommonBVMFragment
+import com.develop.common.utils.StringUtils
 import com.develop.step.databinding.FragmentDetailCookDescBinding
 import com.develop.step.viewmodel.CookDetailViewModel
 
@@ -23,7 +24,9 @@ class CookDetailDescFragment :
     override fun onPostCreateView() {
         super.onPostCreateView()
         viewModel.getRecipeLiveData().observe(viewLifecycleOwner) {
-            binding.tvStepDetail.text = it.recipe.introduction
+            //食谱总步骤内容过于密集显示,需要分段显示
+//            binding.tvStepDetail.text = it.recipe.introduction
+            binding.tvStepDetail.text = StringUtils.getStringWrap(it.recipe.introduction)
         }
     }
 }

+ 8 - 1
BusinessStep/src/main/res/layout/activity_mode_detail.xml

@@ -62,7 +62,14 @@
             android:layout_marginEnd="@dimen/convert_40px"
             android:layout_toStartOf="@id/iv_weight"
             android:background="@drawable/ic_turbo" />
-
+        <ImageView
+            android:id="@+id/iv_eggs"
+            android:layout_width="@dimen/convert_60px"
+            android:layout_height="@dimen/convert_60px"
+            android:layout_marginTop="@dimen/convert_28px"
+            android:layout_marginEnd="@dimen/convert_40px"
+            android:layout_toStartOf="@id/iv_turbo"
+            android:background="@drawable/ic_egg" />
 
 
     </RelativeLayout>

+ 4 - 1
BusinessStep/src/main/res/layout/fragment_detail_cook_desc.xml

@@ -14,8 +14,11 @@
         android:text="MAKES 2 JARS (300 ML EACH)"
         android:textSize="@dimen/convert_28px"
         android:textColor="@color/step_detail"
+        android:paddingBottom="@dimen/convert_5px"
         android:lineSpacingExtra="@dimen/convert_30px"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"/>
+        app:layout_constraintTop_toTopOf="parent"
+
+        />
 
 </ScrollView>

+ 4 - 1
app/src/main/java/com/develop/foodcooking/MainActivity.kt

@@ -33,7 +33,10 @@ class MainActivity : CommonBindingActivity<ActivityMainBinding>() {
         if (MMkvUtils.getBool(FIRST_IN)) {
             navigateTo(Screens.Main.ENTRANCE_CHOSEN)
         } else {
-            navigateTo(Screens.Setting.ANIMATION)
+            //机器首次开机时会出现两段开机动画,这样给用户的感觉开机时长太长了,因此决定去掉后面apk显示的那一段开机动画
+//            navigateTo(Screens.Setting.ANIMATION)
+            navigateTo(Screens.Main.ENTRANCE_CHOSEN)
+
         }
 //        this.initSDK()
         //初始化涂鸦

+ 1 - 0
libBase/src/main/AndroidManifest.xml

@@ -3,5 +3,6 @@
     package="com.develop.base">
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
 </manifest>

+ 2 - 4
libBase/src/main/java/com/develop/base/ext/GlobaExt.kt

@@ -20,9 +20,6 @@ import androidx.core.content.ContextCompat
 import com.bumptech.glide.Glide
 import com.bumptech.glide.load.engine.DiskCacheStrategy
 import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
-import com.bumptech.glide.request.target.BitmapImageViewTarget
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.transition.Transition
 import com.develop.base.app.BaseApp
 import com.develop.base.util.MMkvUtils
 import kotlinx.serialization.decodeFromString
@@ -188,7 +185,7 @@ fun getBrandNum(): String {
  */
 fun getSN(): String {
     var serial: String
-
+//    return "000A30150020123010190001"
     //通过反射获取sn号
     try {
         val c = Class.forName("android.os.SystemProperties")
@@ -201,6 +198,7 @@ fun getSN(): String {
     } catch (e: java.lang.Exception) {
         serial = "unknown"
     }
+
     return serial
 }
 

+ 284 - 0
libBase/src/main/java/com/develop/base/manager/ConnectWifiUtils.java

@@ -0,0 +1,284 @@
+package com.develop.base.manager;
+
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiNetworkSpecifier;
+import android.net.wifi.WifiNetworkSuggestion;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConnectWifiUtils {
+    private static final String TAG = ConnectWifiUtils.class.getSimpleName();
+
+    private final ConnectivityManager connectivityManager;//连接管理者
+
+    private final WifiManager wifiManager;//Wifi管理者
+
+    private WifiConnectCallback wifiConnectCallback;
+
+    @SuppressLint("StaticFieldLeak")
+    private static volatile ConnectWifiUtils mInstance;
+
+    private final Context mContext;
+
+    public ConnectWifiUtils(Context context) {
+        mContext = context;
+        wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    public static ConnectWifiUtils initialize(Context context) {
+        if (mInstance == null) {
+            synchronized (ConnectWifiUtils.class) {
+                if (mInstance == null) {
+                    mInstance = new ConnectWifiUtils(context);
+                }
+            }
+        }
+        return mInstance;
+    }
+
+    public void setWifiConnectCallback(WifiConnectCallback wifiConnectCallback) {
+        this.wifiConnectCallback = wifiConnectCallback;
+    }
+
+    /**
+     * 连接Wifi
+     *
+     * @param scanResult 扫描结果
+     * @param password   密码
+     */
+    public void connectWifi(WifiData scanResult, String password) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            connectBySug(scanResult.getSsid(), password);
+
+        } else {
+            connectByOld(scanResult, password);
+        }
+    }
+
+    /**
+     * Android 10 以下使用
+     *
+     * @param scanResult 扫描结果
+     * @param password   密码
+     */
+    private void connectByOld(WifiData scanResult, String password) {
+        String ssid = scanResult.getSsid();
+        boolean isSuccess;
+        WifiConfiguration configured = isExist(ssid);
+        if (configured != null) {
+            //在配置表中找到了,直接连接
+            isSuccess = wifiManager.enableNetwork(configured.networkId, true);
+        } else {
+            WifiConfiguration wifiConfig = createWifiConfig(ssid, password, scanResult.getCapabilities());
+            int netId = wifiManager.addNetwork(wifiConfig);
+            isSuccess = wifiManager.enableNetwork(netId, true);
+        }
+        Log.d(TAG, "connectWifi: " + (isSuccess ? "成功" : "失败"));
+    }
+
+    /**
+     * Android 10及以上版本使用此方式连接Wifi
+     *
+     * @param ssid     名称
+     * @param password 密码
+     */
+    @SuppressLint("NewApi")
+    private void connectByNew(String ssid, String password) {
+
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
+                .setSsid(ssid)
+                .setWpa2Passphrase(password)
+                .build();
+        //网络请求
+        NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+                .setNetworkSpecifier(wifiNetworkSpecifier)
+                .build();
+        //网络回调处理
+        ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
+            @Override
+            public void onAvailable(@NonNull Network network) {
+                super.onAvailable(network);
+                if (wifiConnectCallback != null) {
+                    wifiConnectCallback.onSuccess(network);
+                    Log.d("WifiUtils", "======onAvailable: ====连接成功======");
+                }
+            }
+
+            @Override
+            public void onUnavailable() {
+                super.onUnavailable();
+                Log.d("WifiUtils", "======onAvailable: ====连接失败======");
+                if (wifiConnectCallback != null) {
+                    wifiConnectCallback.onFailure();
+                }
+            }
+        };
+
+        //请求连接网络
+        connectivityManager.requestNetwork(request, networkCallback);
+    }
+
+    @SuppressLint("NewApi")
+    private void connectBySug(String ssid, String password) {
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setSsid(ssid)
+                .setWpa2Passphrase(password)
+                .setIsAppInteractionRequired(true)
+                .build();
+        List<WifiNetworkSuggestion> suggestionList = new ArrayList<>();
+        suggestionList.add(suggestion);
+        int status = wifiManager.addNetworkSuggestions(suggestionList);
+        if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+            return;
+        }
+        Log.d(TAG, "======onReceive: ==网络连接状态=111111111===");
+        IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
+        BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+
+                Log.d(TAG, "======onReceive: ==网络连接状态====");
+                if (!intent.getAction().equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
+
+                    return;
+                }
+            }
+        };
+        mContext.registerReceiver(wifiScanReceiver, intentFilter);
+    }
+
+    /**
+     * 创建Wifi配置
+     *
+     * @param ssid     名称
+     * @param password 密码
+     * @param type     类型
+     */
+    private WifiConfiguration createWifiConfig(String ssid, String password, WiFiPwdType type) {
+        WifiConfiguration config = new WifiConfiguration();
+        config.allowedAuthAlgorithms.clear();
+        config.allowedGroupCiphers.clear();
+        config.allowedKeyManagement.clear();
+        config.allowedPairwiseCiphers.clear();
+        config.allowedProtocols.clear();
+        config.SSID = "\"" + ssid + "\"";
+        WifiConfiguration configured = isExist(ssid);
+        if (configured != null) {
+            wifiManager.removeNetwork(configured.networkId);
+            wifiManager.saveConfiguration();
+        }
+
+        //不需要密码的场景
+        if (type == WiFiPwdType.ESS) {
+            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+            //以WEP加密的场景
+        } else if (type == WiFiPwdType.WEP) {
+            config.hiddenSSID = true;
+            config.wepKeys[0] = "\"" + password + "\"";
+            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
+            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+            config.wepTxKeyIndex = 0;
+            //以WPA加密的场景,自己测试时,发现热点以WPA2建立时,同样可以用这种配置连接
+        } else if (type == WiFiPwdType.WPA2_EAP) {
+            config.preSharedKey = "\"" + password + "\"";
+            config.hiddenSSID = true;
+            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+            config.status = WifiConfiguration.Status.ENABLED;
+        }
+        return config;
+    }
+
+    /**
+     * 网络是否连接
+     */
+    @SuppressLint("NewApi")
+    public static boolean isNetConnected(ConnectivityManager connectivityManager) {
+        return connectivityManager.getActiveNetwork() != null;
+    }
+
+    /**
+     * 连接网络类型是否为Wifi
+     */
+    @SuppressLint("NewApi")
+    public static boolean isWifi(ConnectivityManager connectivityManager) {
+        if (connectivityManager.getActiveNetwork() == null) {
+            return false;
+        }
+        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
+        if (networkCapabilities != null) {
+            return false;
+        }
+        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+    }
+
+    /**
+     * 配置表是否存在对应的Wifi配置
+     *
+     * @param SSID
+     * @return
+     */
+    @SuppressLint("MissingPermission")
+    private WifiConfiguration isExist(String SSID) {
+        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
+        for (WifiConfiguration existingConfig : existingConfigs) {
+            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
+                return existingConfig;
+            }
+        }
+        return null;
+    }
+
+    private WifiCapability getCipherType(String capabilities) {
+        if (capabilities.contains("WEB")) {
+            return WifiCapability.WIFI_CIPHER_WEP;
+        } else if (capabilities.contains("PSK")) {
+            return WifiCapability.WIFI_CIPHER_WPA;
+        } else if (capabilities.contains("WPS")) {
+            return WifiCapability.WIFI_CIPHER_NO_PASS;
+        } else {
+            return WifiCapability.WIFI_CIPHER_NO_PASS;
+        }
+    }
+
+    /**
+     * wifi连接回调接口
+     */
+    public interface WifiConnectCallback {
+
+        void onSuccess(Network network);
+
+        void onFailure();
+    }
+
+    public enum WifiCapability {
+        WIFI_CIPHER_WEP, WIFI_CIPHER_WPA, WIFI_CIPHER_NO_PASS
+    }
+
+}

+ 134 - 5
libBase/src/main/java/com/develop/base/manager/WifiHelp.kt

@@ -10,12 +10,13 @@ import android.net.NetworkInfo.DetailedState
 import android.net.wifi.*
 import android.os.Parcelable
 import com.develop.base.ext.appGlobalScope
+import com.develop.base.ext.toJson
+import com.develop.base.manager.ConnectWifiUtils.WifiConnectCallback
 import com.develop.base.scop.safeGlobalScope
 import com.develop.base.util.TimeDownUtil
 import kotlinx.coroutines.*
 
 
-
 class WifiHelp {
     private lateinit var mWifiManager: WifiManager
     private var mBuild: Build? = null
@@ -70,9 +71,9 @@ class WifiHelp {
         }
     }
 
-    fun connect(wifiData: WifiData) {
+    fun connect(wifiData: WifiData, isSaveType: Boolean) {
         countTime()
-        connect(wifiData, "")
+        connectNew(wifiData, "", isSaveType)
     }
 
     @SuppressLint("MissingPermission")
@@ -99,6 +100,7 @@ class WifiHelp {
                 WiFiPwdType.ESS -> {
                     wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
                 }
+
                 WiFiPwdType.WAP -> {
                     wifiConfiguration.preSharedKey = addQuotationMarks(password)
                     wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
@@ -111,12 +113,14 @@ class WifiHelp {
                     wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
                     wifiConfiguration.status = WifiConfiguration.Status.ENABLED
                 }
+
                 WiFiPwdType.WEP -> {
                     wifiConfiguration.wepKeys[0] = addQuotationMarks(password)
                     wifiConfiguration.wepTxKeyIndex = 0;
                     wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                     wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                 }
+
                 WiFiPwdType.WPA2_EAP -> {
                     //不支持企业WiFi密码
                 }
@@ -127,6 +131,66 @@ class WifiHelp {
         currWifiData = wifiData
     }
 
+    @SuppressLint("MissingPermission")
+    fun connectNew(wifiData: WifiData, password: String, isSaveType: Boolean = false) {
+//        removeAllWifi()
+        mWifiManager.disconnect()
+        val configurationList = mWifiManager.configuredNetworks //已经保存密码的WiFi
+        val isSave = configurationList.any {
+            removeQuotationMarks(it.SSID) == wifiData.ssid
+        }
+        if (isSave && isSaveType) {
+            //如果是已经保存密码的的WiFi就重新连接
+//            mWifiManager.enableNetwork(wifiData.netId, false)
+            connectSavedWiFi(wifiData.ssid)
+        } else {
+            val wifiConfiguration = WifiConfiguration()
+            //清除一些默认wifi的配置
+            wifiConfiguration.allowedAuthAlgorithms.clear()
+            wifiConfiguration.allowedGroupCiphers.clear()
+            wifiConfiguration.allowedKeyManagement.clear()
+            wifiConfiguration.allowedPairwiseCiphers.clear()
+            wifiConfiguration.allowedProtocols.clear()
+            wifiConfiguration.SSID = addQuotationMarks(wifiData.ssid)
+            when (wifiData.capabilities) {
+                WiFiPwdType.ESS -> {
+                    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
+                }
+
+                WiFiPwdType.WAP -> {
+                    wifiConfiguration.preSharedKey = addQuotationMarks(password)
+                    wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
+                    wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
+                    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
+                    wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
+                    wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
+                    wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
+                    wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
+                    wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
+                    wifiConfiguration.status = WifiConfiguration.Status.ENABLED
+                }
+
+                WiFiPwdType.WEP -> {
+                    wifiConfiguration.wepKeys[0] = addQuotationMarks(password)
+                    wifiConfiguration.wepTxKeyIndex = 0;
+                    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+                    wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
+                }
+
+                WiFiPwdType.WPA2_EAP -> {
+                    //不支持企业WiFi密码
+                }
+            }
+            var netId = mWifiManager.addNetwork(wifiConfiguration)
+//            mWifiManager.enableNetwork(netId, true)
+            mWifiManager.enableNetwork(netId, true)
+//            mWifiManager.reconnect()
+        }
+        currWifiData = wifiData
+    }
+
+
+
     /**
      * 断开当前连接的网络
      */
@@ -300,6 +364,22 @@ class WifiHelp {
                 timeDownUtil?.cancel()
                 mBuild?.mScanCallback?.invoke(list)
                 mBuild?.mAlreadyConnectionCallback?.invoke(connectionWifi)
+
+                //重连机制
+                var isWifiConnected = false
+                list.forEach {
+                    if (it.isConnected) {
+                        isWifiConnected = true
+                    }
+                }
+
+
+                var reconnectWifi =
+                    if (!isWifiConnected) list.filter { filter -> !filter.isConnected && filter.isSavePwd } else null
+
+                if (reconnectWifi!!.isNotEmpty()) {
+                    initWork()
+                }
             }
         }
     }
@@ -484,12 +564,21 @@ class WifiHelp {
                 }
                 if (networkInfo.detailedState == NetworkInfo.DetailedState.DISCONNECTED) {
                     mBuild?.mErrorAuthenticating?.invoke("failed to connect")
+
+                    /**
+                     * 之前由于save连接也会走这个回调,固然添加isSavePwd判断不走删除WiFi,
+                     * 当第一次连接的时候,会导致密码正确,但isSavaPwd 返回false,固加多个password 不为空的情况下,也不清楚
+                     * */
                     currWifiData?.apply {
-                        removeSaveWifi(this)
+                        if (this.isSavePwd||this.password.isNotEmpty()) {
+                        } else {
+                            removeSaveWifi(this)
+                        }
                     }
                 }
                 if (networkInfo.detailedState == NetworkInfo.DetailedState.FAILED) {
                     mBuild?.mErrorAuthenticating?.invoke("failed to connect")
+
                     currWifiData?.apply {
                         removeSaveWifi(this)
                     }
@@ -507,6 +596,9 @@ class WifiHelp {
             if (intent.action == WifiManager.SUPPLICANT_STATE_CHANGED_ACTION) {
                 val linkWifiResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1)
                 if (linkWifiResult == WifiManager.ERROR_AUTHENTICATING) {
+                    /**
+                     * 密码错误的回调方法
+                     * */
                     timeDownUtil?.cancel()
                     currWifiData?.apply {
                         removeSaveWifi(this)
@@ -518,13 +610,22 @@ class WifiHelp {
         }
     }
 
+    @SuppressLint("MissingPermission")
+    fun initWork() {
+        val configurationList = mWifiManager.configuredNetworks //已经保存密码的WiFi
+        if (configurationList.isNotEmpty()) {
+            configurationList.forEach {
+                connectSavedWiFi(removeQuotationMarks(it.SSID))
+            }
+        }
+
+    }
 
     fun getDetailedState(): DetailedState? {
         return if (getActiveNetworkInfo() != null) {
             getActiveNetworkInfo()?.detailedState
         } else null
     }
-
     /**
      * 获取当前网络信息
      */
@@ -549,8 +650,36 @@ class WifiHelp {
         }
         timeDownUtil?.start()
     }
+
+    /**
+     * 连接到保存过的WiFi
+     * @param[ssid] 字符串或一串16进制的数字
+     */
+    fun connectSavedWiFi(ssids: String) {
+        val config = getWiFiConfig(ssids)
+        config?.networkId?.let {
+            mWifiManager.enableNetwork(it, true)
+        }
+        mWifiManager.saveConfiguration()
+    }
+
+    /**
+     * 获取当前SSID的WiFi配置
+     * @param[ssid] 字符串或一串16进制的数字
+     */
+    fun getWiFiConfig(ssids: String): WifiConfiguration? {
+        val configs = mWifiManager.configuredNetworks
+        if (configs != null && configs.size > 0) {
+            for (config in configs) {
+                val configSSID = config.SSID.replace("\"", "")
+                if (ssids == configSSID) return config
+            }
+        }
+        return null
+    }
 }
 
+
 /**
  * wifi数据
  */

+ 1 - 0
libBase/src/main/java/com/develop/base/widgets/CommonPopupWindow.java

@@ -20,6 +20,7 @@ public abstract class CommonPopupWindow<V extends View, Binding extends ViewData
         super(context);
         getIntercept().intercept();
         setContentView(builder.mBinding.getRoot());
+
         setWidth(builder.mWidth);
         setHeight(builder.mHeight);
         setOutsideTouchable(builder.mOutsideTouchable);

+ 2 - 0
libBase/src/main/res/values/dimens.xml

@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources>
+    <dimen name="convert_78px_negative">-39.0dp</dimen>
+    <dimen name="convert_40px_negative">-20.0dp</dimen>
     <dimen name="convert_0px">0.0dp</dimen>
     <dimen name="convert_1px">0.5dp</dimen>
     <dimen name="convert_2px">1.0dp</dimen>