Explorar el Código

1、调试通文件下载功能,增加下载页面,增加下载进度条控件

不会爬树的猴 hace 2 años
padre
commit
6d18dd9dfb
Se han modificado 87 ficheros con 1759 adiciones y 59 borrados
  1. 82 0
      app/src/main/java/com/cr/adapter/CrAdapter.kt
  2. 113 0
      app/src/main/java/com/cr/adapter/DownloadDataAdapter.kt
  3. 110 0
      app/src/main/java/com/cr/adapter/SettingAdapter.kt
  4. 61 0
      app/src/main/java/com/cr/common/CrSaveManager.kt
  5. 33 8
      app/src/main/java/com/cr/cruav/AvLogin.kt
  6. 64 1
      app/src/main/java/com/cr/cruav/AvMain.kt
  7. 14 3
      app/src/main/java/com/cr/cruav/CrApplication.kt
  8. 120 0
      app/src/main/java/com/cr/dialog/DialogProgressUtil.kt
  9. 32 0
      app/src/main/java/com/cr/models/DownloadDataModel.kt
  10. 89 0
      app/src/main/java/com/cr/models/SetItemModel.kt
  11. 87 1
      app/src/main/java/com/cr/network/TCPDataTask.kt
  12. 79 0
      app/src/main/java/com/cr/pages/CrAnimationFragment.kt
  13. 2 37
      app/src/main/java/com/cr/pages/CrFragment.kt
  14. 2 1
      app/src/main/java/com/cr/pages/CrNavigationFragment.kt
  15. 1 3
      app/src/main/java/com/cr/pages/FragmentFPV.kt
  16. 1 1
      app/src/main/java/com/cr/pages/FragmentMap.kt
  17. 194 0
      app/src/main/java/com/cr/pages/FragmentSet.kt
  18. 75 0
      app/src/main/java/com/cr/pages/FragmentSetDataDownload.kt
  19. 1 1
      app/src/main/java/com/cr/pages/FragmentSetIpAndCom.kt
  20. 214 0
      app/src/main/java/com/cr/pages/FragmentSetMain.kt
  21. 46 0
      app/src/main/java/com/cr/ui/CrNoScrollViewPager.kt
  22. 26 0
      app/src/main/java/com/cr/widget/CrNavigationBarWidget.kt
  23. 10 0
      app/src/main/res/anim/slide_right_in.xml
  24. 9 0
      app/src/main/res/anim/slide_right_out.xml
  25. BIN
      app/src/main/res/drawable/goto_back.png
  26. BIN
      app/src/main/res/drawable/ico_aircraft.png
  27. BIN
      app/src/main/res/drawable/ico_airstate.png
  28. BIN
      app/src/main/res/drawable/ico_area.png
  29. BIN
      app/src/main/res/drawable/ico_arrow_right.png
  30. BIN
      app/src/main/res/drawable/ico_back.png
  31. BIN
      app/src/main/res/drawable/ico_basemap_raster.png
  32. BIN
      app/src/main/res/drawable/ico_basemap_vector.png
  33. BIN
      app/src/main/res/drawable/ico_bmap_v.png
  34. BIN
      app/src/main/res/drawable/ico_camera_phoshop.png
  35. BIN
      app/src/main/res/drawable/ico_camera_record.png
  36. BIN
      app/src/main/res/drawable/ico_case_tools.png
  37. BIN
      app/src/main/res/drawable/ico_check_no.png
  38. BIN
      app/src/main/res/drawable/ico_check_yes.png
  39. BIN
      app/src/main/res/drawable/ico_clear.png
  40. BIN
      app/src/main/res/drawable/ico_draw_blue.png
  41. BIN
      app/src/main/res/drawable/ico_draw_green.png
  42. BIN
      app/src/main/res/drawable/ico_draw_red.png
  43. BIN
      app/src/main/res/drawable/ico_hisdata.png
  44. BIN
      app/src/main/res/drawable/ico_identify_localcase.png
  45. BIN
      app/src/main/res/drawable/ico_identify_netcase.png
  46. 0 0
      app/src/main/res/drawable/ico_info.png
  47. BIN
      app/src/main/res/drawable/ico_layer.png
  48. BIN
      app/src/main/res/drawable/ico_left.png
  49. BIN
      app/src/main/res/drawable/ico_length.png
  50. BIN
      app/src/main/res/drawable/ico_location.png
  51. BIN
      app/src/main/res/drawable/ico_media_cur.png
  52. BIN
      app/src/main/res/drawable/ico_media_net.png
  53. BIN
      app/src/main/res/drawable/ico_media_old.png
  54. BIN
      app/src/main/res/drawable/ico_mession.png
  55. BIN
      app/src/main/res/drawable/ico_multimage.png
  56. BIN
      app/src/main/res/drawable/ico_old_down.png
  57. BIN
      app/src/main/res/drawable/ico_old_map.png
  58. BIN
      app/src/main/res/drawable/ico_old_time.png
  59. BIN
      app/src/main/res/drawable/ico_repeatflight_no.png
  60. BIN
      app/src/main/res/drawable/ico_repeatflight_yes.png
  61. BIN
      app/src/main/res/drawable/ico_tools_add_map_repeatflight.png
  62. BIN
      app/src/main/res/drawable/ico_tools_case_map_sel.png
  63. BIN
      app/src/main/res/drawable/ico_ty.png
  64. BIN
      app/src/main/res/drawable/ico_ty1.png
  65. BIN
      app/src/main/res/drawable/ico_upload_case.png
  66. BIN
      app/src/main/res/drawable/ico_upload_wj.png
  67. BIN
      app/src/main/res/drawable/ico_wj_no.png
  68. BIN
      app/src/main/res/drawable/ico_wj_upload_yes.png
  69. BIN
      app/src/main/res/drawable/icon_layer_draw.png
  70. BIN
      app/src/main/res/drawable/icon_layer_other1.png
  71. BIN
      app/src/main/res/drawable/icon_layer_other2.png
  72. BIN
      app/src/main/res/drawable/icon_layer_tiled.png
  73. BIN
      app/src/main/res/drawable/icon_layer_vector.png
  74. BIN
      app/src/main/res/drawable/img.png
  75. 5 0
      app/src/main/res/drawable/item_click_normal.xml
  76. 5 0
      app/src/main/res/drawable/item_click_select.xml
  77. 5 0
      app/src/main/res/drawable/item_click_selector.xml
  78. 48 0
      app/src/main/res/drawable/progress_bar.xml
  79. 2 2
      app/src/main/res/layout/av_login.xml
  80. 8 0
      app/src/main/res/layout/av_main.xml
  81. 1 1
      app/src/main/res/layout/dig_normal.xml
  82. 46 0
      app/src/main/res/layout/dig_progress.xml
  83. 25 0
      app/src/main/res/layout/frag_set.xml
  84. 20 0
      app/src/main/res/layout/frag_set_data_download.xml
  85. 20 0
      app/src/main/res/layout/frag_set_main.xml
  86. 56 0
      app/src/main/res/layout/item_data_download.xml
  87. 53 0
      app/src/main/res/layout/item_set.xml

+ 82 - 0
app/src/main/java/com/cr/adapter/CrAdapter.kt

@@ -0,0 +1,82 @@
+package com.cr.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.BaseAdapter
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 10:01
+ * 描述:基础适配器
+ */
+open class CrAdapter<T>@JvmOverloads constructor(
+    context: Context?=null,
+    dataList:MutableList<T>
+) : BaseAdapter() {
+    // define: 2023/4/11 上下文
+    var context: Context? = null
+
+    // define: 2023/4/11 数据集合
+    var dataList: MutableList<T>? = null
+
+    // define: 2023/4/11 视图管理器
+    var inflater: LayoutInflater? = null
+
+    /**
+     *  初始化
+     */
+    init {
+        this.context = context
+        this.dataList = dataList
+        this.inflater = LayoutInflater.from(context)
+    }
+
+    /**
+     * 返回数量
+     * @return Int
+     */
+    override fun getCount(): Int {
+        return dataList!!.size
+    }
+
+    /**
+     * 返回选择项
+     * @param p0 Int
+     * @return Any
+     */
+    override fun getItem(p0: Int): T {
+        return dataList!![p0]
+    }
+
+    /**
+     * 返回选择项Id
+     * @param p0 Int
+     * @return Long
+     */
+    override fun getItemId(p0: Int): Long {
+        return 0
+    }
+
+    /**
+     * 返回视图
+     * @param p0 Int
+     * @param p1 View
+     * @param p2 ViewGroup
+     * @return View
+     */
+    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View? {
+        return null
+    }
+
+    /**
+     * 更新数据
+     * @param dataList MutableList<T> 数据集合
+     */
+    fun notifyUpdate(dataList: MutableList<T>){
+        this.dataList = dataList
+        this.notifyDataSetChanged()
+    }
+}

+ 113 - 0
app/src/main/java/com/cr/adapter/DownloadDataAdapter.kt

@@ -0,0 +1,113 @@
+package com.cr.adapter
+
+import android.content.Context
+import android.graphics.Color
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.ProgressBar
+import android.widget.TextView
+import com.cr.cruav.R
+import com.cr.models.DownloadDataModel
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 16:15
+ * 描述:数据下载适配器
+ */
+class DownloadDataAdapter @JvmOverloads constructor(
+    context: Context,
+    dataList: MutableList<DownloadDataModel>
+) : CrAdapter<DownloadDataModel>(context, dataList),View.OnClickListener {
+    private val DOWNLOAD_START = 9001
+    private val DOWNLOAD_PROGRESS = 9002
+    private val DOWNLOAD_FAILURE = 9003
+    private val DOWNLOAD_SUCCESS = 9004
+    // todo: 2023/4/11 多线程
+    private val handler:Handler = object:Handler(Looper.getMainLooper()){
+        override fun handleMessage(msg: Message) {
+            super.handleMessage(msg)
+        }
+    }
+    companion object {
+        class ViewHolder {
+            var lblTitle: TextView? = null
+            var lblIsDownload: TextView? = null
+            var btnDownload:ImageView?=null
+            var progressBar:ProgressBar?=null
+            var model:DownloadDataModel? = null
+        }
+    }
+
+    /**
+     * 重写获取视图
+     * @param position Int
+     * @param convertView View?
+     * @param viewGroup ViewGroup?
+     * @return View?
+     */
+    override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup?): View? {
+        var viewHolder:ViewHolder
+        var view = convertView
+        if(convertView == null){
+            viewHolder = ViewHolder()
+            view = inflater?.inflate(R.layout.item_data_download,null)
+            viewHolder.lblTitle = view?.findViewById(R.id.item_down_title)
+            viewHolder.lblIsDownload = view?.findViewById(R.id.item_down_state)
+            viewHolder.btnDownload = view?.findViewById(R.id.item_down_down)
+            viewHolder.progressBar = view?.findViewById(R.id.item_down_bar)
+            // todo: 2023/4/11 设置最大值
+            viewHolder.progressBar?.max = 100
+            view?.tag = viewHolder
+        }else{
+            viewHolder = view?.tag as ViewHolder
+        }
+        // todo: 2023/4/11 初始化数据
+        var model:DownloadDataModel = dataList!![position]
+        model.let {
+            viewHolder.lblTitle?.text = it.title
+            viewHolder.lblIsDownload?.text = if (model.isDownload) "已下载" else "未下载"
+            viewHolder.lblIsDownload?.setTextColor(
+                if (model.isDownload) Color.argb(
+                    255,
+                    255,
+                    255,
+                    255
+                ) else Color.argb(255, 255, 0, 0)
+            )
+            viewHolder.model = model
+            viewHolder.btnDownload?.tag = viewHolder
+            viewHolder.btnDownload?.setOnClickListener(this)
+        }
+        return view!!
+    }
+
+    /**
+     * 发送多线程消息
+     * @param obj Object 消息体
+     * @param what Int 标识
+     */
+    private fun sendThreadMessage(obj:Object,what:Int){
+        var message = Message()
+        message.what = what
+        message.obj = obj
+        handler.sendMessage(message)
+    }
+
+    /**
+     * 视图点击事件
+     * @param view View
+     */
+    override fun onClick(view: View?) {
+        when(view?.id){
+            R.id.item_down_down->{
+                var holder = view.tag as ViewHolder
+                holder.progressBar?.progress = 50
+            }
+        }
+    }
+}

+ 110 - 0
app/src/main/java/com/cr/adapter/SettingAdapter.kt

@@ -0,0 +1,110 @@
+package com.cr.adapter
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import android.widget.CompoundButton
+import android.widget.CompoundButton.OnCheckedChangeListener
+import android.widget.ImageView
+import android.widget.Switch
+import android.widget.TextView
+import com.cr.cruav.R
+import com.cr.data.FontManager
+import com.cr.models.SetItemModel
+import com.cr.models.SettingAction
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 10:01
+ * 描述:设置项适配器
+ */
+class SettingAdapter @JvmOverloads constructor(
+    context: Context? = null,
+    dataList: MutableList<SetItemModel>
+) : CrAdapter<SetItemModel>(context, dataList), View.OnClickListener, OnCheckedChangeListener {
+    /**
+     * 对外接口
+     */
+    interface SettingListener {
+        // todo: 2023/4/11 动作监听
+        fun onAction(action: SettingAction)
+
+        // todo: 2023/4/11 开关监听
+        fun onSwitch(action: SettingAction, isChecked: Boolean)
+    }
+
+    // define: 2023/4/11 定义监听
+    var listener: SettingListener? = null
+
+    /**
+     * 重写获取视图方法
+     * @param position Int
+     * @param convertView View?
+     * @param viewGroup ViewGroup?
+     * @return View?
+     */
+    override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup?): View? {
+        var holder: ViewHolder
+        var view = convertView
+        if (convertView == null) {
+            holder = ViewHolder()
+            view = inflater!!.inflate(R.layout.item_set, null)
+            holder.imageView = view.findViewById(R.id.item_set_img)
+            holder.lblTitle = view.findViewById(R.id.item_set_title)
+            holder.icoArrow = view.findViewById(R.id.item_set_arrow)
+            FontManager.setTextView(context!!, holder.icoArrow!!, R.string.ico_arrow)
+            holder.aSwitch = view.findViewById(R.id.item_set_switch)
+            view.tag = holder
+        } else {
+            holder = view!!.tag as ViewHolder
+        }
+        var model: SetItemModel = dataList!![position]
+        holder.lblTitle?.text = model.title
+        holder.imageView?.setImageDrawable(context!!.resources.getDrawable(model.imageId))
+        holder.aSwitch?.visibility = if (model.isSwitch) View.VISIBLE else View.GONE
+        // todo: 2023/4/11 设置开关状态
+        holder.aSwitch?.isChecked = model.switchIsOn
+        // todo: 2023/4/11 设置箭头
+        holder.icoArrow?.visibility = if (model.isArrow) View.VISIBLE else View.GONE
+        // todo: 2023/4/11 特殊处理
+        if (model.isSwitch) {
+            holder.lblTitle?.isClickable = false
+            holder.aSwitch?.tag = model
+            holder.aSwitch?.setOnCheckedChangeListener(this)
+        } else {
+            holder.lblTitle?.isClickable = true
+            holder.lblTitle?.tag = model
+            holder.lblTitle?.setOnClickListener(this)
+        }
+        return view
+    }
+
+    companion object {
+        class ViewHolder {
+            var imageView: ImageView? = null
+            var lblTitle: TextView? = null
+            var icoArrow: TextView? = null
+            var aSwitch: Switch? = null
+        }
+    }
+
+    /**
+     * 视图点击事件
+     * @param p0 View
+     */
+    override fun onClick(p0: View?) {
+        var model:SetItemModel = p0?.tag as SetItemModel
+        if(listener != null) model.action?.let { listener?.onAction(it) }
+    }
+
+    /**
+     * 开关事件
+     * @param p0 CompoundButton
+     * @param p1 Boolean
+     */
+    override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
+        var model:SetItemModel = p0?.tag as SetItemModel
+        if(listener != null) model.action?.let { listener?.onSwitch(it,p1) }
+    }
+}

+ 61 - 0
app/src/main/java/com/cr/common/CrSaveManager.kt

@@ -0,0 +1,61 @@
+package com.cr.common
+
+import android.content.Context
+import android.content.SharedPreferences
+import com.cr.cruav.CrApplication
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 09:37
+ * 描述:一般存储的管理
+ */
+class CrSaveManager {
+    // define: 2023/4/11 key对应变量
+    val KEY_MAP_CENTER:String = "mapCenter"
+
+    // define: 2023/4/11 本地化存储实例
+    var preferences:SharedPreferences ?=null
+
+    /**
+     * 初始化
+     * @constructor
+     */
+    constructor(){
+        // todo: 2023/4/11 初始化本地存储实例
+        preferences = CrApplication.getInstance()!!.getSharedPreferences("config", Context.MODE_PRIVATE)
+    }
+
+    // todo: 2023/4/11 静态方法
+    companion object{
+        /**
+         * 获取单例
+         * @return CrSaveManager
+         */
+        fun getInstance() = InstanceHelper.self
+    }
+    /**
+     * 用于单例
+     */
+    object InstanceHelper{
+        var self = CrSaveManager()
+    }
+
+    /**
+     * 获取地图是否自动居中
+     * @return Boolean
+     */
+    fun getMapCenter(): Boolean? {
+        return preferences?.getBoolean(KEY_MAP_CENTER,true)
+    }
+
+    /**
+     * 设置地图是否自动居中
+     * @param isCenter Boolean
+     */
+    fun setMapCenter(isCenter:Boolean){
+        var editor:SharedPreferences.Editor = preferences!!.edit()
+        editor.putBoolean(KEY_MAP_CENTER,isCenter)
+        editor.commit()
+    }
+}

+ 33 - 8
app/src/main/java/com/cr/cruav/AvLogin.kt

@@ -22,6 +22,7 @@ import com.cr.data.CrUtil
 import com.cr.data.CrUtil.Companion.onStart
 import com.cr.dialog.DialogNormal
 import com.cr.dialog.DialogNormal.DialogNormalListener
+import com.cr.dialog.DialogProgressUtil
 import com.cr.event.EventFragmentBarAction
 import com.cr.models.UserModel
 import com.cr.network.NetManager
@@ -34,7 +35,7 @@ import org.json.JSONArray
 
 class AvLogin : CrActivity(), OnClickListener {
     // define: 2023/3/31 权限列表
-    val REQUIRED_PERMISSION_LIST = arrayOf(
+    private val REQUIRED_PERMISSION_LIST: Array<String> = arrayOf(
         Manifest.permission.VIBRATE,  // VARIABLE: 4/8/21
         Manifest.permission.INTERNET,  // VARIABLE: 4/8/21 网路权限
         Manifest.permission.ACCESS_WIFI_STATE,  // VARIABLE: 4/8/21 监测WIFI状态权限
@@ -154,15 +155,39 @@ class AvLogin : CrActivity(), OnClickListener {
     override fun onClick(p0: View?) {
         when (p0!!.id) {
             R.id.login_btn_login -> {
-                var userName: String? = txtUserName?.checkBlank("请输入账号!") ?: return
-                var passWord: String? = txtPassword?.checkBlank("请输入密码!") ?: return
-                var isSave: Boolean? = switchSavePassword?.isChecked
-                checkUserInfo(userName!!, passWord!!, isSave!!)
+//                var userName: String? = txtUserName?.checkBlank("请输入账号!") ?: return
+//                var passWord: String? = txtPassword?.checkBlank("请输入密码!") ?: return
+//                var isSave: Boolean? = switchSavePassword?.isChecked
+//                checkUserInfo(userName!!, passWord!!, isSave!!)
+                this.finish()
+                context!!.onStart<AvMain>()
             }
             R.id.login_btn_set -> {
-                fragIpAndCom?.let {
-                    showFragment(it)
-                }
+//                fragIpAndCom?.let {
+//                    it.setBarVisible(isVisible = true)
+//                    showFragment(it)
+//                }
+                // todo: 2023/4/12 下载测试文件
+                TCPDataTask.getInstance().sendDownloadFile(context!!,"","http://218.59.194.74:8088/lqz_service/download/demo.rar",object:TCPDataTask.OnDownloadListener{
+                    override fun onStart() {
+                        DialogProgressUtil.show(context!!)
+                    }
+
+                    override fun onFailed(message: String) {
+                        DialogProgressUtil.dismiss()
+                    }
+
+                    override fun onProgress(progress: Int, total: Int) {
+                        DialogProgressUtil.setMax(total)
+                        var pValue = String.format("%.2f",(progress/total.toDouble())*100) + "%"
+                        DialogProgressUtil.update("1/1",pValue,progress)
+                    }
+
+                    override fun onComplete() {
+                        DialogProgressUtil.dismiss()
+                    }
+
+                })
             }
 
         }

+ 64 - 1
app/src/main/java/com/cr/cruav/AvMain.kt

@@ -2,6 +2,7 @@ package com.cr.cruav
 
 import android.annotation.SuppressLint
 import android.os.Bundle
+import android.view.View
 import android.widget.FrameLayout
 import android.widget.TextView
 import androidx.activity.viewModels
@@ -14,17 +15,21 @@ import androidx.fragment.app.commit
 import androidx.fragment.app.commitNow
 import com.cr.data.CrConfig
 import com.cr.data.CrUtil
+import com.cr.event.EventFragmentBarAction
 import com.cr.pages.FragmentFPV
 import com.cr.pages.FragmentMap
+import com.cr.pages.FragmentSet
 import com.cr.pages.FragmentTopInfo
 import com.cr.viewmodel.*
+import com.squareup.otto.Subscribe
 import dji.v5.common.error.IDJIError
 import dji.v5.common.register.DJISDKInitEvent
 import dji.v5.manager.interfaces.SDKManagerCallback
 import dji.v5.utils.common.ToastUtils
 import kotlinx.android.synthetic.main.av_main.*
+import kotlinx.android.synthetic.main.tools_top.*
 
-class AvMain : AppCompatActivity() {
+class AvMain : CrActivity(), View.OnClickListener {
     // define: 2023/3/10 将App视图绑定到模型
     private val msdkRegisterVm: CrMSDKRegisterVM by viewModels()
 
@@ -52,6 +57,9 @@ class AvMain : AppCompatActivity() {
     // define: 2023/3/14 图传窗口是不是小窗口
     private var isFpvSmallWindow:Boolean = true
 
+    // define: 2023/4/11 初始化设置页面
+    private var fragmentSet:FragmentSet? = null
+
 
     /**
      * 入口函数
@@ -59,7 +67,20 @@ class AvMain : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.av_main);
+        // todo: 2023/4/11 挂载控件
+        joinControls()
+        // todo: 2023/4/11 初始化
         init()
+        // todo: 2023/4/3 订阅事件
+        CrApplication.getEventBus().register(this)
+    }
+
+    /**
+     * 挂载控件
+     */
+    override fun joinControls() {
+        // todo: 2023/4/11 设置点击事件
+        tools_set.setOnClickListener(this)
     }
 
     /**
@@ -80,6 +101,12 @@ class AvMain : AppCompatActivity() {
     private fun initPage(){
         // todo: 2023/4/10 显示登录账号
         av_main_lbl_user.text = CrConfig.user?.userName
+        // todo: 2023/4/11 初始化设置页面
+        fragmentSet = FragmentSet()
+        fragmentSet?.let {
+            addFragment(it,R.id.av_frm_right_panel)
+            hideFragment(it)
+        }
     }
 
     /**
@@ -167,4 +194,40 @@ class AvMain : AppCompatActivity() {
             }
         })
     }
+
+    /**
+     * 视图点击事件
+     * @param view View
+     */
+    override fun onClick(view: View?) {
+        when(view?.id){
+            R.id.tools_set->{
+                showFragment(fragmentSet!!)
+            }
+        }
+    }
+
+    /**
+     * 销毁
+     */
+    override fun onDestroy() {
+        CrApplication.getEventBus().unregister(this)
+        super.onDestroy()
+    }
+
+    /**
+     * 重新激活
+     */
+    override fun onResume() {
+        super.onResume()
+    }
+
+    /**
+     * 订阅Fragment管理事件
+     * @param event EventFragmentBarAction
+     */
+    @Subscribe
+    fun onFragmentBar(event: EventFragmentBarAction) {
+        hideFragment(fragmentSet!!)
+    }
 }

+ 14 - 3
app/src/main/java/com/cr/cruav/CrApplication.kt

@@ -11,18 +11,21 @@ import com.squareup.otto.ThreadEnforcer
  * 创建日期:3/1/23 9:58 AM
  * 描述:
  */
-class CrApplication: Application() {
+class CrApplication : Application() {
     override fun attachBaseContext(base: Context?) {
         super.attachBaseContext(base);
         com.secneo.sdk.Helper.install(this);
+        app = this
     }
 
     /**
      *  静态方法
      */
-    companion object{
+    companion object {
         // define: 2023/4/3 订阅事件
-        private var bus:Bus = Bus(ThreadEnforcer.ANY)
+        private var bus: Bus = Bus(ThreadEnforcer.ANY)
+        // define: 2023/4/11 应用本身
+        private var app: Application? = null
 
         /**
          * 获取订阅事件
@@ -31,5 +34,13 @@ class CrApplication: Application() {
         fun getEventBus(): Bus {
             return bus
         }
+
+        /**
+         * 获取Application
+         * @return Application?
+         */
+        fun getInstance(): Application? {
+            return CrApplication.app
+        }
     }
 }

+ 120 - 0
app/src/main/java/com/cr/dialog/DialogProgressUtil.kt

@@ -0,0 +1,120 @@
+package com.cr.dialog
+
+import android.app.AlertDialog
+import android.content.Context
+import android.os.Build
+import android.view.LayoutInflater
+import android.view.View
+import android.view.WindowManager
+import android.widget.ProgressBar
+import android.widget.TextView
+import androidx.annotation.RequiresApi
+import com.cr.cruav.R
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/10 14:59
+ * 描述:下载进度条
+ */
+class DialogProgressUtil {
+    companion object{
+        // define: 2023/4/10 对话框
+        var progressDialog:AlertDialog?=null
+        // define: 2023/4/12 定义控件
+        var lblTitle:TextView?= null
+        var lblProgress:TextView?=null
+        var progressBar:ProgressBar?=null
+
+        /**
+         * 初始化
+         * @param context Context 上下文
+         * @param res Int 资源Id
+         */
+        private fun init(context:Context, res:Int){
+            if(progressDialog == null){
+                progressDialog = AlertDialog.Builder(context).create()
+                if(res>0){
+                    // todo: 2023/4/10 创建视图
+                    var view: View = LayoutInflater.from(context).inflate(res,null)
+                    // todo: 2023/4/10 挂载标题文本
+                    lblTitle = view.findViewById(R.id.dig_progress_title)
+                    lblTitle?.text = "1/1"
+                    // todo: 2023/4/12 挂载下载进度文本
+                    lblProgress = view.findViewById(R.id.dig_progress_progress)
+                    lblProgress?.text = "0%"
+                    // todo: 2023/4/12 挂接下载进度条
+                    progressBar = view.findViewById(R.id.dig_progress_bar)
+                    @RequiresApi(Build.VERSION_CODES.O)
+                    progressBar?.min = 0
+                    progressBar?.max = 100
+                    // todo: 2023/4/10 设置视图
+                    progressDialog?.setView(view)
+                    // todo: 2023/4/10 设置对话框背景
+                    progressDialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
+                    // todo: 2023/4/10 去掉阴影
+                    progressDialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+                }
+                // todo: 2023/4/10 禁止点击外部关闭
+                progressDialog?.setCancelable(false)
+            }
+        }
+
+        /**
+         * 显示下载进度框
+         * @param context Context 上下文
+         */
+        fun show(context: Context){
+            init(context, R.layout.dig_progress)
+            progressDialog?.show()
+            progressDialog?.setCancelable(false);
+        }
+
+        /**
+         * 显示下载进度框
+         * @param context Context 上下文
+         * @param max Int 最大值
+         */
+        fun show(context: Context, max:Int){
+            init(context, R.layout.dig_progress)
+            progressDialog?.show()
+            progressDialog?.setCancelable(false);
+            progressBar?.max = max
+        }
+
+        /**
+         * 更新显示内容
+         * @param title String 标题
+         * @param progressTitle String 下载进度
+         * @param progress Int 当前进度
+         */
+        fun update(title:String,progressTitle:String,progress:Int){
+            if(progressDialog != null && progressDialog?.isShowing == true){
+                lblTitle?.text = title
+                lblProgress?.text = progressTitle
+                progressBar?.progress = progress
+            }
+        }
+
+        /**
+         * 设置最大值
+         * @param max Int 最大值
+         */
+        fun setMax(max:Int){
+            if(progressDialog != null && progressDialog?.isShowing == true){
+                progressBar?.max = max
+            }
+        }
+
+        /**
+         * 关闭等待框
+         */
+        fun dismiss(){
+            if(progressDialog != null && progressDialog?.isShowing == true){
+                progressDialog?.dismiss()
+                progressDialog = null
+            }
+        }
+
+    }
+}

+ 32 - 0
app/src/main/java/com/cr/models/DownloadDataModel.kt

@@ -0,0 +1,32 @@
+package com.cr.models
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 16:09
+ * 描述:数据下载模型
+ */
+class DownloadDataModel@JvmOverloads constructor(
+    title:String,
+    fileName:String,
+    isDownload:Boolean = false
+) {
+    // define: 2023/4/11 标题
+    var title: String? = null
+
+    // define: 2023/4/11 下载文件名称
+    var fileName: String? = null
+
+    // define: 2023/4/11 是否已经下载
+    var isDownload: Boolean = false
+
+    /**
+     * 初始化
+     */
+    init {
+        this.title = title
+        this.fileName = fileName
+        this.isDownload = isDownload
+    }
+
+}

+ 89 - 0
app/src/main/java/com/cr/models/SetItemModel.kt

@@ -0,0 +1,89 @@
+package com.cr.models
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 09:14
+ * 描述:设置子项模型
+ */
+class SetItemModel {
+    var imageId = 0
+    var title  : String? = null
+    var isArrow = false
+    var isSwitch = false
+    var action : SettingAction? = null
+    var switchIsOn = false
+
+    /**
+     * 初始化
+     * @param imgId Int 图标资源Id
+     * @param title String 标题
+     * @param isArrow Boolean 是否显示右侧箭头
+     * @param isSwitch Boolean 是否显示开关
+     * @param action SettingAction 动作
+     * @param switchIsOn Boolean 开关是否开启
+     * @constructor
+     */
+    constructor(imgId:Int,title:String,isArrow:Boolean,isSwitch:Boolean,action: SettingAction,switchIsOn:Boolean){
+        this.imageId = imgId
+        this.title = title
+        this.isArrow = isArrow
+        this.isSwitch = isSwitch
+        this.action = action
+        this.switchIsOn = switchIsOn
+    }
+}
+
+/**
+ * 操作类型
+ */
+enum class SettingAction{
+    /**
+     * 登录大疆账号
+     */
+    SA_DJI_LOGIN,
+    /**
+     * 下载数据
+     */
+    SA_DOWNLOAD_DATA,
+    /**
+     * 地图居中
+     */
+    SA_MAP_CENTER,
+    /**
+     * 设置IP和COM
+     */
+    SA_SET_IP_COM,
+    /**
+     * 查看历史航线
+     */
+    SA_OLD_AIRLINE,
+    /**
+     * 重新登录系统
+     */
+    SA_RE_LOGIN,
+    /**
+     * 删除地图缓存
+     */
+    SA_DEL_MAP_CACHE,
+    /**
+     * 查看大疆飞行记录
+     */
+    SA_SHOW_DJI_LOG,
+    /**
+     * 删除取证数据
+     */
+    SA_DEL_QZ_DATA,
+    /**
+     * 删除航线数据
+     */
+    SA_DEL_LINE_DATA,
+    /**
+     * 删除资源数据
+     */
+    SA_DEL_RESOURCE_DATA,
+    /**
+     * 上传断网航点
+     */
+    SA_UPLOAD_NO_UP_AIR_POINT,
+}

+ 87 - 1
app/src/main/java/com/cr/network/TCPDataTask.kt

@@ -6,8 +6,8 @@ import android.os.Looper
 import android.os.Message
 import com.cr.data.*
 import com.cr.dialog.DialogLoadingUtil
+import com.cr.dialog.DialogNormal
 import com.cr.models.iNetDataModel
-import dji.v5.utils.common.ContextUtil
 import okhttp3.*
 import okhttp3.MediaType.Companion.toMediaType
 import okhttp3.RequestBody.Companion.toRequestBody
@@ -15,6 +15,7 @@ import org.json.JSONArray
 import org.json.JSONException
 import org.json.JSONObject
 import java.io.IOException
+import java.io.InputStream
 import java.net.ConnectException
 import java.util.concurrent.TimeUnit
 
@@ -28,6 +29,10 @@ class TCPDataTask {
     // define: 2023/4/10 定义显示或关闭等待条
     val PROGRESS_SHOW:Int = 1001
     val PROGRESS_CLOSE:Int = 1002
+    val SHOW_MESSAGE:Int = 1003
+    var DOWNLOAD_ERROR:Int = 1004
+    var DOWNLOAD_PROGRESS:Int = 1005
+    var DOWNLOAD_COMPLETE:Int = 1006
 
     // define: 2023/4/10 定义变量
     var context:Context? = null
@@ -42,6 +47,8 @@ class TCPDataTask {
                 DialogLoadingUtil.show(context!!,msg.obj.toString())
             }else if(msg.what == PROGRESS_CLOSE){
                 DialogLoadingUtil.dismiss()
+            }else if(msg.what == SHOW_MESSAGE){
+                DialogNormal(context!!,"警告",msg.obj.toString()).show()
             }
         }
     }
@@ -53,6 +60,24 @@ class TCPDataTask {
         fun onSuccess(jsonArray:JSONArray)
         fun onFailed(message:String)
     }
+
+    /**
+     * 下载监听
+     */
+    interface OnDownloadListener{
+        // todo: 2023/4/12 开始下载
+        fun onStart()
+        // todo: 2023/4/12 下载失败
+        fun onFailed(message:String)
+
+        // todo: 2023/4/12 下载进度
+        fun onProgress(progress:Int,total:Int)
+
+        // todo: 2023/4/12 下载完成
+        fun onComplete()
+
+    }
+
     // todo: 2023/4/8 网络连接
     var okHttp: OkHttpClient? = null
 
@@ -103,6 +128,17 @@ class TCPDataTask {
     }
 
     /**
+     * 显示提示消息
+     * @param message String
+     */
+    private fun showMessage(message:String){
+        var msg:Message = Message();
+        msg.what = SHOW_MESSAGE
+        msg.obj = message
+        handler.sendMessage(msg)
+    }
+
+    /**
      *
      * @param url String 服务地址
      * @param iModel iNetDataModel<T> 发送数据
@@ -160,6 +196,56 @@ class TCPDataTask {
         })
     }
 
+    fun sendDownloadFile(context: Context,fileName:String,url:String,callBack:OnDownloadListener){
+        if(callBack != null) callBack.onStart()
+        // todo: 2023/4/12 上下文
+        this.context = context
+        // todo: 2023/4/12 定义下载的Url
+        var request:Request = Request.Builder().url(url).build()
+        // todo: 2023/4/12 开始调用下载
+        okHttp?.newCall(request)?.enqueue(object:Callback{
+            // todo: 2023/4/12 下载失败
+            override fun onFailure(call: Call, e: IOException) {
+                handler.post(Runnable {
+                    if(callBack!= null) {
+                        callBack.onComplete()
+                        callBack.onFailed(e.message!!)
+                    }
+                })
+            }
+
+            // todo: 2023/4/12 下载成功
+            override fun onResponse(call: Call, response: Response) {
+                var inputStream:InputStream? = null
+                var buf = ByteArray(2048)
+                var len:Int
+                try{
+                    inputStream = response.body!!.byteStream()
+                    var total:Long = response.body!!.contentLength()
+                    var sum:Long = 0
+                    while (true){
+                        len = inputStream.read(buf)
+                        if(len == -1) break
+                        sum += len
+                        handler.post(Runnable {
+                            if(callBack != null) callBack.onProgress(sum.toInt(), total.toInt())
+                        })
+                    }
+                }catch (e: IOException){
+                    handler.post(Runnable {
+                        if(callBack!= null) callBack.onFailed(e.message!!)
+                    })
+                }finally {
+                    inputStream!!.close()
+                    handler.post(Runnable {
+                        if(callBack != null) callBack.onComplete()
+                    })
+                }
+            }
+
+        })
+    }
+
     /**
      * 解析JSON数据
      * @param JSON String JSON字符串

+ 79 - 0
app/src/main/java/com/cr/pages/CrAnimationFragment.kt

@@ -0,0 +1,79 @@
+package com.cr.pages
+
+import android.view.animation.Animation
+import android.view.animation.AnimationUtils
+import androidx.fragment.app.FragmentTransaction
+import com.cr.cruav.R
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/3/10 08:51
+ * 描述:Fragment 公共基础类(动画)
+ */
+open class CrAnimationFragment : CrFragment() {
+    /**
+     * 动画方向
+     */
+    enum class AnimationDirection{
+        /**
+         * 左侧
+         */
+        LEFT,
+
+        /**
+         * 右侧
+         */
+        RIGHT,
+    }
+
+    // todo: 2023/4/11 动画方向 默认为左侧弹出 右侧推出
+    private var animationDirection:AnimationDirection = AnimationDirection.LEFT
+
+    /**
+     * 设置动画方向
+     * @param animationDirection AnimationDirection 动画方向
+     */
+    fun setAnimationDirection(animationDirection: AnimationDirection){
+        this.animationDirection = animationDirection
+    }
+
+    /**
+     * 重写左侧滑动动画效果
+     * @param transit Int
+     * @param enter Boolean
+     * @param nextAnim Int
+     * @return Animation?
+     */
+    override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
+        var animInRes:Int = -1
+        var animOutRes:Int = -1
+        if(animationDirection == AnimationDirection.LEFT){
+            animInRes = R.anim.slide_left_in
+            animOutRes = R.anim.slide_left_out
+        }else if(animationDirection == AnimationDirection.RIGHT){
+            animInRes = R.anim.slide_right_in
+            animOutRes = R.anim.slide_right_out
+        }
+        // todo: 2023/4/6 表示是一个进入动作,比如add.show等
+        if (transit == FragmentTransaction.TRANSIT_FRAGMENT_OPEN) {
+            if (enter) {
+                // todo: 2023/4/6 普通的进入的动作
+                return AnimationUtils.loadAnimation(context, animInRes);
+            } else {
+                // todo: 2023/4/6 比如一个已经Fragment被另一个replace,是一个进入动作,被replace的那个就是false
+                return AnimationUtils.loadAnimation(context, animOutRes);
+            }
+        } else if (transit == FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) {
+            // todo: 2023/4/6 表示一个退出动作,比如出栈,hide,detach等
+            if (enter) {
+                // todo: 2023/4/6 之前被replace的重新进入到界面或者Fragment回到栈顶
+                return AnimationUtils.loadAnimation(context, animInRes);
+            } else {
+                // todo: 2023/4/6 Fragment退出,出栈
+                return AnimationUtils.loadAnimation(context, animOutRes);
+            }
+        }
+        return null
+    }
+}

+ 2 - 37
app/src/main/java/com/cr/pages/CrFragment.kt

@@ -4,19 +4,15 @@ import android.content.Context
 import android.os.Handler
 import android.os.Looper
 import android.view.View
-import android.view.animation.Animation
-import android.view.animation.AnimationUtils
 import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentTransaction
-import com.cr.cruav.R
 
 /**
  * 操作系统:MAC系统
  * 创建者:王成
- * 创建日期:2023/3/10 08:51
+ * 创建日期:2023/4/11 14:12
  * 描述:Fragment 公共基础类
  */
-open class CrFragment : Fragment() {
+open class CrFragment :Fragment(){
     // define: 2023/3/10 创建主线程Looper
     protected var mainHandler = Handler(Looper.getMainLooper())
 
@@ -26,7 +22,6 @@ open class CrFragment : Fragment() {
     // define: 2023/4/3 定义自身引用
     protected var self: Fragment? = null
 
-
     /**
      * 关联控件
      */
@@ -56,34 +51,4 @@ open class CrFragment : Fragment() {
     override fun getContext(): Context? {
         return mainView!!.context
     }
-
-    /**
-     * 重写左侧滑动动画效果
-     * @param transit Int
-     * @param enter Boolean
-     * @param nextAnim Int
-     * @return Animation?
-     */
-    override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
-        // todo: 2023/4/6 表示是一个进入动作,比如add.show等
-        if (transit == FragmentTransaction.TRANSIT_FRAGMENT_OPEN) {
-            if (enter) {
-                // todo: 2023/4/6 普通的进入的动作
-                return AnimationUtils.loadAnimation(context, R.anim.slide_left_in);
-            } else {
-                // todo: 2023/4/6 比如一个已经Fragment被另一个replace,是一个进入动作,被replace的那个就是false
-                return AnimationUtils.loadAnimation(context, R.anim.slide_left_out);
-            }
-        } else if (transit == FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) {
-            // todo: 2023/4/6 表示一个退出动作,比如出栈,hide,detach等
-            if (enter) {
-                // todo: 2023/4/6 之前被replace的重新进入到界面或者Fragment回到栈顶
-                return AnimationUtils.loadAnimation(context, R.anim.slide_left_in);
-            } else {
-                // todo: 2023/4/6 Fragment退出,出栈
-                return AnimationUtils.loadAnimation(context, R.anim.slide_left_out);
-            }
-        }
-        return null
-    }
 }

+ 2 - 1
app/src/main/java/com/cr/pages/CrNavigationFragment.kt

@@ -1,6 +1,7 @@
 package com.cr.pages
 
 import android.view.View
+import com.cr.data.CrUtil
 import com.cr.widget.CrNavigationBarWidget
 import com.cr.widget.CrNavigationBarWidget.CrNavigationBarListener
 
@@ -10,7 +11,7 @@ import com.cr.widget.CrNavigationBarWidget.CrNavigationBarListener
  * 创建日期:2023/3/10 08:51
  * 描述:Fragment 带导航栏的页面基础类
  */
-open class CrNavigationFragment : CrFragment(),CrNavigationBarListener{
+open class CrNavigationFragment : CrAnimationFragment(),CrNavigationBarListener{
     // define: 2023/3/30 导航栏定义
     var nvBar:CrNavigationBarWidget?=null
 

+ 1 - 3
app/src/main/java/com/cr/pages/FragmentFPV.kt

@@ -9,7 +9,6 @@ import android.view.ViewGroup
 import android.widget.Button
 import androidx.fragment.app.activityViewModels
 import com.cr.cruav.R
-import com.cr.data.CrUtil
 import com.cr.viewmodel.CrFlightControlVM
 import com.cr.viewmodel.CrVideoChannelListener
 import com.cr.viewmodel.CrVideoChannelVM
@@ -20,7 +19,6 @@ import dji.v5.common.video.decoder.VideoDecoder
 import dji.v5.common.video.interfaces.DecoderStateChangeListener
 import dji.v5.common.video.interfaces.IVideoChannel
 import dji.v5.common.video.interfaces.IVideoDecoder
-import kotlinx.android.synthetic.main.frag_fpv.*
 
 
 /**
@@ -29,7 +27,7 @@ import kotlinx.android.synthetic.main.frag_fpv.*
  * 创建日期:2023/3/10 08:50
  * 描述:图传窗口
  */
-class FragmentFPV : CrFragment(), SurfaceHolder.Callback {
+class FragmentFPV : CrAnimationFragment(), SurfaceHolder.Callback {
     /**
      * FPV窗口监听
      */

+ 1 - 1
app/src/main/java/com/cr/pages/FragmentMap.kt

@@ -16,7 +16,7 @@ import com.esri.arcgisruntime.mapping.view.MapView
  * 创建日期:2023/3/14 09:51
  * 描述:地图界面
  */
-class FragmentMap : CrFragment() {
+class FragmentMap : CrAnimationFragment() {
     // define: 2023/3/14 地图容器
     private var mapView: MapView?= null
     // define: 2023/3/14 地图

+ 194 - 0
app/src/main/java/com/cr/pages/FragmentSet.kt

@@ -0,0 +1,194 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.viewpager2.adapter.FragmentStateAdapter
+import androidx.viewpager2.widget.ViewPager2
+import com.cr.adapter.SettingAdapter
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.models.SettingAction
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/10 17:45
+ * 描述:设置管理页面
+ */
+class FragmentSet : CrNavigationFragment() {
+    // define: 2023/4/11 定义变量
+    private var adapter:CrPageAdapter? = null
+
+    // define: 2023/4/11 定义页面
+    private var pageMain:FragmentSetMain? = null
+    private var pageSetIpAndCom:FragmentSetIpAndCom? = null
+    private var pageDownloadData:FragmentSetDataDownload? = null
+
+    // define: 2023/4/11 定义控件
+    private var viewPager: ViewPager2?=null
+    /**
+     * 创建视图
+     * @param inflater LayoutInflater 视图管理器
+     * @param container ViewGroup? 视图组
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // todo: 2023/4/11 设置动画方向
+        setAnimationDirection(AnimationDirection.RIGHT)
+        self = this
+        mainView = inflater.inflate(R.layout.frag_set,null)
+        // todo: 2023/4/10 设置导航栏
+        setBar(R.id.nv)
+        // todo: 2023/4/11 挂载控件
+        joinControls()
+        // todo: 2023/4/11 初始化页面
+        initPages()
+        return mainView
+    }
+
+    /**
+     * 初始化导航栏
+     */
+    private fun initBar(){
+        nvBar?.crSetTitle(R.string.nv_title_set)
+        nvBar?.crSetVisible(backIsVisible = false, dismissIsVisible = true)
+        showPage(pageMain!!)
+    }
+
+    /**
+     * 初始化页面
+     */
+    private fun initPages(){
+        adapter = CrPageAdapter(this.activity!!)
+        // todo: 2023/4/11 初始化主页面
+        pageMain = FragmentSetMain()
+        pageMain?.setCallback(mainListener)
+        adapter?.addFragment(pageMain!!)
+
+        // todo: 2023/4/11 初始化设置Ip和Com页面
+        pageSetIpAndCom = FragmentSetIpAndCom()
+        pageSetIpAndCom?.setAnimationDirection(AnimationDirection.RIGHT)
+        adapter?.addFragment(pageSetIpAndCom!!)
+
+        // todo: 2023/4/11 初始化数据下载页面
+        pageDownloadData = FragmentSetDataDownload()
+        adapter?.addFragment(pageDownloadData!!)
+
+        // todo: 2023/4/11 设置监听
+        viewPager?.adapter = adapter
+
+        // todo: 2023/4/11 初始化导航栏和页面
+        initBar()
+    }
+
+    /**
+     * 显示页面
+     * @param fragment CrFragment
+     */
+    private fun showPage(fragment: CrNavigationFragment){
+        var fragments = adapter?.getFragments()
+        for(i in 0 until fragments!!.size){
+            if(fragments?.get(i) == fragment){
+                fragment.nvBar?.visibility = View.GONE
+                viewPager?.currentItem = i
+            }
+        }
+    }
+
+    /**
+     * 菜单点击监听
+     */
+    private var mainListener =  object:SettingAdapter.SettingListener{
+        // todo: 2023/4/11 动作监听
+        override fun onAction(action: SettingAction) {
+            when(action){
+                SettingAction.SA_SET_IP_COM->{
+                    showPage(pageSetIpAndCom!!)
+                    nvBar?.crSetVisible(backIsVisible = true, dismissIsVisible = false)
+                    nvBar?.crSetTitle(R.string.nv_title_set_ip_and_com)
+                }
+                SettingAction.SA_DOWNLOAD_DATA->{
+                    showPage(pageDownloadData!!)
+                    nvBar?.crSetVisible(backIsVisible = true, dismissIsVisible = false)
+                    nvBar?.crSetTitle(R.string.nv_title_download)
+                }
+            }
+        }
+
+        // todo: 2023/4/11 开关监听
+        override fun onSwitch(action: SettingAction, isChecked: Boolean) {
+
+        }
+
+    }
+
+    /**
+     * 页面适配器
+     * @constructor
+     */
+    private class CrPageAdapter@JvmOverloads constructor(
+        activity:FragmentActivity
+    ): FragmentStateAdapter(activity){
+        private val mFragmentList: MutableList<CrNavigationFragment> = ArrayList()
+
+        /**
+         * 添加页面
+         * @param fragment CrFragment
+         */
+        fun addFragment(fragment:CrNavigationFragment){
+            mFragmentList.add(fragment)
+        }
+
+        /**
+         * 获取加载的页面
+         * @return MutableList<Fragment>
+         */
+        fun getFragments(): MutableList<CrNavigationFragment> {
+            return mFragmentList
+        }
+
+        // todo: 2023/4/11 页面数量
+        override fun getItemCount(): Int {
+            return mFragmentList.size
+        }
+
+        // todo: 2023/4/11 当前页面
+        override fun createFragment(position: Int): Fragment {
+            return mFragmentList[position]
+        }
+
+    }
+
+    /**
+     * 挂载控件
+     */
+    override fun joinControls() {
+        viewPager = mainView?.findViewById(R.id.frag_set_pages)
+        viewPager?.isUserInputEnabled = false
+    }
+
+    /**
+     * 重写关闭事件
+     */
+    override fun dismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!,BarAction.ACTION_DISMISS))
+    }
+
+    /**
+     * 重写回退事件
+     */
+    override fun onGotoBack() {
+        initBar()
+    }
+}

+ 75 - 0
app/src/main/java/com/cr/pages/FragmentSetDataDownload.kt

@@ -0,0 +1,75 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ListView
+import com.cr.adapter.DownloadDataAdapter
+import com.cr.cruav.R
+import com.cr.data.CrUtil
+import com.cr.models.DownloadDataModel
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 16:03
+ * 描述:数据下载页面
+ */
+class FragmentSetDataDownload:CrNavigationFragment() {
+    // define: 2023/4/11 定义控件
+    private var listView:ListView? = null
+
+    // define: 2023/4/11 定义变量
+    private var dataList:MutableList<DownloadDataModel> = mutableListOf()
+    private var downloadAdapter:DownloadDataAdapter?=null
+    /**
+     * 创建视图
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        self = this
+        mainView = inflater.inflate(R.layout.frag_set_data_download,null)
+        // todo: 2023/4/11 挂载控件
+        joinControls()
+        // todo: 2023/4/11 初始化页面
+        initPage()
+        return mainView
+    }
+
+    /**
+     * 重写挂载控件
+     */
+    override fun joinControls() {
+        // todo: 2023/4/11 挂载列表控件
+        listView = mainView?.findViewById(R.id.list_view)
+    }
+
+    /**
+     * 重写初始化页面
+     */
+    override fun initPage() {
+        dataList.clear()
+        dataList.add(DownloadDataModel("矢量地图集", "base.geodatabase", false))
+        dataList.add(DownloadDataModel("编辑地图集", "map.geodatabase", false))
+        dataList.add(DownloadDataModel("飞行数据库", "data.sqlite", false))
+        dataList.add(DownloadDataModel("基础配置库", "config.sqlite", false))
+        downloadAdapter = DownloadDataAdapter(context!!,dataList)
+        listView?.adapter = downloadAdapter
+    }
+
+    override fun onHiddenChanged(hidden: Boolean) {
+        CrUtil.showMessage(hidden.toString())
+        super.onHiddenChanged(hidden)
+        if(!hidden){
+            initPage()
+        }
+    }
+}

+ 1 - 1
app/src/main/java/com/cr/pages/FragmentSetIpAndCom.kt

@@ -53,7 +53,7 @@ class FragmentSetIpAndCom : CrNavigationFragment(),View.OnClickListener{
         mainView = inflater.inflate(R.layout.frag_set_ip_and_com, null)
         // todo: 2023/3/30 设置导航栏
         setBar(R.id.nv)
-        setBarVisible(true)
+        setBarVisible(isVisible = false)
         // todo: 2023/3/30 关联组件
         joinControls()
         // todo: 2023/3/30 初始化显示

+ 214 - 0
app/src/main/java/com/cr/pages/FragmentSetMain.kt

@@ -0,0 +1,214 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ListView
+import com.cr.adapter.SettingAdapter
+import com.cr.common.CrSaveManager
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.models.SetItemModel
+import com.cr.models.SettingAction
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/11 09:10
+ * 描述:设置-主页面
+ */
+class FragmentSetMain : CrNavigationFragment() {
+    // define: 2023/4/11 菜单数组
+    private var menuList: MutableList<SetItemModel> = mutableListOf()
+
+    // define: 2023/4/11 定义组件
+    private var listView: ListView? = null
+
+    // define: 2023/4/11 定义监听器
+    private var listener: SettingAdapter.SettingListener? = null
+
+    /**
+     * 初始化
+     * @param inflater LayoutInflater 视图管理器
+     * @param container ViewGroup? 视图组
+     * @param savedInstanceState Bundle? 状态
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // todo: 2023/4/11 设置动画方向
+        setAnimationDirection(AnimationDirection.RIGHT)
+        self = this
+        // todo: 2023/4/11 创建视图
+        mainView = inflater.inflate(R.layout.frag_set_main, null)
+        // todo: 2023/4/11 挂载控件
+        joinControls()
+        // todo: 2023/4/11 初始化菜单
+        initMenu()
+        return mainView
+    }
+
+    /**
+     * 初始化菜单
+     */
+    private fun initMenu() {
+        // todo: 2023/4/11 清除
+        menuList.clear()
+        menuList.add(
+            SetItemModel(
+                R.drawable.ico_user,
+                "登录大疆账号",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_DJI_LOGIN,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.tools_download,
+                "数据下载",
+                isArrow = true,
+                isSwitch = false,
+                action = SettingAction.SA_DOWNLOAD_DATA,
+                switchIsOn = false
+            )
+        )
+        // TODO: 6/4/21 获取地图居中状态 设置是否开关
+        val isCenter: Boolean = CrSaveManager.getInstance().getMapCenter() == true
+        menuList.add(
+            SetItemModel(
+                R.drawable.ico_old_map,
+                "飞行器地图居中",
+                isArrow = false,
+                isSwitch = true,
+                action = SettingAction.SA_MAP_CENTER,
+                switchIsOn = isCenter
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.tools_set,
+                "设置服务器的IP和端口",
+                isArrow = true,
+                isSwitch = false,
+                action = SettingAction.SA_SET_IP_COM,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.dji_aircraft,
+                "历史航线",
+                isArrow = true,
+                isSwitch = false,
+                action = SettingAction.SA_OLD_AIRLINE,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.goto_back,
+                "重新登录系统",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_RE_LOGIN,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.tools_deleteall,
+                "清除地图缓存",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_DEL_MAP_CACHE,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.tools_mession,
+                "查看飞行记录",
+                isArrow = true,
+                isSwitch = false,
+                action = SettingAction.SA_SHOW_DJI_LOG,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.tools_upload,
+                "上传断网航点",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_UPLOAD_NO_UP_AIR_POINT,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.ico_multimage,
+                "删除取证数据",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_DEL_QZ_DATA,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.ty_save,
+                "删除航线数据",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_DEL_LINE_DATA,
+                switchIsOn = false
+            )
+        )
+        menuList.add(
+            SetItemModel(
+                R.drawable.ty_delete,
+                "删除资源数据",
+                isArrow = false,
+                isSwitch = false,
+                action = SettingAction.SA_DEL_RESOURCE_DATA,
+                switchIsOn = false
+            )
+        )
+        // todo: 2023/4/11 设置适配器
+        var adapter = SettingAdapter(context, menuList)
+        adapter.listener = listener
+        listView?.adapter = adapter
+    }
+
+    /**
+     * 重写挂载控件方法
+     */
+    override fun joinControls() {
+        // todo: 2023/4/11 挂载列表
+        listView = mainView?.findViewById(R.id.frm_set_main_listview)
+    }
+
+
+    /**
+     * 重写关闭事件
+     */
+    override fun dismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
+    }
+
+    /**
+     * 设置回调监听
+     * @param listener SettingListener
+     */
+    fun setCallback(listener: SettingAdapter.SettingListener){
+        this.listener = listener
+    }
+}

+ 46 - 0
app/src/main/java/com/cr/ui/CrNoScrollViewPager.kt

@@ -0,0 +1,46 @@
+package com.cr.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import androidx.viewpager.widget.ViewPager
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/10 17:21
+ * 描述:禁止或允许的滑动分页组件
+ */
+class CrNoScrollViewPager@JvmOverloads constructor(
+    context: Context,
+    attrs:AttributeSet? = null
+): ViewPager(context,attrs) {
+    // define: 2023/4/10 是否允许滑动
+    var isScroll:Boolean = false
+
+    /**
+     * 重写触摸事件
+     * @param ev MotionEvent 事件
+     * @return Boolean 是否拦截
+     */
+    override fun onTouchEvent(ev: MotionEvent?): Boolean {
+        return isScroll
+    }
+
+    /**
+     * 重写方法
+     * @param ev MotionEvent 事件
+     * @return Boolean 是否拦截
+     */
+    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+        return isScroll
+    }
+
+    /**
+     * 设置是否拦截事件
+     * @param isScroll Boolean 是否拦截
+     */
+    fun crSetIsScroll(isScroll:Boolean){
+        this.isScroll = isScroll
+    }
+}

+ 26 - 0
app/src/main/java/com/cr/widget/CrNavigationBarWidget.kt

@@ -96,4 +96,30 @@ class CrNavigationBarWidget @JvmOverloads constructor(
                 listener?.onDismiss()
         }
     }
+
+    /**
+     * 设置按钮的显示或隐藏
+     * @param backIsVisible Boolean
+     * @param dismissIsVisible Boolean
+     */
+    fun crSetVisible(backIsVisible: Boolean, dismissIsVisible: Boolean) {
+        lblLeft!!.visibility = if (backIsVisible) VISIBLE else GONE
+        lblRight!!.visibility = if (dismissIsVisible) VISIBLE else GONE
+    }
+
+    /**
+     * 设置标题
+     * @param title 标题
+     */
+    fun crSetTitle(title: String?) {
+        lblTitle!!.text = title
+    }
+
+    /**
+     * 设置显示标题
+     * @param titleRes Int
+     */
+    fun crSetTitle(titleRes:Int){
+        lblTitle!!.setText(titleRes)
+    }
 }

+ 10 - 0
app/src/main/res/anim/slide_right_in.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:duration = "800"
+        android:toXDelta="0.0"
+        android:fromXDelta="100.0%p"/>
+    <alpha android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:duration="800"/>
+</set>

+ 9 - 0
app/src/main/res/anim/slide_right_out.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate android:toXDelta="100.0%"
+        android:fromXDelta="0.0"
+        android:duration="800"/>
+    <alpha android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:duration="800"/>
+</set>

BIN
app/src/main/res/drawable/goto_back.png


BIN
app/src/main/res/drawable/ico_aircraft.png


BIN
app/src/main/res/drawable/ico_airstate.png


BIN
app/src/main/res/drawable/ico_area.png


BIN
app/src/main/res/drawable/ico_arrow_right.png


BIN
app/src/main/res/drawable/ico_back.png


BIN
app/src/main/res/drawable/ico_basemap_raster.png


BIN
app/src/main/res/drawable/ico_basemap_vector.png


BIN
app/src/main/res/drawable/ico_bmap_v.png


BIN
app/src/main/res/drawable/ico_camera_phoshop.png


BIN
app/src/main/res/drawable/ico_camera_record.png


BIN
app/src/main/res/drawable/ico_case_tools.png


BIN
app/src/main/res/drawable/ico_check_no.png


BIN
app/src/main/res/drawable/ico_check_yes.png


BIN
app/src/main/res/drawable/ico_clear.png


BIN
app/src/main/res/drawable/ico_draw_blue.png


BIN
app/src/main/res/drawable/ico_draw_green.png


BIN
app/src/main/res/drawable/ico_draw_red.png


BIN
app/src/main/res/drawable/ico_hisdata.png


BIN
app/src/main/res/drawable/ico_identify_localcase.png


BIN
app/src/main/res/drawable/ico_identify_netcase.png


+ 0 - 0
app/src/main/res/drawable/ico_ifno.png → app/src/main/res/drawable/ico_info.png


BIN
app/src/main/res/drawable/ico_layer.png


BIN
app/src/main/res/drawable/ico_left.png


BIN
app/src/main/res/drawable/ico_length.png


BIN
app/src/main/res/drawable/ico_location.png


BIN
app/src/main/res/drawable/ico_media_cur.png


BIN
app/src/main/res/drawable/ico_media_net.png


BIN
app/src/main/res/drawable/ico_media_old.png


BIN
app/src/main/res/drawable/ico_mession.png


BIN
app/src/main/res/drawable/ico_multimage.png


BIN
app/src/main/res/drawable/ico_old_down.png


BIN
app/src/main/res/drawable/ico_old_map.png


BIN
app/src/main/res/drawable/ico_old_time.png


BIN
app/src/main/res/drawable/ico_repeatflight_no.png


BIN
app/src/main/res/drawable/ico_repeatflight_yes.png


BIN
app/src/main/res/drawable/ico_tools_add_map_repeatflight.png


BIN
app/src/main/res/drawable/ico_tools_case_map_sel.png


BIN
app/src/main/res/drawable/ico_ty.png


BIN
app/src/main/res/drawable/ico_ty1.png


BIN
app/src/main/res/drawable/ico_upload_case.png


BIN
app/src/main/res/drawable/ico_upload_wj.png


BIN
app/src/main/res/drawable/ico_wj_no.png


BIN
app/src/main/res/drawable/ico_wj_upload_yes.png


BIN
app/src/main/res/drawable/icon_layer_draw.png


BIN
app/src/main/res/drawable/icon_layer_other1.png


BIN
app/src/main/res/drawable/icon_layer_other2.png


BIN
app/src/main/res/drawable/icon_layer_tiled.png


BIN
app/src/main/res/drawable/icon_layer_vector.png


BIN
app/src/main/res/drawable/img.png


+ 5 - 0
app/src/main/res/drawable/item_click_normal.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!--填充色-->
+    <solid android:color="#000099ff" />
+</shape>

+ 5 - 0
app/src/main/res/drawable/item_click_select.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!--填充色-->
+    <solid android:color="#0099ff" />
+</shape>

+ 5 - 0
app/src/main/res/drawable/item_click_selector.xml

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

+ 48 - 0
app/src/main/res/drawable/progress_bar.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 进度条背景色 -->
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="5dip" />
+            <gradient
+                android:startColor="#ff9d9e9d"
+                android:centerColor="#ff5a5d5a"
+                android:centerY="0.75"
+                android:endColor="#ff747674"
+                android:angle="270"
+                />
+        </shape>
+    </item>
+
+    <!-- 第二进度条 -->
+    <item android:id="@android:id/secondaryProgress">
+        <clip>
+            <shape>
+                <corners android:radius="5dip" />
+                <gradient
+                    android:startColor="#b9a4ff"
+                    android:centerColor="#c6b7ff"
+                    android:centerY="0.75"
+                    android:endColor="#c3b2ff"
+                    android:angle="270"
+                    />
+            </shape>
+        </clip>
+    </item>
+
+    <!-- 第二进度条 -->
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="5dip" />
+                <gradient
+                    android:startColor="#57e8ff"
+                    android:centerColor="#74ebff"
+                    android:centerY="0.75"
+                    android:endColor="#8eefff"
+                    android:angle="270"
+                    />
+            </shape>
+        </clip>
+    </item>
+</layer-list>

+ 2 - 2
app/src/main/res/layout/av_login.xml

@@ -123,11 +123,11 @@
             style="@style/login_bottom_lbl_style"
             android:text="@string/login_technical_support" />
     </LinearLayout>
-    <!--侧弹窗容器-->
+    <!--侧弹窗容器-->
     <FrameLayout
         android:id="@+id/av_frm_left_panel"
         android:layout_width="@dimen/cr_200_dp"
         android:layout_height="match_parent"
         android:orientation="vertical"/>
-    <!--左侧弹窗容器-->
+
 </RelativeLayout>

+ 8 - 0
app/src/main/res/layout/av_main.xml

@@ -93,4 +93,12 @@
         app:layout_constraintTop_toBottomOf="@id/av_fragment_top">
         <include layout="@layout/tools_top"/>
     </LinearLayout>
+    <!--右侧弹窗容器-->
+    <FrameLayout
+        android:id="@+id/av_frm_right_panel"
+        android:layout_width="@dimen/cr_200_dp"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/av_fragment_top"/>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
app/src/main/res/layout/dig_normal.xml

@@ -13,7 +13,7 @@
         <ImageView
             android:layout_width="@dimen/cr_24_dp"
             android:layout_height="@dimen/cr_24_dp"
-            android:src="@drawable/ico_ifno"
+            android:src="@drawable/ico_info"
             android:layout_gravity="center"
             android:layout_margin="@dimen/common_margin"/>
         <TextView

+ 46 - 0
app/src/main/res/layout/dig_progress.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center">
+    <LinearLayout
+        android:layout_width="@dimen/cr_160_dp"
+        android:layout_height="@dimen/cr_100_dp"
+        android:background="@drawable/shape_back_dialog_normal"
+        android:orientation="vertical"
+        android:padding="@dimen/cr_8_dp"
+        android:gravity="center">
+        <TextView
+            style="@style/lbl_title_common"
+            android:text="下载进度..."
+            android:textColor="@color/white"
+            android:textSize="@dimen/sp_18"
+            android:layout_gravity="center"
+            android:layout_marginTop="@dimen/common_padding"
+            android:layout_marginBottom="@dimen/common_padding"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/cr_20_dp"
+            android:layout_marginTop="@dimen/common_padding"
+            android:layout_marginBottom="@dimen/common_padding">
+            <TextView
+                style="@style/lbl_title_common"
+                android:text="1/1"
+                android:id="@+id/dig_progress_title"/>
+            <TextView
+                style="@style/lbl_title_common"
+                android:layout_weight="1"/>
+            <TextView
+                style="@style/lbl_title_common"
+                android:text="100.0%"
+                android:id="@+id/dig_progress_progress"/>
+        </LinearLayout>
+        <ProgressBar
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/cr_5_dp"
+            style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+            android:progressDrawable="@drawable/progress_bar"
+            android:id="@+id/dig_progress_bar"/>
+    </LinearLayout>
+</LinearLayout>

+ 25 - 0
app/src/main/res/layout/frag_set.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:clickable="true">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/shape_back_fragment"
+        android:orientation="vertical">
+        <com.cr.widget.CrNavigationBarWidget
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:crTitle="@string/nv_title_set"
+            app:isGotoBack="false"
+            app:isDismiss="true"
+            android:id="@+id/nv"
+            android:layout_weight="0"/>
+        <androidx.viewpager2.widget.ViewPager2
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/frag_set_pages"/>
+    </LinearLayout>
+</RelativeLayout>

+ 20 - 0
app/src/main/res/layout/frag_set_data_download.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:clickable="true">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/shape_back_fragment"
+        android:orientation="vertical">
+        <ListView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:divider="@null"
+            android:dividerHeight="0dp"
+            android:id="@+id/list_view"/>
+    </LinearLayout>
+</RelativeLayout>

+ 20 - 0
app/src/main/res/layout/frag_set_main.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:clickable="true">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/shape_back_fragment"
+        android:orientation="vertical">
+        <ListView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:divider="@null"
+            android:dividerHeight="0dp"
+            android:id="@+id/frm_set_main_listview"/>
+    </LinearLayout>
+</RelativeLayout>

+ 56 - 0
app/src/main/res/layout/item_data_download.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/cr_34_dp"
+        android:orientation="vertical"
+        android:padding="@dimen/common_padding">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:layout_weight="1">
+            <ImageView
+                android:layout_width="@dimen/cr_16_dp"
+                android:layout_height="@dimen/cr_16_dp"
+                android:src="@drawable/tools_downloadnetwork"
+                android:layout_weight="0"/>
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:textColor="@color/white"
+                android:textSize="15sp"
+                android:text="设置"
+                android:layout_marginLeft="5dp"
+                android:layout_weight="1"
+                android:id="@+id/item_down_title"
+                android:gravity="center_vertical"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="A"
+                android:textSize="14sp"
+                android:textColor="@color/white"
+                android:layout_marginRight="@dimen/cr_10_dp"
+                android:id="@+id/item_down_state"/>
+            <ImageView
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:src="@drawable/tools_download"
+                android:layout_weight="0"
+                android:id="@+id/item_down_down"
+                android:layout_marginRight="@dimen/cr_10_dp"/>
+        </LinearLayout>
+        <ProgressBar
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/cr_5_dp"
+            style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+            android:progressDrawable="@drawable/progress_bar"
+            android:id="@+id/item_down_bar"/>
+        <View style="@style/view_split_h1"/>
+    </LinearLayout>
+</LinearLayout>

+ 53 - 0
app/src/main/res/layout/item_set.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="@dimen/common_padding">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/cr_24_dp"
+        android:orientation="vertical">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:layout_weight="1">
+            <ImageView
+                android:layout_width="@dimen/cr_16_dp"
+                android:layout_height="@dimen/cr_16_dp"
+                android:src="@drawable/tools_set"
+                android:layout_weight="0"
+                android:id="@+id/item_set_img"/>
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:textColor="@color/white"
+                android:textSize="@dimen/sp_11"
+                android:text="设置"
+                android:layout_marginLeft="@dimen/cr_5_dp"
+                android:layout_weight="1"
+                android:id="@+id/item_set_title"
+                android:gravity="center_vertical"
+                android:background="@drawable/item_click_selector"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:text="A"
+                android:textSize="14sp"
+                android:textColor="@color/white"
+                android:layout_marginRight="@dimen/cr_10_dp"
+                android:id="@+id/item_set_arrow"/>
+            <Switch
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:layout_marginRight="@dimen/cr_10_dp"
+                android:track="@drawable/switch_track"
+                android:thumb="@drawable/switch_thumb"
+                android:id="@+id/item_set_switch"/>
+        </LinearLayout>
+        <View style="@style/view_split_h1"/>
+    </LinearLayout>
+</LinearLayout>