通过快速开发Android App 之项目准备(一)差不多完成一个简单的界面!接下来是工具类封装与首页引导页开发!
1.封装Log,方便使用!
日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。:
1.static Level DEBUG :
DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的。
2.static Level INFO
INFO level表明 消息在粗粒度级别上突出强调应用程序的运行过程。
3.static Level WARN
WARN level表明会出现潜在错误的情形。
4.static Level ERROR
ERROR level指出虽然发生错误事件,但仍然不影响系统的继续运行。
5.static Level FATAL
FATAL level指出每个严重的错误事件将会导致应用程序的退出。
另外,还有两个可用的特别的日志记录级别:
1.static Level ALL
ALL Level是最低等级的,用于打开所有日志记录。
2.static Level OFF
OFF Level是最高等级的,用于关闭所有日志记录。
------------------------------------------------------------------------------------------------------------------------------------------------------
介绍完毕之后,开始正式开始搞事情!
这个时候Utils目录可以登场了,在Utils创建一个日志封装类(L)
package com.example.qqazl001.smartbutler.utils;
import android.util.Log;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutler.utils
* 文件名:L
* 创建者: RUI
* 创建时间:2018-08-16 23:03
* 描述:Log封装类
* */
public class L {
//开关
public static final Boolean DEBUG= true;
//TAG
public static final String TAG = "smartbutler";
//5个 DEBUG 等级 DIWEF
public static void d(String text){
if(DEBUG){
Log.d(TAG,text);
}
}
public static void i(String text){
if(DEBUG){
Log.i(TAG,text);
}
}
public static void w(String text){
if(DEBUG){
Log.w(TAG,text);
}
}
public static void e(String text){
if(DEBUG){
Log.e(TAG,text);
}
}
public static void f(String text){
if(DEBUG){
Log.wtf(TAG,text);
}
}
}
,里面包含了d i w e f 五种日志方法!调用方法如下:(就是这样简单粗暴)
L.d("我是测试文本");
L.i("我是测试文本");
L.w("我是测试文本");
L.e("我是测试文本");
L.f("我是测试文本");
2.早餐(Log日志)吃完了,现在可以吃午餐(封装SharedPreferences)了
数据的存储,安卓有4种,SharedPreferences、SQLite、ContentProvider和 File,安卓的存储方式虽然多,但是弱水三千,我只取一瓢(SharedPreferences)
想要搞定获取芳心(SharedPreferences)当然得先了解它!
SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中;当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出。
其中的原理是通过Android系统生成一个xml文件保到:/data/data/包名/shared_prefs目录下,类似键值对的方式来存储数据。
Sharedpreferences提供了常规的数据类型保存接口比如:int、long、boolean、String、Float、Set和Map这些数据类型。
搞定它只需要三步:
(1)定义存取方式 get/put
(2)明确数据类型 Int/String/Boolean/
(3)定义删除功能 单个或者全部
在Utils创建一个Shared{references封装类(ShareUtil)
听过上下文获取SharedPreferences对象,通过edit编辑写入Key-Values
package com.example.qqazl001.smartbutler.utils;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutler.utils
* 文件名:ShareUtil
* 创建者: RUI
* 创建时间:2018-08-16 23:19
* 描述:数据轻量级存储封装
*/
import android.content.Context;
import android.content.SharedPreferences;
import java.lang.reflect.Modifier;
public class ShareUtil {
//存储名称
public static final String NAME = "config";
//上传字符串对象
public static void putString(Context mContext,String key,String values){
//获取SharedPreferences对象
SharedPreferences sp = mContext.getSharedPreferences(NAME,Context.MODE_PRIVATE);
//获取编辑对象
sp.edit().putString(key,values).commit();
}
//获取字符串对象
public static String getString(Context mContext,String key,String defValue){
SharedPreferences sp = mContext.getSharedPreferences(NAME,Context.MODE_PRIVATE);
return sp.getString(key,defValue);
}
//上传数值对象
public static void putInt(Context mContext,String key,int values){
SharedPreferences sp = mContext.getSharedPreferences(NAME,mContext.MODE_PRIVATE);
sp.edit().putInt(key,values).commit();
}
//获取数值对象
public static int getInt(Context mContext,String key,int defValues){
SharedPreferences sp = mContext.getSharedPreferences(NAME,mContext.MODE_PRIVATE);
return sp.getInt(key,defValues);
}
//上传布尔值对象
public static void putBoolean(Context mContext,String key,Boolean values){
SharedPreferences sp = mContext.getSharedPreferences(NAME,mContext.MODE_PRIVATE);
sp.edit().putBoolean(key,values).commit();
}
//获取布尔值对象
public static Boolean getBoolean(Context mContext,String key,Boolean defvalues){
SharedPreferences sp = mContext.getSharedPreferences(NAME, mContext.MODE_PRIVATE);
return sp.getBoolean(key,defvalues);
}
//删除单个
public static void delShare(Context mContext,String key){
SharedPreferences sp = mContext.getSharedPreferences(NAME,mContext.MODE_PRIVATE);
sp.edit().remove(key).commit();
}
//清空全部
public static void delAll(Context mContext){
SharedPreferences sp = mContext.getSharedPreferences(NAME,mContext.MODE_PRIVATE);
sp.edit().clear().commit();
}
}
3.改封装的都封装好了,现在开始首页逻辑的跳转小技巧了
主要逻辑是,通过2000ms的时延,判断是否第一次运行,如果是就运行引导页,如果不是就直接进入主界面
需要完成以下4个操作,完善实现引导页!
(1)延时2000ms
(2)判断程序是否第一次运行
(3)自定义字体
(4)Activity全屏主题
在utils创建一个类StaticClass存放数据和常量
package com.example.qqazl001.smartbutler.utils;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutler.utils
* 文件名:StaticClass
* 创建者: RUI
* 创建时间:2018-08-14 20:39
* 描述:数据/常量
* */
public class StaticClass {
//闪屏页延时
public static final int HANDLER_SPLASH = 1001;
//判断程序是否第一次运行
public static final String SHARE_IS_FIRST = "isfirst";
}
创建一个工具类,封装了加载字体的方法
package com.example.qqazl001.smartbutlers.utility;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutlers.utility
* 创建时间:2018-09-2421:31
* 作者:rui
* 描述:统一工具类
*/
import android.content.Context;
import android.graphics.Typeface;
import android.widget.TextView;
public class UtilTools {
//设置字体发方法
public static void setFont(Context mContext, TextView textView){
//设置字体
Typeface fontType = Typeface.createFromAsset(mContext.getAssets(),"fonts/niuzuo.ttf");
textView.setTypeface(fontType);
}
}
判断是否第一次运行,从而选择跳转到引导页或者主页面,当第一次运行之后,利用之前的数据封装类,存入判断是否第一次运行的数据(true、false)!
设置了闪屏页的字体,创建文件夹main-assets-fonts 在fonts中存放字体文件
package com.example.qqazl001.smartbutlers.ui;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutlers.ui
* 创建时间:2018-09-1719:12
* 作者:rui
* 描述:闪屏页
*/
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.example.qqazl001.smartbutlers.MainActivity;
import com.example.qqazl001.smartbutlers.R;
import com.example.qqazl001.smartbutlers.utility.ShareUtility;
import com.example.qqazl001.smartbutlers.utility.StaticClass;
import com.example.qqazl001.smartbutlers.utility.UtilTools;
/**
* 1.延时2000ms 判断是否第一次运行
* 2.自定义字体
* 3.Activity全屏
* */
public class SplashActicity extends AppCompatActivity{
private TextView tv_splash;
//使用Handler处理是否进入引导页
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case StaticClass.HANDLER_SPLASH:
if(isFirsts()){
//跳转到引导页
startActivity(new Intent(SplashActicity.this,GuideActivity.class));
}else{
//跳转到主页面
startActivity(new Intent(SplashActicity.this, MainActivity.class));
}
}
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
//初始化控件
initView();
}
public void initView(){
//初始化控件
tv_splash = findViewById(R.id.tv_splash);
//延时2000ms
handler.sendEmptyMessageDelayed(StaticClass.HANDLER_SPLASH,2000);
//设置字体
UtilTools.setFont(SplashActicity.this,tv_splash);
}
//判断是否第一次运行
public Boolean isFirsts(){
//获取存储中isFirst的状态
boolean isFirst = ShareUtility.getBoolean(SplashActicity.this,StaticClass.SHARE_IS_FIRST,true);
if(isFirst){
//第一次运行后设置为false
ShareUtility.putBoolean(SplashActicity.this,StaticClass.SHARE_IS_FIRST,false);
//第一次运行返回true
return true;
}else{
return false;
}
}
}
判断跳转之后,第一次运行当然是到引导页了,首先得修改引导页的布局,当然还有3个布局页面要创建,分别是(viewpager_one.xml,viewpager_three.xml,viewpager_three.xml)内容简单,则省略!
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/mVPage"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v4.view.ViewPager>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_marginBottom="15dp"
android:layout_centerHorizontal="true">
<ImageView
android:id="@+id/circle1"
android:layout_width="15dp"
android:layout_height="15dp"/>
<ImageView
android:id="@+id/circle2"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp" />
<ImageView
android:id="@+id/circle3"
android:layout_width="15dp"
android:layout_height="15dp"/>
</LinearLayout>
<ImageView
android:id="@+id/iv_back"
android:layout_marginTop="20dp"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:src="@drawable/iv_back"/>
</RelativeLayout>
布局页面设置好之后,通过ViewParger加载了3个引导页,同时配置界面的 “跳过” “进入主页” 结束引导页!
package com.example.qqazl001.smartbutlers.ui;
/*
* 项目名:SmartButler
* 包名: com.example.qqazl001.smartbutlers.ui
* 创建时间:2018-09-2022:43
* 作者:rui
* 描述:引导页
*/
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import com.example.qqazl001.smartbutlers.MainActivity;
import com.example.qqazl001.smartbutlers.R;
import com.example.qqazl001.smartbutlers.utility.L;
import java.util.ArrayList;
import java.util.List;
public class GuideActivity extends AppCompatActivity{
private ViewPager mVPager;
private View view1,view2,view3;
private Button bt_main;
private ImageView iv_back;
private ImageView circle1,circle2,circle3;
private List<View> mList;
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setContentView(R.layout.activity_guide);
initView();
}
//初始化数据
public void initView(){
//实例化引导页的控件
mVPager = findViewById(R.id.mVPage);
circle1 = findViewById(R.id.circle1);
circle2 = findViewById(R.id.circle2);
circle3 = findViewById(R.id.circle3);
//实例化按钮
bt_main = findViewById(R.id.bt_main);
iv_back = findViewById(R.id.iv_back);
mList = new ArrayList<View>();
//布局转View
view1 = View.inflate(this,R.layout.viewpager_one,null);
view2 = View.inflate(this,R.layout.viewpager_two,null);
view3 = View.inflate(this,R.layout.viewpager_three,null);
//View 加入数组
mList.add(view1);
mList.add(view2);
mList.add(view3);
//ViewPager加载Adapter
mVPager.setAdapter(new GuideAdapter());
//设置默认选中状态
setcircleImg(true,false,false);
//设置滑动监听
mVPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//pager 切换
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
switch(position){
case 0:
iv_back.setVisibility(View.VISIBLE);
setcircleImg(true,false,false);
break;
case 1:
iv_back.setVisibility(View.VISIBLE);
setcircleImg(false,true,false);
break;
case 2:
iv_back.setVisibility(View.GONE);
setcircleImg(false,false,true);
break;
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
//内部类,创建Adapter
class GuideAdapter extends PagerAdapter{
//返回个数
@Override
public int getCount() {
return mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
//取出View
@Override
public Object instantiateItem(ViewGroup container, int position) {
((ViewPager)container).addView(mList.get(position));
return mList.get(position);
}
//销毁View
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager)container).removeView(mList.get(position));
//super.destroyItem(container, position, object);
}
}
//设置选中圆圈默认图片的方法
public void setcircleImg(boolean iscircle1,boolean iscricle2,boolean iscricle3){
if(iscircle1){
circle1.setBackgroundResource(R.drawable.on);
}else{
circle1.setBackgroundResource(R.drawable.off);
}
if(iscricle2){
circle2.setBackgroundResource(R.drawable.on);
}else{
circle2.setBackgroundResource(R.drawable.off);
}
if(iscricle3){
circle3.setBackgroundResource(R.drawable.on);
}else{
circle3.setBackgroundResource(R.drawable.off);
}
}
//监听按钮!!
public void onClick(View view){
switch(view.getId()){
case R.id.bt_main:
case R.id.iv_back:
finish();
startActivity(new Intent(this,MainActivity.class));
break;
}
}
//引导页禁止跳过
@Override
public void onBackPressed() {
// super.onBackPressed();
}
}