精华内容
下载资源
问答
  • 想要设置好看的锁屏壁纸,可能需要下载Microsoft Store中的iSaver,但是我们已经花钱买了WE还要再花一次钱买iSaver吗?而且还比WE贵两块钱,我的内心是拒绝的。 那么就需要想办法把Wallpaper Engine的壁纸设置到锁屏...

    Wallpaper Engine想必大多数人都知道,但是它只能设置桌面壁纸,无法设置锁屏壁纸。
    想要设置好看的锁屏壁纸,可能需要下载Microsoft Store中的iSaver,但是我们已经花钱买了WE还要再花一次钱买iSaver吗?而且还比WE贵两块钱,我的内心是拒绝的。
    那么就需要想办法把Wallpaper Engine的壁纸设置到锁屏上了,怎么做呢?步骤如下:

    1. 打开Wallpaper Engine,选择自己喜欢的壁纸:
      在这里插入图片描述
    2. 点击windows左下角“开始”,选择齿轮:
      在这里插入图片描述
    3. 点击“个性化”:
      在这里插入图片描述
    4. 点击左边的“锁屏界面”,然后拉到最下面,点击“屏幕保护程序设置”:
      在这里插入图片描述
      屏幕保护程序,其实是很久以前的CRT显示器,如果屏幕一直不变化,某一个区域的颜色一直不变的话,容易出现坏点,所以才需要屏幕保护程序来保护屏幕。现在的液晶屏不存在这个问题,但是这个传统的程序还是保留下来了。
    5. 在弹出的窗口中,将“屏幕保护程序”下拉框设置为“Wallpaper Engine”:
      在这里插入图片描述
    6. 下面的“等待”可以自行配置时间,配置为1分钟则电脑保持不动1分钟后触发屏幕保护程序。将后面的“在恢复时显示登录屏幕”前面的勾选中,这样解除屏幕保护的时候就可以跳转到锁屏界面,达到跟锁屏一样的效果:
      在这里插入图片描述
    7. 关于壁纸的选择,在Wallpaper Engine中,可以选择让屏幕保护跟桌面壁纸一致,也可以单独对屏幕保护程序进行单独设置。把鼠标移动到Wallpaper Engine左上角的“已安装”上,就会弹出“配置壁纸”和“配置屏幕保护程序”两个选项:
      在这里插入图片描述
    8. 点击“配置屏幕保护程序”,就可以配置屏幕保护的壁纸:
      在这里插入图片描述
      至此,使用Wallpaper Engine配置锁屏壁纸就大功告成了。然后如果离开座位几分钟,屏幕就会自动展示你喜爱的壁纸,并且还自动锁屏(总有人离座忘记锁屏),简直完美。

    创作不易,点赞免费。

    自愿打赏,不为利往。

    在这里插入图片描述

    展开全文
  • 锁屏动态主题壁纸

    2020-12-31 17:33:05
    锁屏动态主题壁纸 应用隐私政策 尊敬的用户: 锁屏动态主题壁纸 应用是由 北京微言科技有限公司 (以下简称 “ 微言科技 ” )为您提供的一款 手机桌面壁纸美化软件 。 “微言科技” 十分尊重您的个人信息和数据,并...

    在这里插入图片描述
    锁屏动态主题壁纸 应用隐私政策

    尊敬的用户:
    锁屏动态主题壁纸 应用是由 北京微言科技有限公司 (以下简称 “ 微言科技 ” )为您提供的一款 手机桌面壁纸美化软件 。
    “微言科技” 十分尊重您的个人信息和数据,并会尽全力保护您的个人信息和数据的安全可靠。
    请在使用 锁屏动态主题壁纸 应用前,务必仔细阅读并了解和同意《 锁屏动态主题壁纸 应用的隐私政策》。
    该政策规定了您在使用 机壁纸软件极速版 应用时我们将如何收集、使用、披露、处理和保护您提供给我们的信息。
    如果我们需要您提供某些信息用于在使用该产品时验证您的身份、以及向我们的第三方服务
    供应商连接服务时,我们会严格遵守该隐私政策来使用这些信息。如果您已经开始使用 锁屏动态主题壁纸 应用,就表示您已经阅读、许可并接受该隐私政策中所描述的所有条款,以及我们今后随时 做出的任何变更。
    一、 我们如何收集您的个人信息
    二、我们如何使用 Cookie 和同类技术
    三、我们如何使用您的个人信息
    四、我们如何保护您的个人信息
    五、未成年人信息保护
    六、隐私政策的更新
    七、第三方 SDK 信息公示
    一、 我们如何收集您的个人信息
    个人信息是指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反应特定自然人活动情况的各种信息。个人信息包括:
    个人基本资料(个人姓名、性别、民族、国籍、住址、出生日期、身份证号码、电话号码、电子邮箱等);个人身份信息(身份证、社保卡、居住证等)、个人生物识别信息(指纹、声纹、掌纹、面部特征等);网络身份标识信息(系统账号、 IP 地址、邮箱地址及其与前述有关的密码、口令、口令保护答案、用户个人数字证书等);
    个人财产信息(银行账号及密码、征信信息、交易和消费记录、流水记录等,以及虚拟货币、虚拟交易、游戏类兑换码等虚拟财产信息);
    个人通信信息(通信通讯联系方式、通信记录和内容、电子邮件、短彩信等)、联系人信息(通讯录、好友列表、群列表、电子邮件地址列表等);
    个人上网记录(指通过日志存储的用户操作记录,包括网站浏览记录、软件使用记录等)、个人常用设备信息(包括硬件序列号、设备 MAC 地址、软件列表、唯一设备识别码 [ 如 IMEI/android ID/IDFA/OPENUDID/GUID\SIM 卡 IMSI 信息等 ] );
    个人位置信息(如行踪轨迹、精准定位信息等);
    其他信息。
    个人敏感信息是指一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息,个人敏感信息包括:身份证及身份证号码、手机号码、银行账号及密码、系统账号及密码、邮箱地址及密码、消费记录、地理位置信息等。
    在您使用手机铃声服务的过程中,我们会按照如下方式收集您在使用服务时主动提供的或因为使用服务而产生的信息,用以向您提供、优化我们的服务以及保障您的账户安全:
    1.3 搜索功能
    1.3.1 当您使用搜索功能时,我们需要收集您使用的搜索词、用户 ID 信息。我们收集这些信息是为了向您提供您所需要的内容和可能更感兴趣的服务,同时亦可以改进我们向您提供的服务。
    1.6 广告功能
    1.6.1 当您使用广告功能时,我们需要收集您的设备标识、浏览内容、浏览广告的次数以及与它们互动的次数信息。我们收集这些信息是为了向您推荐更优质、您可能更感兴趣的广告内容。
    1.6.2 个性化广告是广告展示技术之一,它依据用户行为或兴趣数据提供更相关的广告内容。我们仅提供对接技术,不会获取您在其他应用内的行为或个性数据。是为了帮助您顺利完成交易、保障您的交易安全、查询订单信息、售后服务。
    1.9 意见反馈功能
    1.9.1 联系方式(电话、 QQ 、邮箱)、反馈意见、用户 ID 、设备型号、屏幕分辨率、操作系统信息。
    1.12 缓存下载功能
    1.12.1 当您需要进行图片、视频等下载的,我们需要写入并读取您的存储卡权限,以保证您成功下载需要的图片、视频等。如您拒绝,会使您无法实现上述功能。
    1.12.2 当您查看大图页面进行图片下载或在配音短视频播放页进行视频下载时,我们需要修改或者删除您的存储卡中的内容。如您拒绝,会使您无法实现上述功能。
    1.14 个性化推荐功能
    1.14.1 我们会获取您的地理位置信息,用于个性化推荐,以便于向您更精准的进行内容推荐,提供更优质的服务。
    1.15 经您同意后收集的其他信息。
    二、我们如何使用 Cookie 和同类技术
    2.1 为确保网站正常运转,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。 Cookie 通常包含标识符、站点名称以及一些号码和字符。 Cookie 主要的功能是便于您使用网站产品和服务,以及帮助网站统计独立访客数量等。运用 Cookie 技术,我们能够为您提供更加周到的个性化服务,并允许您设定您特定的服务选项。
    2.2 在您使用我们的服务时,我们可能会使用 Cookie 或同类技术收集您的一些个人信息,例如:您访问网站的习惯、您的登录信息等, Cookie 和同类技术收集该类信息是为了您使用我们的服务的必要、简化您重复操作的步骤(如注册、登录)、便于您查看使用历史(如浏览历史)、向您提供更切合您个人需要的服务内容和您可能更感兴趣的内容、保护您的信息和账号安全性、改善我们的产品和服务等。我们承诺仅在本隐私政策所述目的范围内使用 Cookie 和同类技术。
    2.3 如果您的浏览器允许,您可以通过您的浏览器的设置以管理、(部分 / 全部)拒绝 Cookie 或同类技术;或删除已经储存在您的计算机、移动设备或其他装置内的 Cookie 或同类技术文件,从而实现我们无法全部或部分追踪您的个人信息。您如需详细了解如何更改浏览器设置,请具体查看您使用的浏览器的相关设置页面。
    三、我们如何使用您的个人信息
    3.1 共享
    您的个人信息是我们为您提供服务的重要依据和组成部分,对于您的个人信息,我们仅在本文所述的目的和范围内或根据法律法规的要求收集和使用,并严格保密,我们不会向第三方共享您的个人信息,除非存在以下一项或多项情形:
    3.1.1 事先征得您的明确授权同意;
    3.1.2 您主动提出的要求;
    3.1.3 根据法律法规规定、诉讼争议解决需要,或者行政、司法机关依照法律法规提出的要求;
    3.1.4 将您的个人信息与手机铃声的关联方共享。但手机铃声只会共享必要的个人信息,且受本文的约束。手机铃声的关联方如要改变个人信息的处理目的,将再次征求您的授权同意。
    3.1.5 为了保护您、手机铃声、其他用户的权利及财产安全或社会公共利益使其免遭损害而与第三方的共享;
    3.1.6 与部分业务合作伙伴的必要共享:您理解并知悉,为了必要且合理的业务的顺利展开,履行我们在相关用户协议或本隐私政策中的义务,我们可能会向合作伙伴等第三方共享您的信息(详情见第九条关于 “ 第三方 SDK 信息公示 ” 内容)。但我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作伙伴无权将共享的个人信息用于任何其他用途。对我们与之共享个人信息的公司、组织和个人,我们会要求其遵守保密约定,要求他们按照手机铃声的说明、本文以及其他任何相关的保密和安全措施来处理个人信息。
    3.1.7 其他法律法规等规定,司法机关或行政机关要求的情形。
    3.2 转让
    我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
    3.2.1 事先获得您的明确授权或同意;
    3.2.2 为满足法律法规、程序的要求或强制性的政府要求或司法裁定;
    3.2.3 如果我们或我们的关联公司涉及合并、分立、清算、资产或业务的收购或出售等交易,您的个人信息有可能作为此类交易的一部分而被转移,我们将确保该等信息在转移过程中的保密性,并尽最大可能确保新的持有您个人信息的公司、组织继续受此隐私政策的约束,否则我们将要求该公司、组织重新向您征求您的授权同意。
    3.3 公开披露
    我们仅会在以下情况下,公开披露您的个人信息:
    3.3.1 获得您的明确同意;
    3.3.2 基于法律法规、程序、诉讼或政府主管部门强制性要求下。
    3.4 例外
    在以下情形中,共享、转让、公开披露您的个人信息无需事先征得您的授权同意:
    3.4.1 与国家安全、国防安全直接相关的;
    3.4.2 与公共安全、公共卫生、重大公共利益直接相关的;
    3.4.3 与犯罪侦查、起诉、审判和判决执行等直接相关的;
    3.4.4 出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
    3.4.5 您自行向社会公众公开的个人信息;
    3.4.6 从合法公开披露的信息中收集的个人信息,如合法的新闻报道、政府信息公开等渠道;
    3.4.7 根据与您签订和履行的相关协议或其他书面文件所必需的;
    3.4.8 对收集的个人信息已经进行匿名化或去标识化处理的;
    3.4.9 为合法的新闻报道所必需的;
    3.4.10 做学术研究用途,例如为科研机构开展统计或学术研究之必要
    3.4.11 其他法律法规等规定的情形。

    四、我们如何保护您的个人信息

    4.1 为保障您的个人信息安全,我们努力采取各种合理的物理、电子和管理方面的安全措施来保护您的个人信息,使您的信息不会被泄漏、毁损或者丢失,包括但不限于 SSL 、信息加密存储、数据中心的访问控制等。
    4.2 我们将按照《网络安全法》等法律法规的要求保存您的个人信息。您的个人信息均储存于中华人民共和国境内(注:其中微信分享 SDK 绑定 IP 归属地为香港),如我们需要向境外传输您的个人信息,我们会严格按照法律法规的规定及要求执行,并保证您的个人信息安全。
    4.3 我们将保存您的个人信息不少于六个月,最长不超过 20 年。时间到期后,我们会将您的个人信息匿名化处理,以保证您的个人信息安全。
    4.4 我们仅允许有必要知晓您的个人信息的员工知晓您的个人信息,并为此设置了严格的访问权限控制和监控机制。我们对可能接触到您的个人信息的员工或外包人员也采取了严格管理,包括但不限于根据岗位的不同采取不同的权限控制,与他们签署保密协议,监控他们的操作情况等措施。我们建立了完善的信息安全管理制度和内部安全事件处置机制,我们会定期对负责人员及员工进行信息安全管理培训。我们会采取适当的符合业界标准的安全措施和技术手段存储和保护您的个人信息,以防止您的信息丢失、遭到被未经授权的访问、公开披露、使用、修改、毁损、丢失或泄漏。
    4.5 我们会按现有技术提供相应的安全措施来保护您的信息,提供合理的安全保障,我们将尽力做到使您的个人信息不被泄漏、毁损或丢失。如不幸发生个人信息安全事件的,我们将按照法律法规的要求,及时向您告知安全事件的基本情况和可能产生的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们会及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
    4.6 请您知悉并理解,互联网并非绝对安全的环境,我们强烈建议您通过安全方式、使用复杂密码等手段协助我们保证您的账号安全。如您发现自己的个人信息泄密,尤其是您的账号或密码发生泄露,请您立即根据本文中提供的联系方式联系我们,以便我们及时采取相应措施来保护您的个人信息安全。

    五、未成年人信息保护

    6.1 手机铃声提示父母或监护人指导未满十八周岁的未成年人使用手机铃声所提供的服务。如您为未成年人,手机铃声建议您请您的父母或监护人仔细阅读本文,并建议您在提交个人信息之前寻求父母或监护人的同意和指导。
    6.2 我们将根据国家相关法律法规保护未成年人的个人信息。如果任何时候监护人有理由相信我们在未获得监护人同意的情况下收集了未成年人的个人信息,请联系我们,我们会采取措施尽快删除相关信息。

    六、隐私政策的更新

    7.1 我们鼓励您在每次使用我们的服务时都查阅我们的隐私政策。
    7.2 您理解并同意,为了更好的向您提供服务,我们需要适时根据手机铃声平台产品及服务的发展情况,对本隐私政策进行修订及更新。我们会在手机铃声平台显著位置发布更新后的隐私政策,如您不同意更新后的隐私政策内容,您应不使用或立即停止使用手机铃声平台服务。
    八、第三方 SDK 信息公示

    以下为我们接入的第三方 SDK 名称、信息获取、使用目的及其隐私协议地址说明,
    1 、友盟移动统计 SDK
    信息获取: Mac 地址、唯一设备识别码( IMEI/android ID/IDFA/OPENUDID/GUID 、 SIM 卡 IMSI 信息)、地理位置信息
    使用目的:数据统计
    隐私协议地址: https://www.umeng.com/policy
    2 、友盟统计分析组件 SDK
    信息获取: Mac 地址、唯一设备识别码( IMEI/android ID/IDFA/OPENUDID/GUID 、 SIM 卡 IMSI 信息)、地理位置信息
    使用目的:数据统计
    隐私协议地址: https://www.umeng.com/policy
    隐私协议地址: https://privacy.qq.com/
    3 、友盟埋点 SDK
    信息获取: Mac 地址、唯一设备识别码( IMEI/android ID/IDFA/OPENUDID/GUID 、 SIM 卡 IMSI 信息)、地理位置信息
    使用目的:用户使用效果统计分析
    隐私协议地址: https://www.umeng.com/policy
    4 、穿山甲广告 SDK
    信息获取:
    设备品牌、型号、软件系统相关信息
    安卓 (oaid 、无线网 SSID 名称、 WiFi 路由器 MAC 地址、设备 MAC 地址、 IMEI 、地理位置 )
    iOS (手机系统重启时间、磁盘总空间、系统总内存空间 )
    广告的展示、点击等数据
    使用目的:
    使用目的:广告请求和视图渲染
    隐私协议地址: http://partner.toutiao.com/privacy
    更新时间: 2020 年 10 月 18 日

    展开全文
  • 热门动态壁纸主题锁屏墙纸精选这款软件将会为用户们提供更多高清精美的壁纸,多种风格分类让你肆意挑选,超多热门的动态壁纸可以让用户们自由选择,为你带来更加个性化的手机桌面。还可以将自己喜欢的视频进行上传,...

    热门动态壁纸主题锁屏墙纸精选这款软件将会为用户们提供更多高清精美的壁纸,多种风格分类让你肆意挑选,超多热门的动态壁纸可以让用户们自由选择,为你带来更加个性化的手机桌面。还可以将自己喜欢的视频进行上传,制作出独一无二的动态壁纸。

    e375e3a22b5cd03c98a9462ec62f4f25.png

    《热门动态壁纸主题锁屏墙纸精选》软件特色:

    流行的壁纸,网红壁纸和流行的网络短视频,拥有您想要的一切,您可以将其设置为桌面锁定屏幕。

    2.透明的桌面主题和创意的视频桌面游戏玩法使移动桌面独树一帜。

    3.您还可以上传本地视频,只需单击一下,就可以将自己喜欢的视频制作到动态桌面中,并自定义独家动态壁纸。

    22e420babc2293bc0596ff71f4827cef.png

    《热门动态壁纸主题锁屏墙纸精选》软件亮点:

    1.所有墙纸均为绝对高清大图,可适应各种型号的手机,并有多种类型可供选择。

    2.各种各样的样式,可以在网上找到许多不同类型的主题样式,整体图片看起来很舒服。

    3.可以找到各种带有引人注目的帧的图片,每张图片都有一个小标签,您可以通过该小标签搜索所需的图片。

    dd8742d9f74bb65fa71db4f4e68d413d.png

    《热门动态壁纸主题锁屏墙纸精选》小编点评:

    使用这款壁纸软件,你将会拥有一个全网最全的动态壁纸库,各种不同风格的动态壁纸应有尽有,用户们可以直接根据自己的喜好在这些分类中进行自由搜索浏览,让你拥有最独特的动态壁纸。

    展开全文
  • 实习期间做的一个项目,项目主要功能是提供动态锁屏壁纸,并实现手势交互,增加可玩性。壁纸资源基于Lottie动画,项目还实现了可以从手机资源库中读取Lottie的json文件,可以从网上下载Lottie资源的json文件,从而可...

    基于Lottie的动态锁屏APP

    先上实现图

    锁屏效果图
    在这里插入图片描述
    APP主页面
    在这里插入图片描述

    预览页面
    在这里插入图片描述

    设置解锁方式
    在这里插入图片描述

    主页面侧边栏
    在这里插入图片描述

    实现思路:(大家实现类似APP时,也可以按照这种步骤进行分工,并进行迭代开发)
    在这里插入图片描述
    重点部分:其实在这个APP中,比较难的一点就是锁屏页面自定义View的实现,和锁屏交互逻辑的实现,现在放上这两个部分的代码。

    锁屏中间部分的自定义View

    package com.example.lockscreen.myview;
    import android.animation.Animator;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.ProgressBar;
    import android.widget.RelativeLayout;
    import android.widget.TextClock;
    import android.widget.TextView;
    import com.airbnb.lottie.LottieAnimationView;
    import com.example.lockscreen.R;
    import com.example.lockscreen.StyleDetailActivity;
    import com.example.lockscreen.vo.CodeData;
    import com.example.lockscreen.vo.ViewDisplay;
    import com.example.lockscreen.vo.WordDisplay;
    import androidx.appcompat.app.AppCompatActivity;
    
    public class LockScreenView extends RelativeLayout {
    
        private ProgressBar mProgressBar;
        private LottieAnimationView mLottieView;
        private RelativeLayout.LayoutParams mProgressBarLayout;
    
        private CodeData mCodeData;
        private ViewDisplay mViewDisplay;
        private Context mContext;
    
        //此视图布局
        private View mView;
    
        //屏幕宽和高
        private int mWidth;
        private int mHeight;
    
        //手指按下时的坐标
        private float mStartX;
        private float mStartY;
    
        //展示该View的Activity
        private AppCompatActivity mActivity;
    
        //显示进度条
        private final float SHOW_PROGRESS = 1f;
    
        //-1代表相对于父容器
        private final int SUBJECT = -1;
    
        //解锁方式
        private int mInteractionCode = 1;
    
        //正在播放动画的文件名(assets下加载)
        private String mLottieName;
    
        //正在播放动画的json字符串(本地加载)
        private String mLottieJson;
    
        public LockScreenView(Context context) {
            this(context, null);
        }
    
    
        public LockScreenView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public LockScreenView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        /**
         * 初始化
         *
         * @param context
         * @param attrs
         */
        private void init(Context context, AttributeSet attrs) {
            mView = LayoutInflater.from(context).inflate(R.layout.lock_screen,this, true);
            mProgressBar = mView.findViewById(R.id.progressBar);
            mProgressBarLayout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            mProgressBarLayout.addRule(RelativeLayout.CENTER_HORIZONTAL);
            mProgressBarLayout.addRule(RelativeLayout.ALIGN_BOTTOM, SUBJECT);
    
            //加载视图布局
            mLottieView = mView.findViewById(R.id.lock_screen_lottie);
    
            mLottieView.addAnimatorListener(myLottieListener);
    
            mActivity = (AppCompatActivity) context;
    
    
            //mContext = getContext();
            mCodeData = new CodeData();
            mViewDisplay = new ViewDisplay(mCodeData);
    
        }
    
        /**
         * 测量
         *
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //测量子view
            measureChildren(widthMeasureSpec, heightMeasureSpec);
            //获取屏幕宽高
            mWidth = getMeasuredWidth();
            mHeight = getMeasuredHeight();
        }
    
        /**
         * 布局
         *
         * @param changed
         * @param l
         * @param t
         * @param r
         * @param b
         */
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
    
            //设置滚动条的相对布局位置和相关属性
            mProgressBar.setMax(mWidth / 5 * 2);
            mProgressBarLayout.topMargin = mHeight / 10 * 9;
            mProgressBarLayout.width = mWidth / 5 * 2;
            mProgressBarLayout.height = mHeight / 100;
            mProgressBar.setLayoutParams(mProgressBarLayout);
        }
    
        /**
         * 动画播放进度监听器
         */
        private Animator.AnimatorListener myLottieListener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }
    
            @Override
            public void onAnimationEnd(Animator animation) {
            }
    
            @Override
            public void onAnimationCancel(Animator animation) {
            }
    
            @Override
            public void onAnimationRepeat(Animator animation) {
                if (mLottieView.getSpeed() < 0) {
                    //用户滑动屏幕后将速度恢复正常
                    mLottieView.setSpeed(1f);
                }
            }
        };
    
        /**
         * 此方法会在所有的控件都从xml中加载完毕后加载
         */
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
        }
    
        /**
         * 监听屏幕点击和移动事件
         * @param event
         * @return
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            final float x = event.getRawX();
            final float y = event.getRawY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mStartX = x;
                    mStartY = y;
                    mLottieView.pauseAnimation();
                    break;
                case MotionEvent.ACTION_MOVE:
                    setProgress(x, y);
                    break;
                case MotionEvent.ACTION_UP: // 手指抬起时和异常取消时都是使用同一种方式判断是否解锁
                case MotionEvent.ACTION_CANCEL:
                    handlerMoveEvent(x, y);
                    break;
            }
            return true;
        }
    
        /**
         * 根据手指触摸的情况更改进度条的进度和Lottie动画的播放状态
         *
         * @param x
         */
        private void setProgress(float x, float y) {
            float offset = getOffset(x, y);
            int progressScale = (int) (mProgressBar.getMax() * offset / mProgressBar.getMax());//进度条进度
            float lottieScale = offset / mProgressBar.getMax();//动画播放进度
            if (offset > 0) {
                //设置进度条进度
                mProgressBar.setAlpha(SHOW_PROGRESS);
                mProgressBar.setProgress(progressScale);
                //设置lottie播放进度
                if (lottieScale <= 1) {
                    mLottieView.setProgress(lottieScale);
                } else {
                    mLottieView.setProgress(1);
                }
            } else {
                mProgressBar.setAlpha(0);
            }
        }
    
        /**
         * 根据进度条进度判断是否解锁成功
         *
         * @param
         */
        private void handlerMoveEvent(float x, float y) {
            if (mProgressBar.getMax() == mProgressBar.getProgress()) {
                //解锁成功
                mActivity.finish();
            } else {
                float offset = getOffset(x, y);
                if (offset >= 0) {
                    //未解锁
                    //重置进度条
                    mProgressBar.setProgress(0);
                    mProgressBar.setAlpha(0);
                    //倒放动画至初始位置
                    mLottieView.setSpeed(-1f);
                    mLottieView.resumeAnimation();
                }
            }
        }
    
        /**
         * 通过用户传进的交互码,设置屏幕解锁方式
         * @return
         */
        public void setDirection(int code) {
            mCodeData.setCode(code);
        }
    
        /**
         * 通过x,y坐标计算出想要的偏移量
         * @param x
         * @param y
         * @return
         */
        private float getOffset(float x, float y){
            float offset = 0;
            offset = mViewDisplay.offsetShow(mStartX , mStartY , x , y);
            return offset;
        }
    
        /**
         * 暴露此接口,用于播放从assets文件夹下加载的动画
         *
         * @param lottieName
         */
        public void setLottieName(String lottieName) {
            mLottieName = lottieName;
            mLottieView.setAnimation(mLottieName);
            invalidate();
        }
    
        /**
         * 暴露此接口,用于播放从本地加载的Lottie动画
         *
         * @param lottieJson
         */
        public void setLottieFromJson(String lottieJson) {
            mLottieJson = lottieJson;
            mLottieView.setAnimationFromJson(mLottieJson, null);
            invalidate();
        }
    
        /**
         * 暴露此接口,用于获取当前正在播放的动画名(assets下加载时)
         *
         * @return
         */
        public String getLottieName() {
            return mLottieName;
        }
    
        /**
         * 暴露此接口,用于获取当前正在播放的json字符串(从本地加载时)
         * @return
         */
        public String getLottieJson() {
            return mLottieJson;
        }
    }
    

    时间和提示文字部分的自定义View

    package com.example.lockscreen.myview;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.LinearGradient;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Shader;
    import android.util.AttributeSet;
    import androidx.appcompat.widget.AppCompatTextView;
    
    
    public class LockScreenTextView extends AppCompatTextView {
    
        private int mViewWidth;
        private LinearGradient mLinearGradient;
        private Paint mPaint;
        private Matrix mGradientMatrix;
        private int mTranslate;
    
        public LockScreenTextView(Context context) {
            this(context, null);
        }
    
        public LockScreenTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public LockScreenTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        /**
         * 测量View
         *
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mViewWidth = getMeasuredWidth();
        }
    
        /**
         * 先在onSizeChanged()方法中进行一些初始化工作,根据View的宽来设置一个LinearGradient渐变渲染器
         * 此方法在onMeasure()方法调用完成后调用
         *
         * @param w
         * @param h
         * @param oldw
         * @param oldh
         */
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            if (mViewWidth > 0) {
                //获取当前绘制TextView的Paint对象
                mPaint = getPaint();
                //自定义渐变渲染器
                mLinearGradient = new LinearGradient(
                        0, 0, mViewWidth, 0, //渲染的起止坐标
                        new int[]{Color.BLACK, Color.WHITE, Color.BLACK},//定义渐变颜色
                        new float[]{0.25F, 0.5F, 1.0F},//不同渲染渲染阶段渲染不同的颜色
                        Shader.TileMode.CLAMP);//Shader渲染器
                //为画笔设置渐变渲染器
                mPaint.setShader(mLinearGradient);
                //创建一个单位矩阵
                mGradientMatrix = new Matrix();
            }
        }
    
        /**
         * 在onDraw方法中,通过矩阵的方法来不断平移渐变效果,使绘制文字时产生动态的闪动效果
         *
         * @param canvas
         */
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (mLinearGradient != null) {
                //每次向右平移字体长度的二十分之一
                mTranslate += mViewWidth / 20;
                if (mTranslate > 2 * mViewWidth) {
                    mTranslate = -mViewWidth;
                }
                //设置单位矩阵平移
                mGradientMatrix.setTranslate(mTranslate, 0);
                //为着色器设置矩阵
                mLinearGradient.setLocalMatrix(mGradientMatrix);
                //循环等待时间
                postInvalidateDelayed(100);
            }
        }
    }
    

    部分手势交互的处理逻辑代码

    /*
    * 按压解锁
    */
    package com.example.lockscreen.myview;
    import android.content.Context;
    import android.content.res.AssetManager;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.RelativeLayout;
    import androidx.appcompat.app.AppCompatActivity;
    import com.airbnb.lottie.LottieAnimationView;
    import com.example.lockscreen.R;
    import org.json.JSONException;
    import org.json.JSONObject;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Calendar;
    
    public class MarkView extends RelativeLayout {
    
        private LottieAnimationView mLottieView;
    
        //上下文
        private Context mContext;
    
        private Calendar mCalendar;
    
        //此视图布局
        private View mView;
    
        //json文件名
        private String mFilename;
    
        //展示该View的Activity
        private AppCompatActivity mActivity;
    
        //json字符串
        private String mLottieJson;
    
        //手指按压开始的时间
        private long mStartTime;
    
        //手指按压结束的时间
        private long mEndTime;
    
        //Lottie图层的时长
        private double mDuration;
    
        //图层结束的帧数
        private int mEndFrame;
    
        //图层开始的帧数
        private int mBeginFrame;
    
        //设置Lottie的起始帧
        private int mLottieStartFrame;
    
        //Lottie的帧率
        private double mFrameRate;
    
        //毫秒数
        private int mMilliSecond;
    
        //BaseView类
        private BaseView mBaseView;
    
        public MarkView(Context context) {
            this(context, null);
        }
    
        public MarkView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MarkView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            //加载视图布局
            mView = LayoutInflater.from(context).inflate(R.layout.lock_screen_interaction, this, true);
            mLottieView = mView.findViewById(R.id.lottie_interaction);
            mBaseView = new BaseView();
    
            mFilename = getResources().getString(R.string.mark_lottie);
            mLottieView.setAnimation(mFilename);
            mLottieStartFrame = getResources().getInteger(R.integer.mark_lottieStartFrame);
            mLottieView.setMinFrame(mLottieStartFrame);
    
            mContext = getContext();
            mLottieJson = mBaseView.getJson(mFilename,mContext);
            datafromJson(mLottieJson);
    
            mMilliSecond = getResources().getInteger(R.integer.mark_milliSecond);
            mDuration = ((mEndFrame - mBeginFrame) / (mFrameRate)) * mMilliSecond;
    
            mActivity = (AppCompatActivity)context;
    
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            final float x = event.getRawX();
            final float y = event.getRawY();
    
            // 手指位置与圆点之间的距离
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mLottieView.setSpeed(1f);
                    mCalendar = Calendar.getInstance();
                    mStartTime = mCalendar.getTimeInMillis();
                    break;
                case MotionEvent.ACTION_MOVE:
                    setProgress();
                    break;
                case MotionEvent.ACTION_UP: // 手指抬起时和异常取消时都是使用同一种方式判断是否解锁
                case MotionEvent.ACTION_CANCEL:
                    handlerMoveEvent();
                    break;
            }
            return true;
        }
    
        /*
        *Lottie播放帧数的设置
        */
        private void setProgress() {
            mCalendar = Calendar.getInstance();
            mEndTime = mCalendar.getTimeInMillis();
            //lottie播放比例
            float playrate;
            playrate = (float) ((mEndTime - mStartTime) / mDuration);
            mLottieView.setProgress(playrate);
        }
    
        /*
         *  手指抬起事件
         */
        private void handlerMoveEvent() {
            //没达到阈值就回放
            if(mLottieView.getFrame() < mEndFrame - 7){
                if(mLottieView.getFrame()  > mLottieStartFrame + 2){//给于误触,简单的点击不响应
                    mLottieView.setSpeed(-1f);
                    mLottieView.resumeAnimation();
                }
            }else{
                mActivity.finish();
            }
        }
    
        /*
         * 从json文件中获取数据
         */
        private void datafromJson(String lottiejson) {
            try {
                //创建一个包含原始json串的json
                JSONObject dataJson = new JSONObject(lottiejson);
                // 读取对象里的字段值
                mBeginFrame = dataJson.getInt("ip");
                mEndFrame = (int) dataJson.getDouble("op");
                mFrameRate = dataJson.getDouble("fr");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
    
    /*
    * 拖动解锁
    */
    package com.example.lockscreen.myview;
    import android.animation.Animator;
    import android.content.Context;
    import android.content.res.AssetManager;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.RelativeLayout;
    import androidx.appcompat.app.AppCompatActivity;
    import com.airbnb.lottie.LottieAnimationView;
    import com.example.lockscreen.R;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class BoxView extends RelativeLayout {
    
        private LottieAnimationView mLottieView;
    
        //上下文
        private Context mContext;
    
        //此视图布局
        private View mView;
    
        //手指按下时的坐标
        private float mStartX;
        private float mStartY;
    
        //屏幕宽和高
        private int mWidth;
        private int mHeight;
    
        //json文件名
        private String mFilename;
    
        //展示该View的Activity
        private AppCompatActivity mActivity;
    
        //拉绳子图层的结束帧
        private int mEndFrame;
    
        //拉绳子的上边界
        private float mRopeTop;
    
        //拉绳子的下边界
        private float mRopeButtom;
    
        //触碰到绳子的标志
        private boolean mTouchFlag;
    
        //在绳子上滑动的标志
        private boolean mSlipFlag;
    
        //json字符串
        private String mLottieJson;
    
        //BaseView类
        private BaseView mBaseView;
    
    
        public BoxView(Context context) {
            this(context, null);
        }
    
        public BoxView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public BoxView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            //加载视图布局
            mView = LayoutInflater.from(context).inflate(R.layout.lock_screen_interaction, this, true);
            mLottieView = mView.findViewById(R.id.lottie_interaction);
            mBaseView = new BaseView();
    
            mFilename = getResources().getString(R.string.giftbox_lottie);
            mContext = getContext();
            mLottieView.setAnimation(mFilename);
            mLottieJson = mBaseView.getJson(mFilename,mContext);
            datafromJson(mLottieJson);
    
            mActivity = (AppCompatActivity)context;
        }
    
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //获取屏幕宽高
            mWidth = getWidth();
            mHeight = getHeight();
            mRopeTop = mHeight / 20 * 11;
            mRopeButtom = mHeight / 13 * 8;
        }
    
        /*
         * 从json文件中获取数据
         */
        private void datafromJson(String lottiejson) {
            try {
                //创建一个包含原始json串的json
                JSONObject dataJson = new JSONObject(lottiejson);
                // 找到layers的json数组
                JSONArray layers = dataJson.getJSONArray("layers");
                // 获取layers数组的第1个json对象
                JSONObject info1 = layers.getJSONObject(1);
                // 读取info1对象里的op字段值
                int op = (int)info1.getDouble("op");
                //比结束帧稍小一点,手指离开时可以有缓冲播放
                mEndFrame = op - 5;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            final float x = event.getRawX();
            final float y = event.getRawY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mStartX = x;
                    mStartY = y;
                    if(mStartY >= mRopeTop && mStartY <= mRopeButtom ){
                        mTouchFlag = true;
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    if(y >= mRopeTop && y <= mRopeButtom) {
                        mSlipFlag = true;
                        }else{
                            mSlipFlag = false;
                        }
                    setProgress(x);
                    break;
                case MotionEvent.ACTION_UP: // 手指抬起时和异常取消时都是使用同一种方式判断是否解锁
                case MotionEvent.ACTION_CANCEL:
                    handlerMoveEvent();
                    break;
            }
            return true;
        }
    
        /*
        * 计算滑动时Lottie播放的对应帧数
         */
        private void setProgress(float x) {
            if(mTouchFlag){
                if(mSlipFlag){//手指在绳子附近滑动
                    if(x - mStartX > 20){//设置误触距离,防止误触和向左移动
                        //手指滑动的距离
                        float length;
                        length = x - mStartX;
                        //Lottie播放比例
                        float playRate;
                        playRate = length / (mWidth / 2);
                        //当前播放的帧数
                        int frame;
                        frame = (int) (mEndFrame  * playRate);
                        //防止实时移动的帧大于最大值
                        if(frame > mEndFrame){
                            frame = mEndFrame;
                        }
                        mLottieView.setFrame(frame);
                    }
                }else{//手指不在绳子附近滑动
                    mLottieView.setSpeed(-0.5f);
                    mLottieView.resumeAnimation();
                    mTouchFlag = false;
                }
            }
        }
    
        /*
         *  手指抬起事件
         */
        private void handlerMoveEvent() {
            if(mTouchFlag && mSlipFlag){
                //还没到达阈值时,让Lottie倒放
                if(mLottieView.getFrame() < mEndFrame){//设置误触距离
                    if(mLottieView.getFrame() > 3){
                        mLottieView.setSpeed(-0.5f);
                        mLottieView.resumeAnimation();
                    }
                }else{
                    mLottieView.setSpeed(0.1f);
                    mLottieView.resumeAnimation();
                    mLottieView.addAnimatorListener(myLottieListener);
                }
            }
            mTouchFlag = false;
            mSlipFlag = false;
        }
    
        /**
         * 动画播放进度监听器
         */
        private Animator.AnimatorListener myLottieListener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }
    
            @Override
            public void onAnimationEnd(Animator animation) {
                mActivity.finish();
            }
    
            @Override
            public void onAnimationCancel(Animator animation) {
            }
    
            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        };
    }
    
    /*
    * 绘制图形解锁
    */
    package com.example.lockscreen.myview;
    import android.animation.Animator;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.RelativeLayout;
    import androidx.appcompat.app.AppCompatActivity;
    import com.airbnb.lottie.LottieAnimationView;
    import com.example.lockscreen.R;
    
    public class CheckView extends RelativeLayout {
    
        private LottieAnimationView mLottieView;
    
        //此视图布局
        private View mView;
    
        //手指按下时的坐标
        private float mStartX;
        private float mStartY;
    
        //屏幕宽和高
        private int mWidth;
        private int mHeight;
    
        //json文件名
        private String mFilename;
    
        //画勾的第一个点的坐标
        private float mFirstX;
        private float mFirstY;
    
        //画勾的第二个点的坐标
        private float mSecondX;
        private float mSecondY;
    
        //画勾的第三个点的坐标
        private float mThirdX;
        private float mThirdY;
    
        //点击次数
        private int mTemp;
    
        //json字符串1
        private String mLottieJson1;
    
        //json字符串2
        private String mLottieJson2;
    
        //json字符串3
        private String mLottieJson3;
    
        //json字符串4
        private String mLottieJson4;
    
        //json字符串5
        private String mLottieJson5;
    
        //json字符串6
        private String mLottieJson6;
    
        //json字符串7
        private String mLottieJson7;
    
        //拼接而成的json的字符串
        private String mAppendLottieJson;
    
        //展示该View的Activity
        private AppCompatActivity mActivity;
    
        //是否点击屏幕的标志
        private boolean mTouchFlag;
    
        //点击区域的上边界
        private float mFieldTop;
    
        //点击区域的下边界
        private float mFieldButtom;
    
        public CheckView(Context context) {
            this(context, null);
        }
    
        public CheckView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CheckView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            //加载视图布局
            mView = LayoutInflater.from(context).inflate(R.layout.lock_screen_interaction, this, true);
            mLottieView = mView.findViewById(R.id.lottie_interaction);
            mFilename = getResources().getString(R.string.check_lottie);
            mLottieView.setAnimation(mFilename);
            mLottieView.playAnimation();
            mLottieView.addAnimatorListener(myLottieListener);
    
            mActivity = (AppCompatActivity)context;
    
            mLottieJson1 = getResources().getString(R.string.check_lottiejson1);
            mLottieJson3 = getResources().getString(R.string.check_lottiejson3);
            mLottieJson5 = getResources().getString(R.string.check_lottiejson5);
            mLottieJson7 = getResources().getString(R.string.check_lottiejson7);
        }
    
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //获取屏幕宽高
            mWidth = getWidth();
            mHeight = getHeight();
            mFieldTop = mHeight / 7 * 2;
            mFieldButtom = mHeight / 9 * 7;
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            final float x = event.getRawX();
            final float y = event.getRawY();
    
            // 手指位置与圆点之间的距离
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mStartX = x;
                    mStartY = y;
                    if(mStartY >= mFieldTop && mStartY <= mFieldButtom){
                        mLottieView.setFrame(0);
                        mLottieView.pauseAnimation();
                        mTemp++;
                        setLocation(mTemp);
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP: // 手指抬起时和异常取消时都是使用同一种方式判断是否解锁
                case MotionEvent.ACTION_CANCEL:
                    handlerMoveEvent();
                    break;
    
            }
            return true;
        }
    
        /*
        * 设置画勾的三个点的坐标
         */
        private void setLocation(int temp){
            switch(temp){
                case 1:
                    mFirstX = changeX(mStartX);
                    mFirstY = changeY(mStartY);
                    mLottieJson2 = "" + mFirstX + "," + mFirstY;
                    break;
                case 2:
                    mSecondX = changeX(mStartX);
                    mSecondY = changeY(mStartY);
                    mLottieJson4 = "" + mSecondX + "," + mSecondY;
                    break;
                case 3:
                    mThirdX = changeX(mStartX);
                    mThirdY = changeY(mStartY);
                    mLottieJson6 = "" + mThirdX + "," +mThirdY;
                    break;
            }
        }
    
        /*
        *  手指抬起事件
         */
        private void handlerMoveEvent() {
            if(mTemp == 3){
                mAppendLottieJson = mLottieJson1 + mLottieJson2 + mLottieJson3 + mLottieJson4 + mLottieJson5 + mLottieJson6 + mLottieJson7;
                mLottieView.setAnimationFromJson(mAppendLottieJson,null);
                mLottieView.playAnimation();
                mTouchFlag = true;
                mTemp = 0;
            }
        }
    
        /*
        *将手机坐标系的左边转化为Lottie坐标系的坐标
         */
        private float changeX(float x){
            float lottieX;
            lottieX = (x - mWidth / 2) / 10;
            return lottieX;
        }
    
        private float changeY(float y){
            float lottieY;
            lottieY = (y - (mHeight / 2 - mHeight / 15)) / 10;
            return lottieY;
        }
    
        /**
         * 动画播放进度监听器
         */
        private Animator.AnimatorListener myLottieListener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
    
            }
    
            @Override
            public void onAnimationEnd(Animator animation) {
                if(mTouchFlag){
                    mTouchFlag = false;
                    mActivity.finish();
                }
            }
    
            @Override
            public void onAnimationCancel(Animator animation) {
            }
    
            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        };
    }
    
    

    说明:
    1.以上就是对于这个项目关键部分的说明,大家可以参考这种思路进行开发;
    2.在项目中还进行了一些优化,比如运用RecyclerView的缓存机制和Flutter提供的预加载和缓存机制减少页面中加载Lottie动画时出现的卡顿问题等等。
    3.这个项目也还有很多需要完善的地方,欢迎大佬们提出意见,也希望这篇博客对大家有所帮助,谢谢。

    项目的源码可以到此查看
    https://github.com/Zero-zhangzehua/LockScreen

    展开全文
  • 机械表动态主题

    2016-10-08 08:53:07
    这个主题很漂亮,本来是付费主题来着,现在免费发出来,待机画面是个机械表内部,很多齿轮转动,挺漂亮,这里发不了图,很遗憾!
  • WIN7动态桌面32windows7-DreamScene
  • 该源码是仿iphone动态萤火虫锁屏应用源码,源码SkyLock,这也是最近弄了一款锁屏,苦于市场百般阻拦与锁屏应用数量实在太多,于是将它拿出来开源;废话不多说,希望大家能够希望,更多说明请看下面的吧。 详细源码...
  • 安卓手机最好一键特效锁屏apk
  • 以我自己惠普笔记本为例 壁纸路径为: C:\Users\hp\AppData\Roaming\360safe\DesktopRest\eye\bk_image 文件后缀.dat 可以用常规图片软件打开!!! 参考链接:...
  • Google Pixel 系列机型内置的航拍动态壁纸一直以来都是该...除此之外,这些动态壁纸在息屏显示、锁屏、解锁过程和桌面划动等操作过程中还有不同的动画效果,交互感极强。Pixel 内置的「绚丽蓝星」动态壁纸不过 Pi...
  • 今天我们为大家分享一下最近某音非常火的电子时钟屏保,让你的电脑屏保动起来,而且随着时间流逝而变化(作为一个时间观念强的人,一定会看着屏保更加惜时如金),让你的电脑锁屏与众不同,瞬间黑科技感十足!...
  • 实战_分析病毒锁屏apk

    2019-09-20 11:06:35
    重启后 被锁屏了 提示 这里输入密码 分析 一: androidKiller 反编译 sjrj.apk 搜索 关键字 这里输入密码 没结果 unicode编码 搜索 也没 搜索 qq关键字也没 这时就想 咋会没关键字了,正常来说 搜索关键字 会有的啊 ...
  • 闲来无事,总觉得目前的Ubuntu桌面锁屏看烦了,依然记得之前手机端曾经流行过一款锁屏软件,想想这个应该会有Linux版了,度娘果然查到了,名字就叫GLUQLO,而且也有Linux版还是开源的,那就开始动起来。 一:安装...
  • 分割线网红八卦罗盘屏保支持苹果和安卓手机使用在进入教程之前,我们先来围观这波动态锁屏效果吧。是不是特别炫酷呢!制作前,我们首先在「运了个营」公众号回复“八卦”获取软件安装包,支持苹果和安卓手机使用。在...
  • 点击文件管理图标,找到内部存储设备中的MIUI/theme,到达theme目录下,若该目录下无文件,则文件被隐藏了,设置显示隐藏文件(隐藏文件中包含了所有下载过的小米主题),将隐藏文件打包发送至电脑。 在电脑中将...
  • 手机水面落叶动态壁纸.apk
  • aerial mac汉化版是一个专为mac用户制作的屏幕...修复了仅以字母顺序下载视频而不是随机播放视频的自动下载器 添加新图标,这要归功于Inferno Design 添加俄语翻译感谢(null) 注意:此版本可在Intel和Apple Sili
  • Windows聚焦是微软在Win10系统中添加的非常好用的功能,把这个功能打开,开启电脑或者锁屏的时候就可以看到一张新的锁屏壁纸。 有时候碰到好看又非常喜欢的壁纸,却又不知道如何保存。事实上,windows 10聚焦的壁纸...
  • 以前用过一个红包锁屏的软件,第一次打开手机出现锁屏,滑动领取收益,当时觉得这功能不错,就查阅资料,写了一个案例, apk运行流程: 进入软件---》启动服务---》关闭手机(可先退出应用)--》再打开手机即可看见...
  • 首先我们来看看这款主题的锁屏。我们点击左下角按钮可以进入自定义界面,可以看到有很多锁屏样式可以选择,可以每天换着用。充电动画也有两种可以切换,默认的是100W超级无敌空气闪充,另一种则是非常酷炫的棒棒糖...
  • 简介dyn-wall-rs的目的是为用户提供一种非常简单的方法来为其系统实现动态墙纸以及动态锁屏。 安装您可以从发行版页面下载二进制文件,但如果愿意,可以通过下面列出的方法之一进行安装。 笔记:
  • 平时我们在使用手机时我们都知道,手机的桌面壁纸和锁屏壁纸都是可以设置为动态壁纸的。而对于平时所使用的电脑来说,电脑的壁纸就更为枯燥一些,只能使用静态的图片来作为电脑的桌面,很无聊很枯燥的。 但是,如果...
  • Android Device Administration 设备管理器——锁屏的实现 最近研究了一下安全这一块的内容,当然,我是比较水的,所以也拿不出什么好知识点,但是有一些冷门的东西我还是可以聊聊的,就拿这个锁屏来说吧,我们...
  • Android 锁屏无法继续定位问题

    千次阅读 2020-02-20 09:00:00
    华为并不行,只支持亮屏,之后我用的双服务唤醒通讯方式实现的华为手机,适配8.0,但其实我觉得就是因为一个电量管理中保持锁屏后继续运行权限导致的, 但这个我没有测试过开了权限这个方式行不行,小伙伴测试的时候...
  • 1.更换登录壁纸 :菜单-系统设置-工作区-工作空间行为-锁屏-外观-接下来选取你喜欢的图片即可 2.更换锁屏壁纸 :菜单-系统设置-工作区-工作空间行为-锁屏-外观-接下来选取你喜欢的图片即可 3.更换登录屏幕的壁纸:...
  • 效果图 知识储备 ...在网上随便搜索找到了这个炫酷的充电动画,可惜是css实现的,想在Android中使用那只能 通过 WebView 来加载了,要传递当前系统电量需要在Java和JS中传值,具体可参考下面的文章 ...
  • 实现锁屏弹窗效果

    2017-01-17 16:57:14
    实现锁屏弹窗效果我使用的是Activity,通过监听锁屏广播,然后在接收到广播的时候弹窗Activity。 Activity有点特备就是需要设置他的几个属性: 1、首先这个Activity必须在onCreate里边设置下 final Window win...
  • 做完上面的操作,就能接收到推送消息了,但是,有时候会发现,当我们把APP后台或者手机锁屏的时候,就收不到推送的消息了;解决办法很简单,因为极光推送是通过BroadcastReceiver调起通知栏的,所以只要动态注册...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,828
精华内容 1,531
关键字:

下载动态锁屏