版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

简单记录下欢迎界面的布局以及倒计时和跳过功能。

效果图

代码分析

1、修改APP整个主题为无标题栏样式:styles.xml文件

  1. <resources>
  2.  
  3. <!-- Base application theme. -->
  4. <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  5. <!-- Customize your theme here. -->
  6. <item name="colorPrimary">@color/colorPrimary</item>
  7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  8. <item name="colorAccent">@color/colorAccent</item>
  9. </style>
  10.  
  11. </resources>

2、设置WelcomeActivity界面为全屏模式:在WelcomeActivity的onCreate方法中添加以下代码

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. /*==========设置全屏======必须在setContentView前面=======*/
  5. /*set it to be no title*/
  6. requestWindowFeature(Window.FEATURE_NO_TITLE);
  7. /*set it to be full screen*/
  8. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
  9.  
  10. setContentView(R.layout.activity_welcom);
  11.  
  12. //初始化控件
  13. initView();
  14.  
  15. //初始化Handler和Runnable
  16. initThread();
  17. }

3、倒计时功能并且修改文字

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

将WelcomeActivity文件复制到项目中【跳转界面的操作根据实际情况填写】【如果不需要倒计时区域文本展现,则设置倒计时区域隐藏即可】

  1. package com.why.project.welcomeactivitydemo;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.os.Handler;
  7. import android.os.Message;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.view.View;
  10. import android.view.Window;
  11. import android.view.WindowManager;
  12. import android.widget.TextView;
  13.  
  14. import java.lang.ref.WeakReference;
  15. import java.util.Timer;
  16. import java.util.TimerTask;
  17.  
  18. /**
  19. * @CreateUser HaiyuKing
  20. * @Used 欢迎界面
  21. * Android Handler leak 分析及解决办法:http://www.cnblogs.com/0616--ataozhijia/p/3672021.html
  22. */
  23. public class WelcomActivity extends AppCompatActivity {
  24.  
  25. /**倒计时文本*/
  26. private TextView mCountdownTextView;
  27.  
  28. private static final int MSG_COUNT_WHAT = 99;
  29. private static final int NUM = 3;
  30. private int countdownNum;//倒计时的秒数
  31. private static Timer timer;//计时器
  32. private MyHandler countdownHandle;//用于控制倒计时子线程
  33. private Runnable runnable;//倒计时子线程
  34.  
  35. @Override
  36. protected void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. /*==========设置全屏======必须在setContentView前面=======*/
  39. /*set it to be no title*/
  40. requestWindowFeature(Window.FEATURE_NO_TITLE);
  41. /*set it to be full screen*/
  42. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
  43.  
  44. setContentView(R.layout.activity_welcom);
  45.  
  46. //初始化控件
  47. initView();
  48.  
  49. //初始化Handler和Runnable
  50. initThread();
  51. }
  52.  
  53. /**
  54. * 初始化控件
  55. * */
  56. private void initView(){
  57. mCountdownTextView = (TextView) findViewById(R.id.id_countdownTextView);
  58. mCountdownTextView.setOnClickListener(new View.OnClickListener() {
  59. @Override
  60. public void onClick(View view) {
  61. stopThread();
  62. openNextActivity(WelcomActivity.this);//打开下一个界面
  63. }
  64. });
  65. }
  66. /**
  67. * 初始化Handler和Runnable
  68. * */
  69. private void initThread(){
  70. //倒计时变量
  71. initCountdownNum();
  72. //handler对象
  73. countdownHandle = new MyHandler(this);
  74. //runnable
  75. runnable = new Runnable() {
  76.  
  77. @Override
  78. public void run() {
  79. //执行倒计时代码
  80. timer = new Timer();
  81. TimerTask task = new TimerTask() {
  82. public void run() {
  83. countdownNum --;
  84.  
  85. Message msg = countdownHandle.obtainMessage();
  86. msg.what = MSG_COUNT_WHAT;//message的what值
  87. msg.arg1 = countdownNum;//倒计时的秒数
  88.  
  89. countdownHandle.sendMessage(msg);
  90. }
  91. };
  92. timer.schedule(task,0,1000);
  93. }
  94. };
  95. }
  96.  
  97. /**必须使用静态类:解决问题:This Handler class should be static or leaks might occur Android
  98. * http://www.cnblogs.com/jevan/p/3168828.html*/
  99. private static class MyHandler extends Handler {
  100. // WeakReference to the outer class's instance.
  101. private WeakReference<WelcomActivity> mOuter;
  102.  
  103. public MyHandler(WelcomActivity activity) {
  104. mOuter = new WeakReference<WelcomActivity>(activity);
  105. }
  106. @Override
  107. public void handleMessage(Message msg) {
  108.  
  109. WelcomActivity theActivity = mOuter.get();
  110.  
  111. if (theActivity != null) {
  112.  
  113. switch (msg.what) {
  114. case MSG_COUNT_WHAT:
  115. if(msg.arg1 == 0){//表示倒计时完成
  116.  
  117. //在这里执行的话,不会出现-1S的情况
  118. if(timer != null){
  119. timer.cancel();//销毁计时器
  120. }
  121.  
  122. openNextActivity(theActivity);//打开下一个界面
  123.  
  124. }else{
  125. theActivity.mCountdownTextView.setText("跳过" + msg.arg1 + "s");
  126. }
  127. break;
  128.  
  129. default:
  130. break;
  131. }
  132. }
  133. }
  134. }
  135.  
  136. /*
  137. * Activity有三个状态:
  138. * 运行——当它在屏幕前台时(位于当前任务堆栈的顶部)。它是激活或运行状态。它就是相应用户操作的Activity
  139. * 暂停——当它失去焦点但仍然对用户可见时,它处于暂停状态
  140. * 停止——完全被另一个Activity覆盖时则处于停止状态。它仍然保留所有的状态和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如果其他地方需要内存,则系统经常会杀死这个Activity。
  141. *
  142. * 运行:OnCreate——>OnStart——>OnResume
  143. * 暂停:OnResume——>OnPause 再次重新运行:——>OnResume
  144. * 停止:
  145. * (1)切换到其他界面或者按home键回到桌面:OnPause——>OnStop 重新执行:——>OnRestart——>OnStart——>OnResume
  146. * (2)退出整个应用或者finish():OnPause——>OnStop——>OnDestroy 重新执行:——>OnCreate——>OnStart——>OnResume
  147. *
  148. * */
  149.  
  150. //1、正常状态下,运行——倒计时——跳转到登录界面,finish欢迎界面
  151. //2、用户在打开应用时,按home键返回到了桌面,过了一段时间再次打开了应用
  152. //3、在欢迎界面,手机出现了一个其他应用的提示对话框,此时实现的是继续倒计时,所以暂未处理
  153.  
  154. @Override
  155. protected void onResume() {
  156. //开启线程
  157. countdownHandle.post(runnable);
  158. super.onResume();
  159.  
  160. }
  161.  
  162. @Override
  163. protected void onStop() {
  164.  
  165. initCountdownNum();//初始化倒计时的秒数,这样按home键后再次进去欢迎界面,则会重新倒计时
  166.  
  167. stopThread();
  168.  
  169. super.onStop();
  170. }
  171.  
  172. //停止倒计时
  173. private void stopThread(){
  174. //在这里执行的话,用户点击home键后,不会继续倒计时进入登录界面
  175. if(timer != null){
  176. timer.cancel();//销毁计时器
  177. }
  178.  
  179. //将线程销毁掉
  180. countdownHandle.removeCallbacks(runnable);
  181. }
  182.  
  183. //打开下一个界面
  184. private static void openNextActivity(Activity mActivity) {
  185. //跳转到登录界面并销毁当前界面
  186. Intent intent = new Intent(mActivity, MainActivity.class);
  187. mActivity.startActivity(intent);
  188.  
  189. mActivity.finish();
  190. }
  191.  
  192. @Override
  193. protected void onDestroy() {
  194. super.onDestroy();
  195. }
  196.  
  197. /*初始化倒计时的秒数*/
  198. private void initCountdownNum(){
  199. countdownNum = NUM;
  200. }
  201. }

将欢迎界面的布局文件复制到项目中

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:background="#ffffff">
  7.  
  8. <!-- 倒计时文本 -->
  9. <TextView
  10. android:id="@+id/id_countdownTextView"
  11. android:layout_width="@dimen/countdown_width"
  12. android:layout_height="@dimen/countdown_width"
  13. android:layout_alignParentTop="true"
  14. android:layout_alignParentRight="true"
  15. android:layout_marginTop="@dimen/countdown_margin"
  16. android:layout_marginRight="@dimen/countdown_margin"
  17. android:text=""
  18. android:textSize="@dimen/countdown_text_size"
  19. android:textColor="#ffffff"
  20. android:gravity="center"
  21. android:background="@drawable/countdown_text_circle_bg_drawable"/>
  22.  
  23. </RelativeLayout>

将倒计时区域的背景countdown_text_circle_bg_drawable.xml复制到项目中

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:shape="rectangle">
  4.  
  5. <!-- 矩形的圆角半径(宽度的一半) -->
  6. <corners android:radius="@dimen/countdown_radius"/>
  7.  
  8. <!-- 填充 -->
  9. <solid android:color="#414141"/><!-- 填充的颜色 -->
  10. <!-- <solid android:color="#E0B3B3B3"/> -->
  11.  
  12. </shape>

在dimens.xml中添加以下代码

  1. <resources>
  2.  
  3. <!-- Default screen margins, per the Android Design guidelines. -->
  4. <dimen name="activity_horizontal_margin">16dp</dimen>
  5. <dimen name="activity_vertical_margin">16dp</dimen>
  6.  
  7. <!-- *********************************欢迎界面**************************************** -->
  8. <!-- 倒计时区域的宽度 -->
  9. <dimen name="countdown_width">48dp</dimen>
  10. <!-- 倒计时区域的半径(宽度的一半) -->
  11. <dimen name="countdown_radius">24dp</dimen>
  12. <!-- 倒计时区域的外边距 -->
  13. <dimen name="countdown_margin">15dp</dimen>
  14. <!-- 倒计时区域的文字大小 -->
  15. <dimen name="countdown_text_size">12sp</dimen>
  16.  
  17. </resources>

建议在styles.xml中设置主题样式为无标题栏

  1. <resources>
  2.  
  3. <!-- Base application theme. -->
  4. <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  5. <!-- Customize your theme here. -->
  6. <item name="colorPrimary">@color/colorPrimary</item>
  7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  8. <item name="colorAccent">@color/colorAccent</item>
  9. </style>
  10.  
  11. </resources>

在AndroidManifest.xml中声明WelcomeActivity

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.why.project.welcomeactivitydemo">
  4.  
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:roundIcon="@mipmap/ic_launcher_round"
  10. android:supportsRtl="true"
  11. android:theme="@style/AppTheme">
  12. <!-- 欢迎界面 -->
  13. <activity android:name=".WelcomActivity">
  14. <intent-filter>
  15. <action android:name="android.intent.action.MAIN"/>
  16.  
  17. <category android:name="android.intent.category.LAUNCHER"/>
  18. </intent-filter>
  19. </activity>
  20.  
  21. <activity android:name=".MainActivity">
  22. </activity>
  23. </application>
  24.  
  25. </manifest>

三、使用方法

省略。

混淆配置

参考资料

This Handler class should be static or leaks might occur Android

项目demo下载地址

https://github.com/haiyuKing/WelcomeActivityDemo

WelcomeActivity【欢迎界面】的更多相关文章

  1. Android WelcomeActivity 启动画更换网络图片

    1.运行效果  第一张是本地的启动图,第二张是网络启动图       2.用到的第三方jar包   Android-Universal-Image-Loader-master 不熟的请看  Andro ...

  2. 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

    大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...

  3. 浅谈Android的广告欢迎界面(倒计时)

    前些时候就是别人问我他的android APP怎么做一个广告的欢迎界面,就是过几秒后自动跳转到主界面的实现. 也就是下面这种类似的效果.要插什么广告的话你就换张图吧. 那么我就思考了下,就用了andr ...

  4. 【Android UI设计与开发】第04期:引导界面(四)仿人人网V5.9.2最新版引导界面

    这一篇我将会以人人网的引导界面为实例来展开详细的讲解,人人网的引导界面比较的新颖,不同于其他应用程序千篇一律的靠滑动来引导用户,而是以一个一个比较生动形象的动画效果展示在用户们的面前,有一种给人眼前一 ...

  5. Android 欢迎界面淡入效果并用WebView加载网址

    1.首先是欢迎界面布局文件,只有一个背景图片:welcome.xml: <?xml version="1.0" encoding="utf-8"?> ...

  6. Android UI经常使用实例 怎样实现欢迎界面(Splash Screen)

    在Android平台下.下载一个应用后,首次打开映入眼帘的便是Splash Screen,暂且不说Android的设计原则提不提倡这样的Splash Screen.先来看看一般使用Splash Scr ...

  7. Android课程设计第五天欢迎界面(滑动)和图形选择

    注意:课程设计只为完成任务,不做细节描述~ 滑动界面 package com.example.myapplication; import android.content.Intent; import ...

  8. android开机引导界面的几种实现

    不少应用在设计的时候都会有几个引导界面,这里总结一下几个典型实现: 之前自己做过仅具有一个引导界面的应用,在welcomeActivity中设置一张图片,更复杂的为该图片设置一个渐入渐出的动画,然后利 ...

  9. Android 记住密码和自动登录界面的实现(SharedPreferences 的用法)

    原文:http://blog.csdn.net/liuyiming_/article/details/7704923 SharedPreferences介绍: SharedPreferences是An ...

随机推荐

  1. Python中使用MongoEngine3

    最近重新拾起Django,但是Django并不支持mongodb,但是有一个模块mongoengine可以实现Django Model类似的封装.但是mongoengine的中文文档几乎没有,有的也是 ...

  2. GitHub 系列之「怎样使用 GitHub?」

    1.写在前边的话,为什么要写CitHub? 跟朋友在交流的时候听到求职的时候发现有些公司要附Github帐号,一个优秀的 GitHub 账号当然能让你增色不少.自己之前听说过,但没有花时间研究,最后花 ...

  3. persistent_storage_worker.go

    package) ) :length],) ) :length]) } func (engine *Engine) persistentStorageInitWorker(shard int) {   ...

  4. BZOJ_2460_[BeiJing2011]元素_线性基

    BZOJ_2460_[BeiJing2011]元素_线性基 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔 法矿石炼制法杖的技术.那时人们就认识 ...

  5. HashMap 实现及原理

    1.为什么用HashMap? HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和 ...

  6. 基于思科模拟器的AAA配置与验证

    拓扑图: 地址表如图所示 三个路由器之间采用ospf协议达到互通 先做ping通测试 由ApingB 由ApingC 配置AAA认证 在R1上 R1(config)#username shuaiqiy ...

  7. Java核心技术梳理-基础类库

    一.引言 Oracle为Java提供了丰富的基础类库,Java 8 提供了4000多个基础类库,熟练掌握这些基础类库可以提高我们的开发效率,当然,记住所有的API是不可能也没必要的,我们可以通过API ...

  8. C++线程安全日志库-Win32接口实现

    分享一个C++日志库,使用Win32接口编写,而且是线程安全的日志库.比较简单,只有2个文件,容易上手,使用起来也很简单 头文件 如下是日志库的头文件,接口看似很多,但是使用起来最常用的也就那么几个 ...

  9. Redis介绍使用及进阶

    目录: 一.介绍 二.缓存问题 三.Redis内存滥用 四.键命名规范 五.Redis使用场景 六.持久化操作 七..Net Core 使用redis 简单介绍 一.介绍 1. 高性能-- Redis ...

  10. ES 16 - 对Elasticsearch中的索引数据进行增删改查 (CRUD)

    目录 1 创建document 1.1 创建时手动指定id 1.2 创建时自动生成id 2 查看document 2.1 根据id查询文档 2.2 通过_source字段控制查询结果 3 修改docu ...