飞道的博客

【有内鬼,终止交易】风靡朋友圈的壁纸,实现代码竟如此简单 | 原力计划

309人阅读  评论(0)

作者 | sanmianti

来源 | CSDN博客

出品 | CSDN(ID:CSDNnews)

前几天刷抖音时,看到一款壁纸,显示的是诺基亚时代的键盘机样式,昏黄的屏幕显示着【有内鬼,终止交易】的消息内容。感觉很有创意,记忆一下飘到十年前,那时候手机没有微信,没有QQ,没有抖音~蛮荒时代,大家都是通过短信聊天儿,一条信息一毛钱,偶尔通过移动梦网上网充个浪,一不小心用掉3、5M流量然后电话就欠费停机了, 哈哈哈哈。

既然那么有时代感,那么能引起我们共同的追忆,想着如果能做一款应用,它不仅仅是一款壁纸,而且可以点击按键,甚至可以收发短信,拨打电话,岂不是很酷。光说不练假把式,说干就干,接下来就看我们如何实现它!

实现思路

先给大家看一下效果图:

看似复杂,实际上整个应用就由一个主activity架起,activity布局上半部分是Android原生的两个ImageView(MyNokia 图标及模拟屏幕效果),布局下半部分即键盘处是一个WebView内嵌一个本地页面,键盘效果由本地HTML网页渲染得到,通话及短信都是调用的系统界面。

该应用的难点在于如何准确的在一张图片上的各个部位绑定监听事件,例如数字键、星号键、确认键等等。网上有各种实现思路,但尝试后发现都不太理想,要么过于复杂、要么在不同设备上适配性不佳,监听点击位置不准确。

后来转变思路,尝试将该图片切割为不同的小模块,然后为每一个模块View绑定监听事件,最后将各个子模块合并在一起,从视觉效果上就像一张完整的图片。

比较幸运的是之前有一定的PS使用经验,在PS里面有一个非常好用的工具可以帮助我们快速完成上述切割步骤。该工具叫【切片工具】,使用切片工具将目标图片划分为一个一个小模块后,然后选择【文件】→【导出】→【存储为web格式】,PS自动会将图片切割为一个一个的小模块(item)然后组合在一起生成一个HTML文件,该HTML打开后渲染出切割前的完整图片样式。切割完成后我们在应用中直接嵌入该HTML,同时为HTML中的每一个item绑定监听事件,并将点击事件透传给原生activity进行处理即可。

详细代码

Github 源码:https://github.com/sanmianti/MyNokia

layout布局文件

两个ImageView分别显示NOKIA Logo和屏幕效果,三个TextView分别对应着【销毁】按钮和【退出】按钮以及屏幕中央正文显示,一个Web用于加载本地HTML渲染出键盘效果。


   
  1. 1<?xml version= "1.0" encoding= "utf-8"?>
  2. 2
  3. 3<layout xmlns:app= "http://schemas.android.com/apk/res-auto">
  4. 4
  5. 5    <android.support.constraint.ConstraintLayout
  6. 6
  7. 7    ......
  8. 8
  9. 9        android:layout_width= "match_parent"
  10. 10
  11. 11        android:layout_height= "match_parent">
  12. 12
  13. 13
  14. 14
  15. 15        <ImageView
  16. 16
  17. 17        ......
  18. 18
  19. 19            android:id= "@+id/imageView"
  20. 20
  21. 21            android:layout_width= "match_parent"
  22. 22
  23. 23            android:layout_height= "wrap_content"/>
  24. 24
  25. 25
  26. 26
  27. 27        <ImageView
  28. 28
  29. 29        ......
  30. 30
  31. 31            android:id= "@+id/imageView2"
  32. 32
  33. 33            android:layout_width= "match_parent"
  34. 34
  35. 35            android:layout_height= "0dp"
  36. 36
  37. 37            android:src= "@drawable/screen"/>
  38. 38
  39. 39
  40. 40
  41. 41        <TextView
  42. 42
  43. 43        ......
  44. 44
  45. 45            android:id= "@+id/input"
  46. 46
  47. 47            android:layout_width= "wrap_content"
  48. 48
  49. 49            android:layout_height= "wrap_content"
  50. 50
  51. 51            android:text= "讯息:\n\n有内鬼,终止交易!"/>
  52. 52
  53. 53
  54. 54
  55. 55        <TextView
  56. 56
  57. 57               ......
  58. 58
  59. 59            android:layout_width= "wrap_content"
  60. 60
  61. 61            android:layout_height= "wrap_content"
  62. 62
  63. 63            android:text= "销毁"/>
  64. 64
  65. 65
  66. 66
  67. 67        <TextView
  68. 68
  69. 69               ......
  70. 70
  71. 71            android:layout_width= "wrap_content"
  72. 72
  73. 73            android:layout_height= "wrap_content"
  74. 74
  75. 75            android:padding= "24dp"
  76. 76
  77. 77            android:text= "退出"/>
  78. 78
  79. 79
  80. 80
  81. 81        <WebView
  82. 82
  83. 83        ......
  84. 84
  85. 85            android:id= "@+id/webview_keyboard"
  86. 86
  87. 87            android:layout_width= "0dp"
  88. 88
  89. 89            android:layout_height= "0dp"/>
  90. 90
  91. 91    </android.support.constraint.ConstraintLayout>
  92. 92
  93. 93</layout>

拨打电话


   
  1. 1private void callPhone(String number) {
  2. 2
  3. 3     if (TextUtils.isEmpty(number)) {
  4. 4
  5. 5        showToastMessage( "请输入手机号");
  6. 6
  7. 7    } else {
  8. 8
  9. 9        Intent intent =  new Intent();
  10. 10
  11. 11        intent.setAction(Intent.ACTION_CALL);
  12. 12
  13. 13        Uri data = Uri.parse( "tel:" + number);
  14. 14
  15. 15        intent.setData(data);
  16. 16
  17. 17        startActivity(intent);
  18. 18
  19. 19    }
  20. 20
  21. 21}

跳转至短信列表


   
  1. 1private void toSMSList(){
  2. 2
  3. 3    try{
  4. 4
  5. 5        Intent intent4 =  new Intent();
  6. 6
  7. 7        intent4.setClassName( "com.android.mms", "com.android.mms.ui.ConversationList");
  8. 8
  9. 9        startActivity(intent4);
  10. 10
  11. 11    }catch (Exception e){
  12. 12
  13. 13        showToastMessage( "打开短信失败");
  14. 14
  15. 15    }
  16. 16
  17. 17
  18. 18
  19. 19}

打开通讯录


   
  1. 1private void toAddressList(){
  2. 2
  3. 3    try{
  4. 4
  5. 5        Intent intent =  new Intent(Intent.ACTION_VIEW, ContactsContract.Contacts.CONTENT_URI);
  6. 6
  7. 7        startActivityForResult(intent,  0);
  8. 8
  9. 9    }catch (Exception e){
  10. 10
  11. 11        showToastMessage( "打开通讯录失败");
  12. 12
  13. 13    }
  14. 14
  15. 15}

加载键盘布局及监听JS点击事件


   
  1. 1binding.webviewKeyboard.loadUrl( "file:///android_asset/15694580471773267.html");
  2. 3binding.webviewKeyboard.addJavascriptInterface( new MainActivityJS(),  "jsObj");

说那么多,看的可能云里雾里,不妨结合源码看一下,跑一下demo,主代码拢共不到300行。很简单,聪明的你肯定一看就懂。如遇到任何问题,欢迎留言反馈。

源码及下载

Github MyNokia 源码:

https://github.com/sanmianti/MyNokia

点我下载安装包:https://download.csdn.net/download/u012719153/12196860

原文链接:

https://blog.csdn.net/u012719153/article/details/104548331

【End】

在全民抗疫的特殊时期下,在人员复杂、流动量大地方的出入口处都设置了无接触式无感红外人体测温系统

在这次疫情防控中,无感人体测温系统发挥了怎样的作用高精准的无感人体测温系统的核心技术武器是什么?对于开发者们来说,大家应该了解哪些技术

今晚8点多场景疫情防控:解读云边端联动下的全栈 AI 技术应用

推荐阅读 

腾讯朋友、钉钉等被微信违规公示点名;谷歌更新安卓修复数百万台芯片漏洞;微软终止支持.NET Core 3.0 | 极客头条

独家揭秘阿里自研飞天操作系统洛神平台如何支撑起 2684 亿全球大促!| 问底中国 IT 技术演进

为什么说Transformer就是图神经网络?

我在武汉卖手机

必看!Spark 进阶之路之「SparkSQL」入门概述 | 博文精选

比特币归谁所有?有人通过分析区块链数据集找到答案

你点的每一个在看,我认真当成了喜欢


转载:https://blog.csdn.net/csdnnews/article/details/104681941
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场