wjc
2023-03-28 0446b122504b83aef39087e91a960d53920bec05
2023年03月28日13:26:53

wjc
6个文件已添加
5个文件已修改
1555 ■■■■■ 已修改文件
HDL_ON/Common/Constant.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/Common/HDLCommon.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/Entity/Function/Function.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/HDL_ON.projitems 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/3-Intelligence/Automation/ConditionDeviceFunList.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/CommonMethod.cs 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/ObjectClass.cs 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/StackTraceLog.cs 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideDoorLockSend.cs 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideoDoorLockListPage.cs 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideoDoorLockPage.cs 511 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/Common/Constant.cs
@@ -309,6 +309,7 @@
        /// HDL可视对讲
        /// </summary>
        HDL_INTERPHONE,
        DOOR_BELL,
    }
    /// <summary>
HDL_ON/Common/HDLCommon.cs
@@ -397,7 +397,7 @@
                                return;
                            }
                            ///视频门锁
                            HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock.CommonMethod.Current.SkipRTVActivity(expantContent.devSerial, expantContent.deviceId,expantContent.spk,true);
                            HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock.CommonMethod.Current.SkipRTVActivity(expantContent.devSerial, expantContent.deviceId,expantContent.spk);
                        }
                        catch { }
                    }
HDL_ON/Entity/Function/Function.cs
@@ -1375,6 +1375,10 @@
        /// </summary>
        public const string DoorLock = "security.door";
        /// <summary>
        /// 萤石视屏门锁
        /// </summary>
        public const string VideoDoorLock = "security.door.ezviz";
        /// <summary>
        /// 门锁spk列表
        /// </summary>
        /// <returns></returns>
HDL_ON/HDL_ON.projitems
@@ -528,6 +528,12 @@
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\Music\A31UsbMusicList.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\Music\CommonMethod.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\Music\A31FlieList.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\VideDoorLockSend.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\StackTraceLog.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\ObjectClass.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\CommonMethod.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\VideoDoorLockPage.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)UI\UI2\FuntionControlView\VideoDoorLock\VideoDoorLockListPage.cs" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="$(MSBuildThisFileDirectory)Entity\Device\" />
HDL_ON/UI/UI2/3-Intelligence/Automation/ConditionDeviceFunList.cs
@@ -628,7 +628,7 @@
                        view1.btnClick.MouseUpEventHandler += (sender, e) =>
                        {
                            this.identifier = "open_door";//开锁事件
                            this.VideoDoorLockAction(this, device, view1.btnState);
                            //this.VideoDoorLockAction(this, device, view1.btnState);
                        };
                        if (edit)
                        {
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/CommonMethod.cs
New file
@@ -0,0 +1,451 @@
using System;
using HDL_ON.Entity;
using System.Collections.Generic;
using Shared;
namespace HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock
{
    /// <summary>
    /// 萤石视频门锁公共方法类
    /// </summary>
    public class CommonMethod
    {
        private Loading loading;
        /// <summary>
        /// 记录当前界面索引值
        /// </summary>
        private int pageLayoutIndexValue;
        private static CommonMethod commonMethod = null;
        /// <summary>
        /// 获取对象
        /// </summary>
        public static CommonMethod Current
        {
            get
            {
                if (commonMethod == null)
                {
                    commonMethod = new CommonMethod();
                }
                return commonMethod;
            }
        }
        #region  --------- 跳转到Android那边的方法(萤石视频门锁) --------
        /// <summary>
        /// 读取云端的上设备列表(android源生添加设备到云端成功后)
        /// <paramref name="devSerial"/>设备序列号</param>
        /// </summary>
        public void SkipAddDeviceActivity(string devSerial)
        {
#if __IOS__
#else
            this.InitializationAndroidData((isBools) =>
            {
                if (!isBools) {
                    this.MainThread(()=> {
                        this.ShowTip("先获取萤石云子账号token失败。");
                    });
                }
                HDLEzvizSdk.Instance.JumpToEZScanActivity(Application.Activity);
                HDLEzvizSdk.SetAddCallback(new AndroidIHdlInterface((isBool, adnroidActionDevSerial) =>
                {
                    if (isBool)
                    {
                        var list = VideDoorLockSend.Current.GetVideoDoorLockDeviceList(SPK.VideoDoorLock);
                        if (list.Count > 0)
                        {
                            var function = list.Find((o) => o.sid == adnroidActionDevSerial);
                            if (function != null)
                            {
                                this.SaveFunctionFile(function);
                            }
                        }
                    }
                }));
            });
#endif
        }
        /// <summary>
        /// 打开实时视频画面
        /// </summary>
        /// <param name="deviceSerial">设备序列号</param>
        /// <param name="deviceId">设备id(云端上deviceId)</param>
        /// <param name="spk">设备spk(云雀上定义好的)</param>
        public void SkipRTVActivity(string deviceSerial, string deviceId, string spk)
        {
            #if __IOS__
#else
            this.InitializationAndroidData((isBools) =>
            {
                if (!isBools)
                {
                    this.MainThread(() => {
                        this.ShowTip("先获取萤石云子账号token失败。");
                    });
                }
                Video.View.ShowDialog.Currnet.ClickBox(Language.StringByID(StringId.laizimenlinghujiao), (dialog) =>
                {
                    dialog.Close();
                    HDLEzvizSdk.Instance.JumpToEZRealPlayActivity(Application.Activity,deviceId,deviceSerial,spk);
                }, (dialog) =>
                {
                    dialog.Close();
                });
            });
#endif
        }
        /// <summary>
        /// 浏览历史记录
        /// </summary>
        public void SkipRecordActivity(string deviceId)
        {
            this.InitializationAndroidData((s)=> {
                //HDLEzvizSdk.Instance.JumpLockHistoryActivity(Application.Activity, deviceId);
            });
            //未实现
            //this.InitializationAndroidData();
            //
        }
        /// <summary>
        /// 临时密码开门
        /// <paramref name="deviceId"/>
        /// </summary>
        public void SkipPSWActivity(string deviceId)
        {
#if __IOS__
#else
            this.InitializationAndroidData((isBools) =>
            {
                if (!isBools)
                {
                    this.MainThread(() =>
                    {
                        this.ShowTip("先获取萤石云子账号token失败。");
                    });
                }
                HDLEzvizSdk.Instance.JumpTempPasswordActivity(Application.Activity, deviceId);
            });
#endif
        }
        /// <summary>
        /// 初始化萤石SDK(实际就是传参数,多次调用也没有影响)
        /// </summary>
        public void InitializationAndroidData(Action<bool> action)
        {
            bool isBool = true;
            this.SunThread(() =>
            {
                try
                {
                    //先获取萤石云子账号token
                    var ezChildAccessToken = VideDoorLockSend.Current.GetEZGetChildToken();
                    this.MainThread(() =>
                    {
                        if (string.IsNullOrEmpty(ezChildAccessToken))
                        {
                            //Token
                            isBool = false;
                            return;
                        }
                        Application.RunOnMainThread(() =>
                        {
#if __IOS__
                                ////iOS
                                ////初始化萤石云SDK,中文国内key、英文海外key 开发者账号使用应用包名申请的APPKEY,不同包名应用需配置不同的APPKEY
                                //EZSDK.IOS.EZSDK.SharedInstance().InitLibWithAppKey("1aa98a90489b4838b966b57018b4b04b", "1aa98a90489b4838b966b57018b4b04b");
                                ////1.设置所需河东的AccessToken和RefreshToken、域名地址
                                //EZSDK.IOS.EZSDK.SharedInstance().SetHDlAccessToken(UserVideoDoorLockInfo.Current.LoginTokenString, UserVideoDoorLockInfo.Current.RefreshToken);
                                //EZSDK.IOS.EZSDK.SharedInstance().SetRequestHttpsHostAndPlatform(OnAppConfig.Instance.RequestHttpsHost, 1, DB_ResidenceData.Instance.CurrentRegion.id);
                                ////2.设置萤石子账号的AccessToken到SDK
                                //EZSDK.IOS.EZSDK.SharedInstance().SetEZAccessToken(ezChildAccessToken);
                                //////3.打开摄像头设备列表页面
                                //EZSDK.IOS.EZSDK.SharedInstance().Go2EZvizMonitor();
                                ////EZSDK.IOS.EZDeviceInfo info = new EZSDK.IOS.EZDeviceInfo();
                                ////info.de
                                ////EZSDK.IOS.EZSDK.Play(info);
#else
                            HDLEzvizSdk.Instance.Init(Application.Activity.Application, ezChildAccessToken, UserInfo.Current.LoginTokenString, UserInfo.Current.RefreshToken, OnAppConfig.Instance.RequestHttpsHost, "1aa98a90489b4838b966b57018b4b04b", 1, DB_ResidenceData.Instance.CurrentRegion.id);
#endif
                        });
                    });
                }
                catch (Exception e)
                {
                }
                finally
                {
                    this.MainThread(() =>
                    {
                        action?.Invoke(isBool);
                    });
                }
            });
        }
        /// <summary>
        /// 更换住宅
        /// </summary>
        /// <param name="home">对象</param>
        public void ChangeCurrHome(RegionInfoRes home)
        {
            if (DB_ResidenceData.Instance.CurrentRegion.id == home.id || string.IsNullOrEmpty(home.id)) return;
        }
#endregion
        /// <summary>
        /// 萤石视频门锁的图标
        /// <param name="comerom">来自那里</param>
        /// </summary>
        public string GetVideoDoorLockIcon(Comerom comerom)
        {
            if (comerom == Comerom.collect)
            {
                return "FunctionIcon/DoorLock/VideoDoorLockOpen.png";
            }
            else
            {
                return "FunctionIcon/DoorLock/VideoDoorlockClose.png";
            }
        }
#region  --------- 功能文件保存,删除 --------
        /// <summary>
        /// 保存本地文件
        /// </summary>
        /// <param name="function">当前设备</param>
        public void SaveFunctionFile(Function function)
        {
            if (function == null) return;
            function.AssembleStatus();
            function.SaveFunctionFile();
            FunctionList.List.IniFunctionList(function.savePath, true);
            MainPage.Log($"文件保存->{function.name}-->{function.spk}");
        }
        /// <summary>
        /// 删除本地文件
        /// </summary>
        /// <param name="function">当前设备</param>
        public void DeleteFunction(Function function)
        {
            if (function == null) return;
            FunctionList.List.DeleteFunction(function);
            MainPage.Log($"文件删除->{function.name}-->{function.spk}");
        }
#endregion
        /// <summary>
        /// 获取Loading对象
        /// </summary>
        /// <returns></returns>
        public Loading Loading
        {
            get
            {
                this.MainThread(() =>
                {
                    //if (loading != null && this.pageLayoutIndexValue == MainPage.BasePageView.ChildrenCount - 1)
                    //{
                    //    //防止二重添加对象
                    //    return;
                    //}
                    if (loading == null)//|| MainPage.BasePageView.ChildrenCount < 1)
                    {
                        loading = new Loading();
                    }
                    //loading.BringToFront();
                    Application.MainPage.AddChidren(loading);
                    //View view = MainPage.BasePageView.GetChildren(MainPage.BasePageView.ChildrenCount - 1);
                    //if (view is ViewGroup)
                    //{
                    //    pageLayoutIndexValue = MainPage.BasePageView.ChildrenCount - 1;
                    //    ((ViewGroup)view).AddChidren(loading);
                    //}
                });
                return loading;
            }
        }
        /// <summary>
        /// 获取萤石视频门锁列表
        /// </summary>
        /// <returns></returns>
        public List<Function> GetVideoDoorLockList()
        {
            //var list = FunctionList.List.GetVideoDoorLockList();
#if DEBUG
            //list.Add(new Function { name = "视频门锁一", sid = "23456789", spk = SPK.VideoDoorLock });
            //list.Add(new Function { name = "视频门锁二", sid = "2345678922", spk = SPK.VideoDoorLock });
#endif
            return new List<Function>();
        }
#region  ---------自定义线程(子线程,主线程)--------
        /// <summary>
        /// 子线程
        /// </summary>
        /// <paramref name="tipType"/>是否要提示错误信息(默认显示)<paramref>
        /// <param name="action"></param>
        public void SunThread(Action action, TipType tipType = TipType.confirmation)
        {
            new System.Threading.Thread(() =>
            {
                try
                {
                    action?.Invoke();
                }
                catch (Exception e)
                {
                    this.ShowAlert(e, tipType);
                }
            })
            { IsBackground = true }.Start();
        }
        /// <summary>
        /// 主线程(UI更新)
        /// </summary>
        /// <paramref name="tipType"/>是否要提示错误信息(默认显示)<paramref>
        /// <param name="action"></param>
        public void MainThread(Action action, TipType tipType = TipType.confirmation)
        {
            Application.RunOnMainThread(() =>
            {
                try
                {
                    action?.Invoke();
                }
                catch (Exception e)
                {
                    this.ShowAlert(e, tipType);
                }
            });
        }
#endregion
#region  --------- 提示框,确认框 --------
        /// <summary>
        /// 对话框(只要程序报错的时候才用到)
        /// </summary>
        /// <paramref name="e"/>异常对象<paramref>
        /// <paramref name="tipType"/>是否要提示错误信息(默认显示)<paramref>
        private void ShowAlert(Exception e, TipType tipType)
        {
            if (tipType != TipType.confirmation)
            {
                return;
            }
            Application.RunOnMainThread(() =>
            {
                string msg = e.Message + "\r\n" + e.StackTrace;
                Alert alert = new Alert("抱歉程序出错了.", "按\"确定\"能获取更详细的错误信息.", "取消", "确定");
                alert.Show();
                alert.ResultEventHandler += (alerts, isBool) =>
                {
                    alert.Dismiss();
                    if (isBool)
                    {
                        StackTraceLog stackTraceLog = new StackTraceLog(msg);
                        stackTraceLog.Show();
                    }
                };
            });
        }
        /// <summary>
        /// 信息提示窗口,自动关闭
        /// </summary>
        /// <param name="msg">提示错误文本</param>
        public void ShowTip(string msg, int time = 2)
        {
            Application.RunOnMainThread(() =>
            {
                new PublicAssmebly().TipMsgAutoClose(msg, false, time * 1000);
            });
        }
#endregion
        /// <summary>
        /// 弹框类型
        /// </summary>
        public enum TipType
        {
            none,//无提示
            flicker,//闪烁框
            confirmation//确认框
        }
        /// <summary>
        /// 表示来自那个界面
        /// </summary>
        public enum Comerom
        {
            function,//功能
            collect,//收藏
            room,//房间
            push,//推送
        }
#if __IOS__
#else
        /// <summary>
        ///
        /// </summary>
        public class AndroidIHdlInterface : Java.Lang.Object, IHdlInterface
        {
            Action<bool,string> mAction;
            public AndroidIHdlInterface(Action<bool,string> action)
            {
                mAction = action;
            }
            /// <summary>
            ///
            /// </summary>
            /// <param name="p0">true是入网成功(源生回调返回)</param>
            /// <param name="p1">设备的序列化(源生回调返回)</param>
            public void AddCallback(bool p0, string p1)
            {
                mAction?.Invoke(p0,p1);
            }
        }
#endif
    }
}
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/ObjectClass.cs
New file
@@ -0,0 +1,82 @@
using System;
namespace HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock
{
    public class ObjectClass
    {
    }
    /// <summary>
    /// 用户信息(萤石视频门锁)
    /// </summary>
    public class UserVideoDoorLockInfo
    {
        /// <summary>
        /// 用户id
        /// </summary>
        public string extUserId = string.Empty;
        /// <summary>
        /// 用户名称
        /// </summary>
        public string extUserName = string.Empty;
    }
    /// <summary>
    /// 门锁状态(萤石视频门锁)
    /// </summary>
    public class VideoDoorLockInfo
    {
        /// <summary>
        /// 锁状态(lock:锁;unlock:解锁)
        /// </summary>
        public string lockStatus = string.Empty;
        /// <summary>
        /// 门状态(open:开;close:关)
        /// </summary>
        public string doorStatus = string.Empty;
    }
    /// <summary>
    /// 电池详情(萤石视频门锁)
    /// </summary>
    public class CellInfo
    {
        /// <summary>
        /// 电量
        /// </summary>
        public string remain = string.Empty;
        /// <summary>
        /// 电池名称
        /// </summary>
        public string name = string.Empty;
    }
    /// <summary>
    /// 推送内容对象
    /// </summary>
    public class ExpantContent
    {
        /// <summary>
        /// 设备序列号
        /// </summary>
        public string devSerial = string.Empty;
        /// <summary>
        /// 设备id
        /// </summary>
        public string deviceId = string.Empty;
        /// <summary>
        /// 不知道是啥
        /// </summary>
        public string interphoneTypeEnum = string.Empty;
        /// <summary>
        /// 不知道是啥
        /// </summary>
        public string subToken = string.Empty;
        /// <summary>
        /// 云雀上定义的设备spk
        /// </summary>
        public string spk = string.Empty;
    }
}
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/StackTraceLog.cs
New file
@@ -0,0 +1,58 @@
using System;
using HDL_ON.UI.CSS;
using HDL_ON.UI.Music;
using Shared;
namespace HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock
{
    public class StackTraceLog
    {
        /// <summary>
        /// 堆叠跟踪日志
        /// </summary>
        public string msg;
        public StackTraceLog(string msg)
        {
            this.msg = msg;
        }
        public void Show()
        {
            Dialog dialog = new Dialog()
            {
                BackgroundColor = CSS_Color.textWhiteColor,
            };
            dialog.Show();
            TopView topView = new TopView();
            topView.topNameBtn.Text="错误日志信息";
            dialog.AddChidren(topView.TopFLayoutView());
            topView.clickBackBtn.MouseUpEventHandler += (sen, e) =>
            {
                dialog.Close();
            };
            var middleFl = new FrameLayout
            {
                Y = topView.fLayout.Bottom,
                Height = Application.GetRealHeight(H_W.H - H_W.T_Height),
            };
            dialog.AddChidren(middleFl);
            Button btnLogText = new Button
            {
                //TextSize = TextSize.Text14,
                TextColor = MusicColor.Text18Color,
                Width = Application.GetRealWidth(H_W.W - 16 - 16),
                Height = middleFl.Height,
                X = Application.GetRealWidth(16),
                Text = this.msg,
                TextAlignment = TextAlignment.TopLeft,
                IsMoreLines = true,
            };
            middleFl.AddChidren(btnLogText);
        }
    }
}
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideDoorLockSend.cs
New file
@@ -0,0 +1,216 @@
using System;
using System.Collections.Generic;
using System.Threading;
using HDL_ON.DAL.Server;
using HDL_ON.Entity;
using Shared;
using static HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock.CommonMethod;
namespace HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock
{
    /// <summary>
    /// 萤石视频门锁数据发送
    /// </summary>
    public class VideDoorLockSend
    {
        private static VideDoorLockSend send = null;
        /// <summary>
        /// 获取当前的对象
        /// </summary>
        public static VideDoorLockSend Current
        {
            get
            {
                if (send == null)
                {
                    send = new VideDoorLockSend();
                }
                return send;
            }
        }
        /// <summary>
        /// 解绑设备(萤石视频门锁)
        /// </summary>
        /// <param name="function">当前的设备</param>
        /// <param name="action">回调结果</param>
        /// <param name="tipType">是否需要提示,默认提示</param>
        public void DelDevice(Function function, Action<bool> action, TipType tipType = TipType.flicker)
        {
            new Thread(() =>
            {
                try
                {
                    Dictionary<string, object> d = new Dictionary<string, object>();
                    d.Add("homeId", DB_ResidenceData.Instance.CurrentRegion.id);
                    d.Add("deviceSerial", function.sid);//等同门锁序列号
                    d.Add("platform", 1);//平台
                    var responsePackNew = UI.Music.SendMethod.Current.RequestServerhomeId(d, NewAPI.Api_Post_DeleteDevice, "删除萤石门锁设备");
                    if (!this.DataChecking(responsePackNew, tipType))
                    {
                        return;
                    }
                    if (function != null)
                    {
                        action?.Invoke(true);
                    }
                }
                catch (Exception s)
                {
                }
            })
            { IsBackground = true }.Start();
        }
        /// <summary>
        /// 获取门锁状态(萤石视频门锁)
        /// </summary>
        /// <param name="function">当前的设备</param>
        /// <param name="tipType">是否需要提示,默认提示</param>
        /// <param name="return">返回结果不会为null</param>
        public VideoDoorLockInfo GetVideoDoorLockState(Function function, TipType tipType = TipType.flicker)
        {
            Dictionary<string, object> d = new Dictionary<string, object>();
            d.Add("homeId", DB_ResidenceData.Instance.CurrentRegion.id);
            d.Add("deviceId", function.deviceId);
            var responsePackNew = UI.Music.SendMethod.Current.RequestServerhomeId(d, NewAPI.Api_Post_Lockstatus, "获取萤石视频门锁状态");
            if (!this.DataChecking(responsePackNew,tipType))
            {
                return new VideoDoorLockInfo();
            }
            var videoDoorLockInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<VideoDoorLockInfo>(responsePackNew.Data.ToString());
            if (videoDoorLockInfo == null)
            {
                return new VideoDoorLockInfo();
            }
            return videoDoorLockInfo;
        }
        /// <summary>
        /// 获取电池电量(萤石视频门锁)
        /// </summary>
        /// <param name="function">当前的设备</param>
        /// <param name="tipType">是否需要提示,默认提示</param>
        /// <param name="return">返回结果不会为null</param>
        public CellInfo GetCellValue(Function function, TipType tipType = TipType.flicker)
        {
            Dictionary<string, object> d = new Dictionary<string, object>();
            d.Add("homeId", DB_ResidenceData.Instance.CurrentRegion.id);
            d.Add("deviceId", function.deviceId);
            var responsePackNew = UI.Music.SendMethod.Current.RequestServerhomeId(d, NewAPI.Api_Post_Details, "获取萤石门锁设备电量");
            if (!this.DataChecking(responsePackNew,tipType))
            {
                return new CellInfo();
            }
            var cellInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<CellInfo>(responsePackNew.Data.ToString());
            if (cellInfo == null)
            {
                return new CellInfo();
            }
            return cellInfo;
        }
        /// <summary>
        /// 获取门锁用户列表(萤石视频门锁)
        /// </summary>
        /// <param name="function">当前的设备</param>
        /// <param name="tipType">是否需要提示,默认提示</param>
        /// <param name="return">返回结果不会为null</param>
        public List<UserVideoDoorLockInfo> GetVideoDoorLockUserListInfo(Function function, TipType tipType = TipType.flicker)
        {
            Dictionary<string, object> d = new Dictionary<string, object>();
            d.Add("homeId", DB_ResidenceData.Instance.CurrentRegion.id);
            d.Add("deviceId", function.deviceId);
            var responsePackNew = UI.Music.SendMethod.Current.RequestServerhomeId(d, NewAPI.Api_Post_UserList, "获取萤石门锁用户列表");
            if (!this.DataChecking(responsePackNew, tipType))
            {
                return new List<UserVideoDoorLockInfo>();
            }
            var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<UserVideoDoorLockInfo>>(responsePackNew.Data.ToString());
            if (list == null)
            {
                return new List<UserVideoDoorLockInfo>();
            }
            return list;
        }
        /// <summary>
        /// 获取门锁设备列表(萤石视频门锁)
        /// </summary>
        /// <param name="spk">指定spk获取</param>
        /// <param name="tipType">是否需要提示,默认提示</param>
        /// <returns>返回结果不会为null</returns>
        public List<Function> GetVideoDoorLockDeviceList(string spk, TipType tipType = TipType.flicker)
        {
            Dictionary<string, object> d = new Dictionary<string, object>();
            d.Add("homeId", DB_ResidenceData.Instance.CurrentRegion.id);
            d.Add("spk", spk);
            var responsePackNew = UI.Music.SendMethod.Current.RequestServerhomeId(d, NewAPI.Api_Post_UserList, "获取萤石门锁设备列表");
            if (!this.DataChecking(responsePackNew, tipType))
            {
                return new List<Function>();
            }
            var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Function>>(responsePackNew.Data.ToString());
            if (list == null)
            {
                return new List<Function>();
            }
            return list;
        }
        /// <summary>
        /// 先获取萤石云子账号token
        /// </summary>
        /// <param name="tipType">是否需要提示,默认提示</param>
        public string GetEZGetChildToken(TipType tipType = TipType.flicker)
        {
            //先获取萤石云子账号token
            var responsePackNew = new HttpServerRequest().EZGetChildToken();
            if (!this.DataChecking(responsePackNew, tipType))
            {
                return "";
            }
            return responsePackNew.Data.ToString();
        }
        /// <summary>
        /// 检验数据回复成功或者失败
        /// </summary>
        /// <param name="responsePackNew">回复数据对象</param>
        /// <param name="tipType">是否需要提示</param>
        /// <returns></returns>
        private bool DataChecking(ResponsePackNew responsePackNew, TipType tipType)
        {
            if (responsePackNew.Data == null || responsePackNew.Code != "0" || responsePackNew.Data.ToString() == "")
            {
                if (TipType.flicker == tipType)
                {
                    if (responsePackNew == null)
                    {
                        responsePackNew = new ResponsePackNew { message = "没回复,请确认网络是否正常.", Code = "-1", };
                    }
                    Application.RunOnMainThread(() =>
                    {
                        //new Tip()
                        //{
                        //    CloseTime = 1,
                        //    Text = responsePackNew.message + "(" + responsePackNew.Code + ")",
                        //    Direction = AMPopTipDirection.None,
                        //}.Show(MainPage.BasePageView.GetChildren(MainPage.BasePageView.ChildrenCount - 1));
                        CommonMethod.Current.ShowTip(responsePackNew.message + "(" + responsePackNew.Code + ")");
                    });
                }
                return false;
            }
            return true;
        }
    }
}
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideoDoorLockListPage.cs
New file
@@ -0,0 +1,222 @@
using Shared;
using HDL_ON.Stan;
using System;
using System.Collections.Generic;
using System.Text;
using HDL_ON.UI.CSS;
using HDL_ON.Entity;
namespace HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock
{
    /// <summary>
    /// 视频门锁列表界面
    /// </summary>
    public class VideoDoorLockListPage : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 门锁设备列表
        /// </summary>
        private List<Function> listDevice = new List<Function>();
        /// <summary>
        /// 电池控件列表(key:设备的sid)
        /// </summary>
        private Dictionary<string, BatteryPersentControl> dicBatteryContr = new Dictionary<string, BatteryPersentControl>();
        /// <summary>
        /// 列表控件
        /// </summary>
        private VerticalListControl listView = null;
        /// <summary>
        /// 删除设备后需要更新界面的回调
        /// </summary>
        public Action action;
        #endregion
        #region ■ 初始化_____________________________
        public VideoDoorLockListPage(Action action) {
            this.action = action;
        }
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        /// <param name="i_listDevice">门锁设备列表</param>
        public void ShowForm(List<Function> i_listDevice)
        {
            this.listDevice.AddRange(i_listDevice);
            //智能门锁
            base.SetTitleText(Language.StringByID(StringId.shipinmensuo));
            //初始化中部信息
            this.InitMiddleFrame();
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame()
        {
            //清空bodyFrame
            this.ClearBodyFrame();
            string nowSelectId = string.Empty;
            //楼层下拉图标
            var btnFloor = new NormalViewControl(500, Application.GetRealHeight(16), false);
            var btnFloorIcon = new IconViewControl(16);
            btnFloorIcon.X = HdlControlResourse.XXLeft;
            btnFloorIcon.Y = Application.GetRealHeight(18);
            btnFloorIcon.UnSelectedImagePath = "Public/DownIcon.png";
            bodyFrameLayout.AddChidren(btnFloorIcon);
            btnFloorIcon.ButtonClickEvent += (sender, e) =>
            {
                //显示下拉列表
                var form = new FloorRoomSelectPopupView();
                form.ShowDeviceFunctionView(btnFloor, this.listDevice, (selectId, listFunc) =>
                {
                    btnFloor.Width = btnFloor.GetRealWidthByText();//重置文本宽度
                    nowSelectId = selectId;
                    //重新初始化门锁列表控件
                    this.InitDoorListControl(listFunc);
                }, nowSelectId);
            };
            //楼层
            btnFloor.X = btnFloorIcon.Right + Application.GetRealWidth(2);
            btnFloor.TextColor = CSS_Color.FirstLevelTitleColor;
            btnFloor.TextSize = CSS_FontSize.PromptFontSize_FirstLevel;
            btnFloor.Text = DB_ResidenceData.Instance.CurFloor.roomName;
            //btnFloor.Width = btnFloor.GetRealWidthByText();
            bodyFrameLayout.AddChidren(btnFloor);
            //让它相对图标居中
            btnFloor.Y = btnFloorIcon.Y + (btnFloorIcon.Height - btnFloor.Height) / 2;
            btnFloor.ButtonClickEvent += (sender, e) =>
            {
                btnFloorIcon.ButtonClickEvent(null, null);
            };
            //列表控件
            this.listView = new VerticalListControl();
            listView.Y = Application.GetRealHeight(53);
            listView.Height = bodyFrameLayout.Height - Application.GetRealHeight(53);
            bodyFrameLayout.AddChidren(listView);
            //初始化门锁列表控件
            this.InitDoorListControl(this.listDevice);
        }
        #endregion
        #region ■ 添加门锁控件_______________________
        /// <summary>
        /// 初始化门锁列表控件
        /// </summary>
        private void InitDoorListControl(List<Function> i_listDevice)
        {
            this.listView.RemoveAll();
            this.dicBatteryContr = new Dictionary<string, BatteryPersentControl>();
            //生成门锁控件
            foreach (var device in i_listDevice)
            {
                this.AddDoorControl(device);
            }
        }
        /// <summary>
        /// 添加门锁控件
        /// </summary>
        /// <param name="i_device">门锁对象</param>
        private void AddDoorControl(Function i_device)
        {
            //白色背景容器
            var frameBack = new FrameLayoutStatuControl();
            frameBack.Width = Application.GetRealWidth(343);
            frameBack.Height = Application.GetRealHeight(96);
            frameBack.Radius = (uint)Application.GetRealWidth(12);
            frameBack.Gravity = Gravity.CenterHorizontal;
            frameBack.BackgroundColor = CSS_Color.MainBackgroundColor;
            this.listView.AddChidren(frameBack);
            //门锁图标
            var btnIcon = new IconViewControl(32);
            btnIcon.X = Application.GetRealWidth(10);
            btnIcon.Y = Application.GetRealHeight(15);
            btnIcon.UnSelectedImagePath = "FunctionIcon/DoorLock/DoorLock.png";
            frameBack.AddChidren(btnIcon, ChidrenBindMode.BindEvent);
            //设备名字
            var btnName = new Button();
            btnName.X = btnIcon.Right + Application.GetRealWidth(12);
            btnName.Y = Application.GetRealHeight(12);
            btnName.Width = Application.GetRealWidth(150);
            btnName.Height = Application.GetRealHeight(20);
            btnName.TextColor = CSS_Color.FirstLevelTitleColor;
            btnName.TextAlignment = TextAlignment.CenterLeft;
            btnName.Text = i_device.name;
            frameBack.AddChidren(btnName, ChidrenBindMode.BindEvent);
            //房间
            var btnRoom = new Button();
            btnRoom.X = btnName.X;
            btnRoom.Y = btnName.Bottom + Application.GetRealHeight(4);
            btnRoom.Width = Application.GetRealWidth(150);
            btnRoom.Height = Application.GetRealHeight(15);
            btnRoom.TextColor = CSS_Color.PromptingColor1;
            btnRoom.TextSize = CSS_FontSize.PromptFontSize_SecondaryLevel;
            btnRoom.TextAlignment = TextAlignment.CenterLeft;
            btnRoom.Text = i_device.GetRoomListName();
            frameBack.AddChidren(btnRoom, ChidrenBindMode.BindEvent);
            //电池图标
            var btnBattery = new BatteryPersentControl();
            btnBattery.Y = Application.GetRealHeight(62);
            //frameBack.AddChidren(btnBattery, ChidrenBindMode.BindEvent);
            btnBattery.InitControl();
            btnBattery.SetValue(80);
            btnBattery.X = frameBack.Width - btnBattery.Width - Application.GetRealWidth(12);
            this.dicBatteryContr[i_device.sid] = btnBattery;
            frameBack.ButtonClickEvent += (sender, e) =>
            {
                var form = new VideoDoorLockPage(i_device, btnName, btnRoom, CommonMethod.Comerom.function,()=> {
                    this.CloseForm();
                    this.action?.Invoke();
                });
                MainPage.BasePageView.AddChidren(form);
                MainPage.BasePageView.PageIndex = MainPage.BasePageView.ChildrenCount - 1;
                form.Show();
            };
            //底部再加个间距
            var frameSpace = new FrameLayout();
            frameSpace.Height = Application.GetRealHeight(12);
            this.listView.AddChidren(frameSpace);
        }
        #endregion
        #region ■ 设备状态推送_______________________
        /// <summary>
        /// 设备状态推送
        /// </summary>
        /// <param name="i_LocalDevice"></param>
        public override void DeviceStatuPush(Function i_LocalDevice)
        {
            //不是目标设备
            if (this.dicBatteryContr.ContainsKey(i_LocalDevice.sid) == false)
            {
                return;
            }
        }
        #endregion
    }
}
HDL_ON/UI/UI2/FuntionControlView/VideoDoorLock/VideoDoorLockPage.cs
New file
@@ -0,0 +1,511 @@
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
using HDL_ON.UI.CSS;
using HDL_ON.Entity;
using HDL_ON.DriverLayer;
using HDL_ON.UI.Music;
using HDL_ON.UI.UI2.FuntionControlView.VideoDoorLock;
namespace HDL_ON.UI
{
    /// <summary>
    /// 视频门锁的控制界面
    /// </summary>
    public class VideoDoorLockPage : FrameLayout
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 设备
        /// </summary>
        private Function device;
        /// <summary>
        /// 上一级界面的设备名字控件
        /// </summary>
        private Button btnDeviceName;
        /// <summary>
        /// 上一级界面的房间名字控件
        /// </summary>
        private Button btnRoomName;
        /// <summary>
        /// 头部布局
        /// </summary>
        private TopView topView;
        /// <summary>
        /// 当前设备名称
        /// </summary>
        private Button btnCurrDeviceName;
        /// <summary>
        /// 区域
        /// </summary>
        private Button btnCurrDeviceRoom;
        /// <summary>
        /// 电量父控件
        /// </summary>
        private FrameLayout cellFrame;
        /// <summary>
        /// 电量
        /// </summary>
        private Button btnCell;
        /// <summary>
        /// 电量进度条
        /// </summary>
        private DiyArcSeekBar cellDiyArcSeekBar;
        /// <summary>
        ///收藏图标
        /// </summary>
        private Button btnCollectIcon;
        /// <summary>
        /// 门锁状态
        /// </summary>
        private Button btnDoorLockIcon;
        /// <summary>
        /// 实时视频
        /// </summary>
        private CustomFrameLayout rtvFL;
        /// <summary>
        /// 临时密码
        /// </summary>
        private CustomFrameLayout pswFL;
        /// <summary>
        /// 历史记录
        /// </summary>
        private CustomFrameLayout recordFL;
        /// <summary>
        /// 表示来自那个界面
        /// </summary>
        private CommonMethod.Comerom comerom;
        /// <summary>
        /// 删除设备后需要更新界面的回调
        /// </summary>
        public Action action;
        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="function">设备</param>
        /// <param name="btnDeviceName">上一级界面的设备名字控件(注:不能传null,没有可以传new Button())</param>
        /// <param name="btnRoomName">上一级界面的房间名字控件(注:不能传null,没有可以传new Button())</param>
        public VideoDoorLockPage(Function function, Button btnDeviceName, Button btnRoomName, CommonMethod.Comerom comerom, Action action)
        {
            this.device = function;
            this.btnDeviceName = btnDeviceName;
            this.btnRoomName = btnRoomName;
            this.comerom = comerom;
            this.action = action;
        }
        public void Show()
        {
            //初始化UI
            this.InitUI();
            //初始化事件
            this.EventListener();
            //读取数据
            this.ReadData();
        }
        /// <summary>
        /// 初始化界面
        /// </summary>
        private void InitUI()
        {
            #region   ---界面布局---
            this.BackgroundColor = MusicColor.ViewColor;
            this.topView = new TopView();
            this.topView.setBtn.Visible = true;
            this.topView.topNameBtn.TextID = StringId.shipinmensuo;
            this.AddChidren(topView.TopFLayoutView());
            var middleFl = new FrameLayout
            {
                Y = topView.fLayout.Bottom,
                Height = Application.GetRealHeight(H_W.H - H_W.T_Height),
            };
            this.AddChidren(middleFl);
            var whiteFl = new FrameLayout
            {
                Y = Application.GetRealHeight(24),
                X = Application.GetRealWidth(24),
                Height = Application.GetRealHeight(526),
                Width = Application.GetRealWidth(327),
                BackgroundImagePath = "MusicIcon/playBj.png",
                Name = "fl",
            };
            middleFl.AddChidren(whiteFl);
            btnCollectIcon = new Button
            {
                X = Application.GetRealWidth(264),
                Y = Application.GetRealHeight(14),
                Width = Application.GetRealWidth(40),
                Height = Application.GetRealWidth(40),
                UnSelectedImagePath = "MusicIcon/collect.png",
                SelectedImagePath = "MusicIcon/collectSelected.png",
                IsSelected = this.device.collect,
                Name = "collect"
            };
            whiteFl.AddChidren(btnCollectIcon);
            btnCurrDeviceName = new Button
            {
                TextSize = TextSize.Text24,
                TextColor = MusicColor.Text18Color,
                Width = Application.GetRealWidth(160),
                Height = Application.GetRealHeight(33),
                Y = Application.GetRealHeight(16),
                X = Application.GetRealWidth(16),
                Text = this.device.name,
                TextAlignment = TextAlignment.CenterLeft,
            };
            whiteFl.AddChidren(btnCurrDeviceName);
            btnCurrDeviceRoom = new Button
            {
                TextSize = TextSize.Text12,
                TextColor = MusicColor.MusicNoTxetColor,
                Width = Application.GetRealWidth(160),
                Height = Application.GetRealHeight(17),
                Y = btnCurrDeviceName.Bottom + Application.GetRealHeight(4),
                X = Application.GetRealWidth(16),
                Text = this.device.GetRoomListName(),
                TextAlignment = TextAlignment.CenterLeft,
            };
            whiteFl.AddChidren(btnCurrDeviceRoom);
            cellFrame = new FrameLayout
            {
                X = btnCurrDeviceRoom.Right + Application.GetRealWidth(20),
                Y = btnCurrDeviceName.Bottom + Application.GetRealHeight(5),
                Width = Application.GetRealWidth(30),
                Height = Application.GetRealHeight(16),
            };
            whiteFl.AddChidren(cellFrame);
            cellDiyArcSeekBar = new DiyArcSeekBar
            {
                X = Application.GetRealWidth(3),
                Y = Application.GetRealHeight(3),
                Width = cellFrame.Width + Application.GetRealWidth(-6),
                Height = cellFrame.Height + Application.GetRealHeight(-6),
                Progress = 60,
                ProgressBarColor = MusicColor.MusicNoTxetColor,
                MaxValue = 100,
                MinValue = 0,
                //IsCanMove = false,
                //IsCanScrolled=false,
            };
            //cellFrame.AddChidren(cellDiyArcSeekBar);
            btnCell = new Button
            {
                TextSize = TextSize.Text10,
                TextColor = MusicColor.TextColor,
                Text = "60" + "%",
                TextAlignment = TextAlignment.Center,
                UnSelectedImagePath = "FunctionIcon/DoorLock/Cell.png",
            };
            cellFrame.AddChidren(btnCell);
             //门锁状态
             btnDoorLockIcon = new Button
            {
                X = Application.GetRealWidth(65),
                Y = Application.GetRealHeight(108),
                Width = Application.GetRealWidth(198),
                Height = Application.GetRealWidth(200),
                UnSelectedImagePath = "FunctionIcon/DoorLock/UnLocked.png",
                SelectedImagePath = "FunctionIcon/DoorLock/UnLocking.png",
            };
            whiteFl.AddChidren(btnDoorLockIcon);
            this.CalculatedPosition();//重新计算宽度
            int heightY = btnDoorLockIcon.Bottom + Application.GetRealHeight(70);
            //实时视频
            rtvFL = new CustomFrameLayout(CustomFrameLayout.widthFrameLayout, CustomFrameLayout.heightFrameLayout);
            whiteFl.AddChidren(rtvFL);
            rtvFL.Y = heightY;
            rtvFL.X = Application.GetRealWidth(41);
            rtvFL.AddImageView();
            rtvFL.AddTextButtonView();
            rtvFL.GetImageButton().UnSelectedImagePath = "FunctionIcon/DoorLock/RTV.png";
            rtvFL.GetTextButton().TextID = StringId.shishishipin;
            //历史记录
            recordFL = new CustomFrameLayout(CustomFrameLayout.widthFrameLayout, CustomFrameLayout.heightFrameLayout);
            whiteFl.AddChidren(recordFL);
            recordFL.Y = heightY;
            recordFL.X = rtvFL.Right + Application.GetRealWidth(CustomFrameLayout.interval);
            recordFL.AddImageView();
            recordFL.AddTextButtonView();
            recordFL.GetImageButton().UnSelectedImagePath = "FunctionIcon/DoorLock/HistoryList.png";
            recordFL.GetTextButton().TextID = StringId.lishijilu;
            //临时密码
            pswFL = new CustomFrameLayout(CustomFrameLayout.widthFrameLayout, CustomFrameLayout.heightFrameLayout);
            whiteFl.AddChidren(pswFL);
            pswFL.Y = heightY;
            pswFL.X = recordFL.Right + Application.GetRealWidth(CustomFrameLayout.interval);
            pswFL.AddImageView();
            pswFL.AddTextButtonView();
            pswFL.GetImageButton().UnSelectedImagePath = "FunctionIcon/DoorLock/OneOpenLock.png";
            pswFL.GetTextButton().TextID = StringId.linshimima1;
            #endregion
        }
        /// <summary>
        /// 注册事件
        /// </summary>
        private void EventListener()
        {
            //返回
            this.topView.clickBackBtn.MouseUpEventHandler += (sender, e) =>
            {
                this.RemoveFromParent();
            };
            //设置
            this.topView.clickSetBtn.MouseUpEventHandler += (sender, e) =>
            {
                CommonMethod.Current.MainThread(() =>
                {
                    //调用秀绕的界面
                    var infoView = new UI.FunctionBaseInfoSetPage(this.device, () =>
                     {
                         if (this.btnDeviceName == null || this.btnRoomName == null || this.device == null)
                         {
                             return;
                         }
                         ////刷新显示
                         this.btnDeviceName.Text = this.device.name;
                         this.btnRoomName.Text = this.device.GetRoomListName();
                         this.btnCurrDeviceName.Text = this.device.name;
                         this.btnCurrDeviceRoom.Text = this.device.GetRoomListName();
                         this.CalculatedPosition();//重新计算宽度
                     });
                    //infoView.actionDel += () =>
                    //  {
                    //      //解绑设备后
                    //      this.RemoveFromParent();
                    //      this.action?.Invoke();
                    //  };
                    MainPage.BasePageView.AddChidren(infoView);
                    infoView.LoadPage();
                    MainPage.BasePageView.PageIndex = MainPage.BasePageView.ChildrenCount - 1;
                });
            };
            //收藏
            this.btnCollectIcon.MouseUpEventHandler += (sender, e) =>
            {
                btnCollectIcon.IsSelected = this.device.collect = !btnCollectIcon.IsSelected;
                this.device.CollectFunction();
            };
            //实时视频
            this.rtvFL.SetClickListener((fl, btnStateImage, btnStateText) =>
            {
                CommonMethod.Current.SkipRTVActivity(this.device.sid, this.device.deviceId, this.device.spk);
            });
            //临时密码
            this.pswFL.SetClickListener((fl, btnStateImage, btnStateText) =>
            {
                CommonMethod.Current.SkipPSWActivity(this.device.deviceId);
            });
            //历史记录
            this.recordFL.SetClickListener((fl, btnStateImage, btnStateText) =>
            {
                CommonMethod.Current.SkipRecordActivity(this.device.deviceId);
            });
        }
        /// <summary>
        /// 初始数据
        /// </summary>
        private void ReadData()
        {
            CommonMethod.Current.Loading.Start();
            CommonMethod.Current.SunThread(() =>
            {
                try
                {
                    var videoDoorLockInfo = VideDoorLockSend.Current.GetVideoDoorLockState(this.device);
                    var cellInfo = VideDoorLockSend.Current.GetCellValue(this.device);
                    CommonMethod.Current.MainThread(() =>
                    {
                        //this.cellDiyArcSeekBar.Progress = i;
                        //更新电量值
                        this.btnCell.Text = cellInfo.remain + "%";
                        this.btnDoorLockIcon.IsSelected = videoDoorLockInfo.doorStatus == "open";
                    });
                }
                catch { }
                finally
                {
                    Application.RunOnMainThread(() =>
                    {
                        CommonMethod.Current.Loading.Hide();
                    });
                }
            });
        }
        /// <summary>
        /// 重新计算宽度(设备名称,房间控件)
        /// </summary>
        private void CalculatedPosition()
        {
            this.btnCurrDeviceName.Width = this.btnCurrDeviceName.GetTextWidth();
            if (this.btnCurrDeviceName.GetTextWidth() > this.btnCollectIcon.X)
            {
                //重新计算宽度
                this.btnCurrDeviceName.Width = this.btnCollectIcon.X + Application.GetRealWidth(-10);
            }
            this.btnCurrDeviceRoom.Width = this.btnCurrDeviceRoom.GetTextWidth();
            if (this.btnCurrDeviceRoom.GetTextWidth() > this.btnCollectIcon.X)
            {
                //重新计算宽度
                this.btnCurrDeviceRoom.Width = this.btnCollectIcon.X + Application.GetRealWidth(-20 - 10);
            }
            this.cellFrame.X = this.btnCurrDeviceRoom.Right + Application.GetRealWidth(20);
        }
    }
    /// <summary>
    /// 自己弄一个FrameLayout
    /// </summary>
    class CustomFrameLayout : FrameLayout
    {
        public const int widthFrameLayout = 48;
        public const int heightFrameLayout = 53;
        public const int yFrameLayout = 378;
        public const int xFrameLayout = 41;
        public const int interval = 51;//行中的列间隔值
        public CustomFrameLayout(int width, int height, int x = 0, int y = 0)
        {
            this.Width = Application.GetRealWidth(width);
            this.Height = Application.GetRealHeight(height);
            this.X = Application.GetRealWidth(x);
            this.Y = Application.GetRealHeight(y);
        }
        Button btnStateImage = new Button
        {
            Width = Application.GetRealWidth(32),
            Height = Application.GetRealWidth(32),
            Gravity = Gravity.TopCenter,
            Name = "btnStateImage",
        };
        Button btnStateText = new Button
        {
            Y = Application.GetRealHeight(4),
            Width = Application.GetRealWidth(100),
            Height = Application.GetRealWidth(20),
            TextID = StringId.dangqianmenweiguan,
            TextSize = TextSize.Text12,
            TextColor = MusicColor.TextCancelColor,
            TextAlignment = TextAlignment.Center,
            Gravity = Gravity.CenterHorizontal,
            Name = "btnStateText"
        };
        public void AddImageView()
        {
            this.AddChidren(btnStateImage);
        }
        public void AddTextButtonView()
        {
            btnStateText.Y += btnStateImage.Bottom;
            this.AddChidren(btnStateText);
        }
        public Button GetImageButton()
        {
            //if (!this.AddWithout(this.btnStateImage))
            //{
            //    this.AddImageView();
            //}
            return this.btnStateImage;
        }
        public Button GetTextButton()
        {
            //if (!this.AddWithout(this.btnStateText))
            //{
            //    this.AddTextButtonView();
            //}
            return this.btnStateText;
        }
        /// <summary>
        /// 事件监听方法
        /// </summary>
        /// <param name="action">回调(第一个是父类对象;第二个是图标对象;第三个是状态对象</param>
        /// <param name="button1">注意:在SetClickListener()前面调用AddImageView()才有效</param>
        /// <param name="button2">注意:在SetClickListener()前面调用AddImageView()才有效</param>
        public void SetClickListener(Action<FrameLayout, Button, Button> action)
        {
            EventHandler<MouseEventArgs> click = (sender, e) =>
                    {
                        action?.Invoke(this, btnStateImage, btnStateText);
                    };
            this.MouseUpEventHandler += click;
            btnStateImage.MouseUpEventHandler += click;
            btnStateText.MouseUpEventHandler += click;
        }
        /// <summary>
        /// 在父布局查找子控件是否存在
        /// </summary>
        /// <param name="btn">查找对象</param>
        /// <returns>存在为true,否则为false</returns>
        private bool AddWithout(View btn)
        {
            if (this.ChildrenCount <= 0 || btn == null)
            {
                return false;
            }
            for (int i = 0; i < this.ChildrenCount; i++)
            {
                View view = this.GetChildren(i);
                if (view == null)
                {
                    continue;
                }
                if (view is Button)
                {
                    if (view.Name == btn.Name)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}