WelcomeActivity【欢迎界面】

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

前言

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

效果图

代码分析

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

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

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

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*==========设置全屏======必须在setContentView前面=======*/
        /*set it to be no title*/ requestWindowFeature(Window.FEATURE_NO_TITLE); /*set it to be full screen*/ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_welcom);
        
        //初始化控件
        initView();

        //初始化Handler和Runnable
        initThread();
    }

 三、倒计时功能而且修改文字github

使用步骤

1、项目组织结构图

注意事项:app

一、  导入类文件后须要change包名以及从新import R文件路径ide

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

2、导入步骤

将WelcomeActivity文件复制到项目中【跳转界面的操做根据实际状况填写】【若是不须要倒计时区域文本展示,则设置倒计时区域隐藏便可

package com.why.project.welcomeactivitydemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @CreateUser HaiyuKing
 * @Used 欢迎界面
 * Android Handler leak 分析及解决办法:http://www.cnblogs.com/0616--ataozhijia/p/3672021.html
 */
public class WelcomActivity extends AppCompatActivity {
    
    /**倒计时文本*/
    private TextView mCountdownTextView;

    private static final int MSG_COUNT_WHAT = 99;
    private static final int NUM = 3;
    private int countdownNum;//倒计时的秒数
    private static Timer timer;//计时器
    private MyHandler countdownHandle;//用于控制倒计时子线程
    private Runnable runnable;//倒计时子线程
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*==========设置全屏======必须在setContentView前面=======*/
        /*set it to be no title*/
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        /*set it to be full screen*/
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_welcom);
        
        //初始化控件
        initView();

        //初始化Handler和Runnable
        initThread();
    }
    
    
    /**
     * 初始化控件
     * */
    private void initView(){
        mCountdownTextView = (TextView) findViewById(R.id.id_countdownTextView);
        mCountdownTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopThread();
                openNextActivity(WelcomActivity.this);//打开下一个界面
            }
        });
    }
    /**
     * 初始化Handler和Runnable
     * */
    private void initThread(){
        //倒计时变量
        initCountdownNum();
        //handler对象
        countdownHandle = new MyHandler(this);
        //runnable
        runnable = new Runnable() {
            
            @Override
            public void run() {
                //执行倒计时代码
                timer = new Timer();
                TimerTask task = new TimerTask() {
                    public void run() {
                        countdownNum --;
                        
                        Message msg = countdownHandle.obtainMessage();
                        msg.what = MSG_COUNT_WHAT;//message的what值
                        msg.arg1 = countdownNum;//倒计时的秒数
                        
                        countdownHandle.sendMessage(msg);
                    }
                };
                timer.schedule(task,0,1000);
            }
        };
    }
    
    /**必须使用静态类:解决问题:This Handler class should be static or leaks might occur Android
     * http://www.cnblogs.com/jevan/p/3168828.html*/
    private static class MyHandler extends Handler {
        // WeakReference to the outer class's instance.
        private WeakReference<WelcomActivity> mOuter;
        
        public MyHandler(WelcomActivity activity) {
            mOuter = new WeakReference<WelcomActivity>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            
            WelcomActivity theActivity = mOuter.get();
            
            if (theActivity != null) {
                
                switch (msg.what) {
                    case MSG_COUNT_WHAT:
                        if(msg.arg1 == 0){//表示倒计时完成
                            
                            //在这里执行的话,不会出现-1S的状况
                            if(timer != null){
                                timer.cancel();//销毁计时器
                            }

                            openNextActivity(theActivity);//打开下一个界面

                            
                        }else{
                            theActivity.mCountdownTextView.setText("跳过" + msg.arg1 + "s");
                        }
                        break;
    
                    default:
                        break;
                }
            }
        }
    }
    
    /*
     * Activity有三个状态:
     * 运行——当它在屏幕前台时(位于当前任务堆栈的顶部)。它是激活或运行状态。它就是相应用户操做的Activity
     * 暂停——当它失去焦点但仍然对用户可见时,它处于暂停状态
     * 中止——彻底被另外一个Activity覆盖时则处于中止状态。它仍然保留全部的状态和成员信息。然而对用户是不可见的,因此它的窗口将被隐藏,若是其余地方须要内存,则系统常常会杀死这个Activity。
     * 
     * 运行:OnCreate——>OnStart——>OnResume
     * 暂停:OnResume——>OnPause  再次从新运行:——>OnResume
     * 中止:
     * (1)切换到其余界面或者按home键回到桌面:OnPause——>OnStop   从新执行:——>OnRestart——>OnStart——>OnResume
     * (2)退出整个应用或者finish():OnPause——>OnStop——>OnDestroy   从新执行:——>OnCreate——>OnStart——>OnResume
     * 
     * */
    
    //一、正常状态下,运行——倒计时——跳转到登陆界面,finish欢迎界面
    //二、用户在打开应用时,按home键返回到了桌面,过了一段时间再次打开了应用
    //三、在欢迎界面,手机出现了一个其余应用的提示对话框,此时实现的是继续倒计时,因此暂未处理
    
    @Override
    protected void onResume() {
        //开启线程
        countdownHandle.post(runnable);
        super.onResume();
        
    }
    
    @Override
    protected void onStop() {
        
        initCountdownNum();//初始化倒计时的秒数,这样按home键后再次进去欢迎界面,则会从新倒计时

        stopThread();
        
        super.onStop();
    }

    //中止倒计时
    private void stopThread(){
        //在这里执行的话,用户点击home键后,不会继续倒计时进入登陆界面
        if(timer != null){
            timer.cancel();//销毁计时器
        }

        //将线程销毁掉
        countdownHandle.removeCallbacks(runnable);
    }

    //打开下一个界面
    private static void openNextActivity(Activity mActivity) {
        //跳转到登陆界面并销毁当前界面
        Intent intent = new Intent(mActivity, MainActivity.class); mActivity.startActivity(intent); mActivity.finish();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    
    /*初始化倒计时的秒数*/
    private void initCountdownNum(){
        countdownNum = NUM;
    }
}

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <!-- 倒计时文本 -->
    <TextView 
        android:id="@+id/id_countdownTextView"
        android:layout_width="@dimen/countdown_width"
        android:layout_height="@dimen/countdown_width"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_marginTop="@dimen/countdown_margin"
        android:layout_marginRight="@dimen/countdown_margin"
        android:text=""
        android:textSize="@dimen/countdown_text_size"
        android:textColor="#ffffff"
        android:gravity="center"
        android:background="@drawable/countdown_text_circle_bg_drawable"/>

</RelativeLayout>

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

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

</shape>

在dimens.xml中添加如下代码

<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <!-- *********************************欢迎界面**************************************** -->
    <!-- 倒计时区域的宽度 -->
    <dimen name="countdown_width">48dp</dimen>
    <!-- 倒计时区域的半径(宽度的一半) -->
    <dimen name="countdown_radius">24dp</dimen>
    <!-- 倒计时区域的外边距 -->
    <dimen name="countdown_margin">15dp</dimen>
    <!-- 倒计时区域的文字大小 -->
    <dimen name="countdown_text_size">12sp</dimen>
    
</resources>

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

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

在AndroidManifest.xml中声明WelcomeActivity

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.why.project.welcomeactivitydemo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!-- 欢迎界面 -->
        <activity android:name=".WelcomActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity android:name=".MainActivity">
        </activity>
    </application>

</manifest>

3、使用方法

省略。post

混淆配置

ui

参考资料

This Handler class should be static or leaks might occur Android

项目demo下载地址

https://github.com/haiyuKing/WelcomeActivityDemo