智能管家App kotlin版(2)——工具类封装与首页引导页开发

前言:项目最讲究的前期架构搭建,我们把标准的Log和SharedPreferences进行封装,同时开发我们的首页和引导页做一些技巧性的处理,项目开发效率将大大的提高,同时我们继承腾讯的bugly为我们的Carsh做一些约束性的策略!

此篇文章紧做关于该项目的工具类封装与首页引导页开发,后续功能实现请关注后续文章!!!

此篇文章完成后效果展示:
在这里插入图片描述

一.工具类的封装—Log封装

在utils包下,创建L类,代码如下:

package com.zrc.smartbutler.utils

import android.util.Log

/**
 *项目名:  SmartButler
 *包名:    com.zrc.smartbutler.utils
 *文件名:  L
 *创建者:  张如成
 *创建时间: 2020/5/6 21:21
 *描述:    Log封装类
 */
class L {
    
    
    //开关
    val DEBUG = true
    //TAG
    val TAG = "Smartbutler"

    //五个等级 DIWE
    fun d(text: String?) {
    
    
        if (DEBUG) {
    
    
            Log.d(TAG, text)
        }
    }
    fun i(text: String?) {
    
    
        if (DEBUG) {
    
    
            Log.i(TAG, text)
        }
    }

    fun w(text: String?) {
    
    
        if (DEBUG) {
    
    
            Log.w(TAG, text)
        }
    }

    fun e(text: String?) {
    
    
        if (DEBUG) {
    
    
            Log.e(TAG, text)
        }
    }
}

这地方没什么好说的,就是对系统自带的Log进行封装,使我们更方便使用!!!
至此,Log封装完成!!!

二.工具类的封装—SharedPreferences封装

在utils包下创建一个类,名为ShareUtils,代码如下:

package com.zrc.smartbutler.utils

import android.content.Context
import android.content.SharedPreferences


/**
 *项目名:  SmartButler
 *包名:    com.zrc.smartbutler.utils
 *文件名:  ShareUtils
 *创建者:  张如成
 *创建时间: 2020/5/6 21:39
 *描述:    SharedPreferences封装
 */
class ShareUtils {
    
    

    val NAME:String = "config"

    //存储String类型参数
    // 键 值
    fun putString(mContext:Context,key:String,value:String){
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME,Context.MODE_PRIVATE)
        sp.edit().putString(key,value).commit()
    }

    //读取String类型参数
    // 键 默认值
    fun getString(mContext:Context,key:String,defvalue:String):String{
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE)
        return sp.getString(key, defvalue)!!
    }

    //存储Int类型参数
    // 键 值
    fun putInt(mContext:Context,key:String,value:Int){
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME,Context.MODE_PRIVATE)
        sp.edit().putInt(key,value).commit()
    }

    //读取Int类型参数
    // 键 默认值
    fun getInt(mContext:Context,key:String,defvalue:Int):Int{
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE)
        return sp.getInt(key, defvalue)!!
    }

    //存储Boolean类型参数
    // 键 值
    fun putBoolean(mContext:Context,key:String,value:Boolean){
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME,Context.MODE_PRIVATE)
        sp.edit().putBoolean(key,value).commit()
    }

    //读取Boolean类型参数
    // 键 默认值
    fun getBoolean(mContext:Context,key:String,defvalue:Boolean):Boolean{
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE)
        return sp.getBoolean(key, defvalue)!!
    }

    //删除  单个
    fun deleShare(mContext:Context,key:String){
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE)
        sp.edit().remove(key).commit()
    }

    //删除  全部
    fun deleAll(mContext:Context){
    
    
        val sp:SharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE)
        sp.edit().clear().commit()
    }
}

这个封装类,我要做简要说明。

首先,在封装时,定义存储方式 get/put
其次,明确数据类型Int/String/Boolean
最后,定义删除功能 单个/全部

至此,SharedPreferences封装完成!!!

三.首页逻辑—首页跳转逻辑开发

1.创建闪屏页和引导页,名为SplashActivity和GuideActivity。
2.在清单文件中,对闪屏页进行设置,让他第一个启动

<!-- 闪屏 -->
        <activity
            android:name=".ui.SplashActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

就相当于让他和MainActivity换位置,此时MainActivity在清单文件中为:

 <!-- 主页 -->
        <activity android:name=".MainActivity" />

3.对闪屏页 xml界面进行设置

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wechat_bg"
    tools:context=".ui.SplashActivity">

    <TextView
        android:id="@+id/tv_splash"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="50sp"
        android:text="@string/app_name"
        android:layout_marginBottom="30dp"
        android:layout_centerInParent="true"
        android:textColor="@color/base_color"/>

    <TextView
        android:layout_marginBottom="15dp"
        android:layout_alignParentBottom="true"
        android:gravity="center"
        android:text="智能管家制作人:张如成"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>

代码很简单,在此就不赘述!!!
4.对闪屏页进行逻辑开发
在SplashActivity里面进行操作,代码如下:

package com.zrc.smartbutler.ui

import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import androidx.appcompat.app.AppCompatActivity
import com.zrc.smartbutler.MainActivity
import com.zrc.smartbutler.R
import com.zrc.smartbutler.utils.ShareUtils
import com.zrc.smartbutler.utils.StaticClass
import com.zrc.smartbutler.utils.UtilTools
import kotlinx.android.synthetic.main.activity_splash.*


/**
 *项目名:  SmartButler
 *包名:    com.zrc.smartbutler.ui
 *文件名:  SplashActivity
 *创建者:  张如成
 *创建时间: 2020/5/6 22:05
 *描述:    闪屏页
 */
class SplashActivity : AppCompatActivity() {
    
    

    /**
     *1.延时2000ms
     *2.判断程序是否第一次运行
     *3.自定义字体
     *4.Activity全屏主题
     */

    private var handler: Handler? = object : Handler() {
    
    
        override fun handleMessage(msg: Message) {
    
    
            super.handleMessage(msg)
            when(msg.what){
    
    
                StaticClass().HANDLER_SPLASH -> {
    
    
                    //判断程序是否是第一次运行
                    if(isFirst()){
    
    
                        startActivity(Intent(this@SplashActivity, GuideActivity::class.java))
                    }else{
    
    
                        startActivity(Intent(this@SplashActivity, MainActivity::class.java))
                    }
                    finish()
                }
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        //初始化View
        initView()
    }

    //初始化View
    private fun initView() {
    
    
        //延时2秒
        handler?.sendEmptyMessageDelayed(StaticClass().HANDLER_SPLASH,2000)
        //设置字体
        UtilTools().setFont(this,tv_splash)
    }

    //判断程序是否是第一次运行
    private fun isFirst():Boolean{
    
    
        val isFirst = ShareUtils().getBoolean(this,StaticClass().SHARE_IS_FIRST,true)
        if(isFirst){
    
    
            ShareUtils().putBoolean(this,StaticClass().SHARE_IS_FIRST,false)
            //是第一次运行
            return true
        }else{
    
    
            //不是第一次运行
            return false
        }
    }

    //禁止返回
    override fun onBackPressed() {
    
    
        // super.onBackPressed()
    }
}

这段代码主要实现四个功能:
第一个,设置延时2000ms,是通过handler来进行耗时操作

第二个,判断程序是否运行,是使用刚刚封装的ShareUtils进行判断,2秒延时结束后,进行判断,当第一运行时,为true值,进入引导页面,并修改值为false,以后进入,直接进入主页

第三个是自定义字体,在main包下,创建assets/fonts包,并把从网络上下载的字体FONT.TTF放入,在UtilTools里面进行封装,代码如下:

package com.zrc.smartbutler.utils

import android.content.Context
import android.graphics.Typeface
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_splash.*

/**
 *项目名:  SmartButler
 *包名:    com.zrc.smartbutler.utils
 *文件名:  UtilTools
 *创建者:  张如成
 *创建时间: 2020/5/6 8:07
 *描述:    工具统一类
 */
class UtilTools {
    
    
    //设置字体
    fun setFont(mContext:Context,textView: TextView){
    
    
        val fontType = Typeface.createFromAsset(mContext.assets,"fonts/FONT.TTF")
        textView.setTypeface(fontType)
    }
}

并使用:

UtilTools().setFont(this,tv_splash)

第四个是Activity全屏主题,在values/styles.xml文件中,创建样式,代码如下:

  <!--全屏主题-->
    <style name="NoActivityFullscreen" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>

然后前往清单文件,对闪屏页进行设置:

android:theme="@style/NoActivityFullscreen"

闪屏页大致就这四部分事情,当然这只是简单描述,想要具体了解,欢迎查看源码,本人注释写的已经很详细了!!!

至此,引导页逻辑开发完成!!!

四.引导页逻辑—引导页逻辑开发

1.首先先编写引导页界面,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".ui.GuideActivity">
   

   <androidx.viewpager.widget.ViewPager
       android:id="@+id/mViewPager"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

   <LinearLayout
       android:id="@+id/mLinearLayout"
       android:layout_alignParentBottom="true"
       android:layout_marginBottom="15dp"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:orientation="horizontal">


      <ImageView
          android:id="@+id/point1"
          android:layout_width="10dp"
          android:layout_height="10dp"
          />

      <ImageView
          android:id="@+id/point2"
          android:layout_width="10dp"
          android:layout_height="10dp"
          android:layout_marginLeft="10dp"
          android:layout_marginRight="10dp"
         />

      <ImageView
          android:id="@+id/point3"
          android:layout_width="10dp"
          android:layout_height="10dp"
          />


   </LinearLayout>

   <Button
       android:id="@+id/btn_start"
       android:text="进入主页"
       android:background="@drawable/button_bg"
       android:layout_above="@+id/mLinearLayout"
       android:layout_marginBottom="200dp"
       android:textColor="@android:color/white"
       android:layout_centerInParent="true"
       android:layout_width="150dp"
       android:visibility="gone"
       android:layout_height="wrap_content"/>

   <ImageView
       android:id="@+id/iv_back"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentRight="true"
       android:layout_marginRight="25dp"
       android:layout_marginTop="25dp"
       android:src="@drawable/black"/>
</RelativeLayout>

这里面呢,主要是ViewPager滑动页面 + 三个小圆点(即里面的ImageView) + 跳过 + 进入主页按钮,将在Kotlin逻辑代码中展示!!!

2.GuideActivty逻辑代码如下所示:

package com.zrc.smartbutler.ui

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.zrc.smartbutler.MainActivity
import com.zrc.smartbutler.R
import com.zrc.smartbutler.utils.L
import com.zrc.smartbutler.utils.UtilTools
import kotlinx.android.synthetic.main.activity_guide.*
import kotlinx.android.synthetic.main.activity_main.mViewPager

/**
 *项目名:  SmartButler
 *包名:    com.zrc.smartbutler.ui
 *文件名:  GuideActivity
 *创建者:  张如成
 *创建时间: 2020/5/6 22:37
 *描述:    引导页
 */
class GuideActivity : AppCompatActivity() {
    
    

    //容器
    private  val mList = mutableListOf<View>()

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_guide)


        //初始化View
        initView()
    }

    //初始化View
    private fun initView() {
    
    

        //设置默认图片
        setPointImg(true,false,false)

        //第三页的按钮点击事件
        btn_start.setOnClickListener {
    
    
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        }

        //跳过按钮
        iv_back.setOnClickListener {
    
    
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        }

        val view1 = View.inflate(this, R.layout.pager_item_one, null)
        val view2 = View.inflate(this, R.layout.pager_item_two, null)
        val view3 = View.inflate(this, R.layout.pager_item_three, null)
        UtilTools().setFont(this,view1.findViewById(R.id.tv_pager_1))
        UtilTools().setFont(this,view2.findViewById(R.id.tv_pager_2))
        UtilTools().setFont(this,view3.findViewById(R.id.tv_pager_3))
        mList.add(view1)
        mList.add(view2)
        mList.add(view3)
        //设置适配器
        mViewPager.adapter = GuideAdapter()


        //监听ViewPager的滑动
        mViewPager.addOnPageChangeListener(object :ViewPager.OnPageChangeListener{
    
    
            override fun onPageScrollStateChanged(state: Int) {
    
    

            }

            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    
    

            }

            //切换的回调
            override fun onPageSelected(position: Int) {
    
    
                L().i("position"+position)
                when(position){
    
    
                    0 ->{
    
    
                        setPointImg(true,false,false)
                        btn_start.visibility = View.GONE
                        iv_back.visibility = View.VISIBLE
                    }
                    1 ->{
    
    
                        setPointImg(false,true,false)
                        btn_start.visibility = View.GONE
                        iv_back.visibility = View.VISIBLE
                    }
                    2 ->{
    
    
                        setPointImg(false,false,true)
                        btn_start.visibility = View.VISIBLE
                        iv_back.visibility = View.GONE
                    }
                }
            }

        })
    }


    //设置小圆点的选中效果
    fun setPointImg(isCheck1:Boolean,isCheck2:Boolean,isCheck3:Boolean){
    
    
        if(isCheck1){
    
    
            point1.setBackgroundResource(R.drawable.point_on)
        }else{
    
    
            point1.setBackgroundResource(R.drawable.point_off)
        }

        if(isCheck2){
    
    
            point2.setBackgroundResource(R.drawable.point_on)
        }else{
    
    
            point2.setBackgroundResource(R.drawable.point_off)
        }

        if(isCheck3){
    
    
            point3.setBackgroundResource(R.drawable.point_on)
        }else{
    
    
            point3.setBackgroundResource(R.drawable.point_off)
        }

    }

    //适配器
    inner class GuideAdapter(): PagerAdapter(){
    
    

        override fun isViewFromObject(view: View, `object`: Any): Boolean {
    
    
            return view == `object`
        }

        override fun getCount(): Int {
    
    
            return mList.size
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
    
    
            (container as ViewPager).addView(mList.get(position))
            return mList.get(position)
        }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
    
    
            (container as ViewPager).removeView(mList.get(position))
            // super.destroyItem(container, position, `object`)
        }

    }
}

首先创建ViewPager的三个界面,在layout包下,创建三个xml文件

pager_item_one.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/guide_smart"/>

    <TextView
        android:id="@+id/tv_pager_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="智能"
        android:layout_marginTop="10dp"
        android:textSize="50sp"/>
</LinearLayout>

pager_item_two.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/guide_concise"/>

    <TextView
        android:layout_marginTop="10dp"
        android:id="@+id/tv_pager_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="简洁"
        android:textSize="50sp"/>
</LinearLayout>

pager_item_three.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/guide_strong"/>

    <TextView
        android:layout_marginTop="10dp"
        android:id="@+id/tv_pager_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="强大"
        android:textSize="50sp"/>


</LinearLayout>

把上面3个布局传入ViewPager后,进行监听滑动,设置跳过按钮和按钮的出现和消失时机以及小圆点的切换

 //切换的回调
            override fun onPageSelected(position: Int) {
    
    
                L().i("position"+position)
                when(position){
    
    
                    0 ->{
    
    
                        setPointImg(true,false,false)
                        btn_start.visibility = View.GONE
                        iv_back.visibility = View.VISIBLE
                    }
                    1 ->{
    
    
                        setPointImg(false,true,false)
                        btn_start.visibility = View.GONE
                        iv_back.visibility = View.VISIBLE
                    }
                    2 ->{
    
    
                        setPointImg(false,false,true)
                        btn_start.visibility = View.VISIBLE
                        iv_back.visibility = View.GONE
                    }
                }
            }

按钮和跳过点击进入主页的实现:

 //第三页的按钮点击事件
        btn_start.setOnClickListener {
    
    
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        }

        //跳过按钮
        iv_back.setOnClickListener {
    
    
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        }

还有全屏知识点要添加,在讲解闪屏页的时候,已经说明,故不再赘述,直接引用即可!!!

至此,引导页逻辑开发完成!!!

五.异常反馈收集—腾讯Bugly

作为开发人员,很容易就能碰到Crash ,但是作为用户,我相信也有 很大部分人碰到过Crash ,这些原因,也正是Android的平台差异化和适配所导致的,而且,你要是你安装一个软件就Crash ,我想你会 立马把他卸载掉。同时心理嘲笑了一下开发人员,这就比较尴尬了!

Bugly官网

Bugly Android SDK 使用指南

放置Bugly官网以及使用指南,方便大家查阅!!!

工具类封装与首页引导页开发完成,下篇文章将针对用户注册/登录/忘记重置密码进行开发,欢迎关注后续更新!!!

猜你喜欢

转载自blog.csdn.net/weixin_43912367/article/details/105966780