Kotlin 實現App首頁頂部倒計時、左右滑動廣告和底部切換廣告頁長條

各大應用市場應用首頁實現的功能樣式都差不多,無非就是倒計時和廣告。雖然以前一直都是Java的語言爲基礎開發的手機應用程序,谷歌推出的科特林語言也在應用開發的語言選擇中使用起來,以Java的語言爲基礎的安卓與科特林有語言上的一些差異,不過稍微細心的對比起來學習並開發,並非難事下圖是UI給出的界面,需要用科特林語言來進行實現:

在看界面UI之面,第一步:想到是佈局,佈局是傳遞給活動重寫方法onCreate方法內部調用的setContentView的參數值。第二步:我們需要實現又上角的倒計時【倒計時需要用到CountDownTimer(long millisInFuture,long countDownInterval),millisInFuture表示:從調用start()到onFinish()的時間段,countDownInterval表示:onTick(millisUntilFinished:Long)收到倒計時回調後的時間間隔,注意:需要在Activity onDestroy( )回調方法中執行CountDownTimer(倒計時)的回調方法取消()進行倒計時的銷燬。第三步:使用控件ViewPager實現廣告頁,並實現ViewPager滑動監聽事件OnPageChangeListener,滑動到不同位置的廣告頁順便帶動底部不同位置的長條狀態的切換。】

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white">

        </android.support.v4.view.ViewPager>

        <com.midai.goodbabymall.widget.IndicatorView
            android:id="@+id/indicatorView"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/comm_30dp"
            android:layout_marginBottom="@dimen/comm_20dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true">

        </com.midai.goodbabymall.widget.IndicatorView>

        <TextView
            android:id="@+id/skipBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:minWidth="@dimen/comm_90dp"
            android:minHeight="@dimen/comm_30dp"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginTop="@dimen/comm_20dp"
            android:layout_marginRight="@dimen/comm_20dp"
            android:layout_marginEnd="@dimen/comm_20dp"
            android:background="@drawable/bg_rectangle_corner_2dp_solid_transpant_gray"
            android:gravity="center"
            android:textSize="@dimen/text_size_14sp"
            android:textColor="@color/font_gray2"
            android:text="5秒後跳過"
             />

    </RelativeLayout>

</android.support.constraint.ConstraintLayout>

倒計時執行過程:在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<MainActivity>()
                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<String>) : 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<ImageView>? = 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

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:height="@dimen/comm_2dp"
        android:width="@dimen/comm_30dp"/>

    <solid android:color="@color/main_bottom_navigator_blood_orange"/>

</shape>

indicator_rectangle_check_black.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:height="@dimen/comm_2dp"
        android:width="@dimen/comm_30dp"/>

    <solid android:color="@color/bg_black"/>

</shape>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章