各大应用市场应用首页实现的功能样式都差不多,无非就是倒计时和广告。虽然以前一直都是Java的语言为基础开发的手机应用程序,谷歌推出的科特林语言也在应用开发的语言选择中使用起来,以Java的语言为基础的安卓与科特林有语言上的一些差异,不过稍微细心的对比起来学习并开发,并非难事下图是UI给出的界面,需要用科特林语言来进行实现:
在看界面UI之面,第一步:想到是布局,布局是传递给活动重写方法onCreate方法内部调用的setContentView的参数值。第二步:我们需要实现又上角的倒计时【倒计时需要用到CountDownTimer(long millisInFuture,long countDownInterval),millisInFuture表示:从调用start()到onFinish()的时间段,countDownInterval表示:onTick(millisUntilFinished:Long)收到倒计时回调后的时间间隔,注意:需要在Activity onDestroy( )回调方法中执行CountDownTimer(倒计时)的回调方法取消()进行倒计时的销毁。第三步:使用控件ViewPager实现广告页,并实现ViewPager滑动监听事件OnPageChangeListener,滑动到不同位置的广告页顺便带动底部不同位置的长条状态的切换。】
倒计时执行过程:在onStart() - >的onClick() - > onFinish() - >取消(),在onStart()和取消()为手动调用,的onClick()和onFinish()为倒计时在指定的时间段和时间间隔执行过程中,结束的回调方法。
未来的毫秒数将形成对{@ link #start()}的调用,直到倒计时结束,并且调用{@link #onFinish()}。(大概念意思:从start()调用到直到倒计时完成并调用onFinish()的毫秒数)
The interval along the way to receive {@link #onTick(long)} callbacks.(大概意思:onTick()被回调的时间间隔。)
调用onStart() - > onFinish()执行过程的日志信息(我设置的时间段是5000毫秒,时间间隔1000毫秒):
倒计时创建代码片段,onTick回调方法中获取到的毫秒值/ 1000拿到整数值为秒,onFinish回调方法表示倒计时时间端结束,可以执行活动跳转(比如跳转到首页)或者其他操作:
mCount = object : CountDownTimer(5000,1000){
override fun onTick(millisUntilFinished: Long) {
skipBtn.text = "${millisUntilFinished / 1000}秒后跳过"
Timber.i(javaClass.name+"onTick()当前毫秒值:"+millisUntilFinished)
}
override fun onFinish() {
skipBtn.text = "0秒后跳过"
Timber.i(javaClass.name+"onFinish()")
startActivity()
finish()
}
}
mCount.start()
执行倒计时销毁:
override fun onDestroy() {
mCount.cancel()
super.onDestroy()
}
广告页:为ViewPager添加滑动监听事件和创建PagerAdapter适配器:
class SplashActivity : BaseActivity(),ViewPager.OnPageChangeListener{
private lateinit var mAdapter : SplashAdapter
private lateinit var mCount : CountDownTimer
.........................
//todo 测试数据
val list = mutableListOf("","","")
mAdapter = SplashAdapter(mContext,list)
indicatorView.initView(list.size)
vp.adapter = mAdapter
vp.addOnPageChangeListener(this)
..............................
}
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float
positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
vp.currentItem = position
indicatorView.updatePosition(position)
}
import android.content.Context
import android.support.v4.view.PagerAdapter
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.midai.goodbabymall.R
import com.midai.goodbabymall.util.GlideUtils
import timber.log.Timber
class SplashAdapter (val context: Context, val mList : MutableList) : PagerAdapter() {
/**
* 该回调方法执行图片的与预加载,一般预加载2张图片
* getCount()=0:不执行
* getCount()=1:执行1次
* getCount>=2:执行2次
*/
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val image = ImageView(context)
image.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)
GlideUtils.setImageUri(context,image, R.mipmap.product_def_big)
container.addView(image)
Timber.i(javaClass.name+"instantiateItem");
return image
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
override fun getCount(): Int {
return mList.size;
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
}
底部滚动条切换:
import android.content.Context
import android.support.annotation.DrawableRes
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import com.midai.goodbabymall.R
/**
* 广告页横条
*/
class IndicatorView : LinearLayout{
constructor(context: Context) : this(context,null)
constructor(context: Context,attributeSet: AttributeSet?) : this(context,attributeSet,0)
constructor(context: Context,attributeSet: AttributeSet?, defStyleAttr : Int) : super(context,attributeSet,defStyleAttr)
@DrawableRes var checkedResId : Int = R.drawable.indicator_rectangle_check_orange
@DrawableRes var unCheckdResId : Int = R.drawable.indicator_rectangle_check_black
private var adIndicatorIVs : MutableList? = null
fun initView(size : Int) {
removeAllViews()
if (size <= 1){
return
}
adIndicatorIVs = mutableListOf()
for (i in 0 until size){
// 有多少张图片就new多少次
val layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
// 设置每个小圆点距离左边的中间Lin
layoutParams.setMargins(14, 0, 0, 0)
val imageView = ImageView(context)
// 设置小圆点的宽高
imageView.layoutParams = ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
adIndicatorIVs!!.add(imageView)
if (i == 0) {
// 默认第一张图片
adIndicatorIVs!![i].setBackgroundResource(checkedResId)
} else {
// 其他图片都未选中状态
adIndicatorIVs!![i].setBackgroundResource(unCheckdResId)
}
addView(adIndicatorIVs!![i], layoutParams)
}
}
/**
* 更新位置
*/
fun updatePosition(position: Int){
if (null != adIndicatorIVs){
for (it in 0 until adIndicatorIVs!!.size){
if (position == it){
adIndicatorIVs!![it].setBackgroundResource(checkedResId)
} else {
adIndicatorIVs!![it].setBackgroundResource(unCheckdResId)
}
}
}
}
indicator_rectangle_check_orange.xml
indicator_rectangle_check_black.xml