Androidブートページ実装
102287 ワード
背景
もし私たちのアプリにいくつかのリソースをロードする必要がある場合、あるいは移行したインタフェースがメインインタフェースにそんなに突然表示されないようにする必要がある場合、私たちはブートページという概念を使用する必要があります.ブートページの間にいくつかのリソースをロードすることで、ユーザーに仕事をさせないなど、ユーザーに悪い体験を与えることになります.Androidのガイドページの実現には主に4つの方法があります. Splashインターフェース ViewPager ViewFlipper ScrollView
次は順番に彼を実現します.
Splashインタフェース
この方法は最も簡単な方法であり,主界面に遅延したStartを行うことであり,この実現はHandlerを用いて達成できる.
ViewFlipper
もし私たちがまたページをめくる効果がほしいならば、このようにアプリの製品紹介に使うことができて、このようにView Flipperと結びつけて実現しなければなりません.これはAndroidが持っているマルチインタフェースの展示Viewです.XMLで直接定義すればよい.
Activityでも簡単で、ジェスチャーを傍受してどの方向にスライドしているのかを判断し、関連する方法を呼び出すだけで実現でき、ViewFlipperが変化したときに対応するインジケータを変更すればよい.
今ここで私が書いたのはオフセットがあれば変化して、本当の実現の中で私たちは彼に一定のしきい値を与えることができて、そのしきい値に達してこそページの変化を行うことができます.
ViewPager
ViewFlipperが実装したガイドページのページめくりを実現するにはいくつかの突起があり、直接飛び越えたので、グラデーションの効果は一つもなく、グラデーションの効果を実現するにはViewPagerを使用しなければならない.現在のページに基づいて異なるFragmentを表示し、ページをめくって指示標の状態を変えるだけでいいです.activity_view_pager.xml
ここでは特に簡単な色でどのFragmentにあるかを区別します.fragment_content.xml
そしてFragmentを実現し,その中で伝達されたパラメータによってどの色がロードされているかを判断し,最後の1枚であればボタンを表示する状態にする.ContentFragment.kt
すぐにViewPagerのAdapterを実現しますが、実は簡単です.FragmentPagerAdapterに継承し、関連するデータリストを渡せばいいので、対応する戻りはリストのいずれかでいいです.ViewPagerAdapter.kt
最後に最も重要なActivityは、対応する必要なFragmentをすべて実現し、それによって関連するAdapterを実現し、ViewPagerにロードすることです.最後に、関連するナビゲーションバーを初期化し、ViewPagerの変化を監視する必要があります.ViewPagerActivity.kt
ScrollView
もし私たちがドラッグ効果のガイドページを実現するにはどうすればいいのでしょうか.ここではScrollViewを使用します.単純にドラッグを使用するだけであれば、ScrollViewコントロールを直接使用することができます.アニメーション効果を追加するには、カスタムコントロールを使用してこの操作を完了する必要があります.まず、私たちは上下にスライドしているので、onScrollChangedメソッドでは垂直方向のオフセットに関心を持ってインタフェースに渡し、Activityに渡して処理する必要があります.MyScrollView.kt
次に、このコントロールを直接使用して、必要な背景activityを定義します.scroll_view.xml
その後、このコントロールをそのまま使用して、上下スライドのずれ量で上に移動するか下に移動するかを判断し、判断時に現在の状態に対する判断を加えて、繰り返し設定状態を防止しました.ScrollViewActivity.kt
プロジェクトGithubアドレス:転送ゲート
もし私たちのアプリにいくつかのリソースをロードする必要がある場合、あるいは移行したインタフェースがメインインタフェースにそんなに突然表示されないようにする必要がある場合、私たちはブートページという概念を使用する必要があります.ブートページの間にいくつかのリソースをロードすることで、ユーザーに仕事をさせないなど、ユーザーに悪い体験を与えることになります.Androidのガイドページの実現には主に4つの方法があります.
次は順番に彼を実現します.
Splashインタフェース
この方法は最も簡単な方法であり,主界面に遅延したStartを行うことであり,この実現はHandlerを用いて達成できる.
package com.xjh.bootpagedemo.splash
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import com.xjh.bootpagedemo.MainActivity
import com.xjh.bootpagedemo.R
class SplashActivity : AppCompatActivity() {
companion object {
private val DELAY_TIME = 3000L
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
Handler().postDelayed({
startActivity(Intent(this, MainActivity::class.java))
finish()
}, DELAY_TIME)
}
}
ViewFlipper
もし私たちがまたページをめくる効果がほしいならば、このようにアプリの製品紹介に使うことができて、このようにView Flipperと結びつけて実現しなければなりません.これはAndroidが持っているマルチインタフェースの展示Viewです.XMLで直接定義すればよい.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="@+id/viewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@color/colorAccent" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@color/colorPrimary" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp"
android:gravity="center"
android:text=" "
android:textSize="22sp" />
RelativeLayout>
ViewFlipper>
<LinearLayout
android:id="@+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="30dp"
android:orientation="horizontal" />
FrameLayout>
Activityでも簡単で、ジェスチャーを傍受してどの方向にスライドしているのかを判断し、関連する方法を呼び出すだけで実現でき、ViewFlipperが変化したときに対応するインジケータを変更すればよい.
package com.xjh.bootpagedemo.viewflipper
import android.app.ActionBar
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.TypedValue
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import androidx.core.view.get
import com.xjh.bootpagedemo.MainActivity
import com.xjh.bootpagedemo.R
import kotlinx.android.synthetic.main.activity_view_flipper.*
import kotlinx.android.synthetic.main.activity_view_pager.*
import kotlinx.android.synthetic.main.activity_view_pager.indicator
import kotlinx.android.synthetic.main.fragment_content.view.*
class ViewFlipperActivity : AppCompatActivity(), GestureDetector.OnGestureListener {
private lateinit var gestureDetector: GestureDetector
private var index = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_flipper)
btn.setOnClickListener {
startActivity(Intent(this, MainActivity::class.java))
}
initIndicator()
}
private fun initIndicator() {
val width =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
20f,
resources.displayMetrics
).toInt()
val lp = ActionBar.LayoutParams(width, width)
lp.rightMargin = 2 * width
lp.leftMargin = 2 * width
for (i in 0 until viewFlipper.childCount) {
val view = View(this)
view.id = i
view.setBackgroundResource(if (i == 0) R.drawable.dot_focus else R.drawable.dot_normal)
view.layoutParams = lp
indicator.addView(view, i)
}
gestureDetector = GestureDetector(this)
}
override fun onShowPress(e: MotionEvent?) {
}
override fun onSingleTapUp(e: MotionEvent?): Boolean {
return false
}
override fun onDown(e: MotionEvent?): Boolean {
return false
}
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean {
e1?.let { a ->
e2?.let { b ->
if (a.x > b.x) {
viewFlipper.showNext()
index = if (index < 2) index + 1 else 0
changeIndicator()
return true
} else if (a.x < b.x) {
viewFlipper.showNext()
index = if (index > 0) index - 1 else 2
changeIndicator()
return true
}
}
}
return false
}
private fun changeIndicator() {
for (i in 0 until viewFlipper.childCount) {
indicator[i].setBackgroundResource(
if (i == index) R.drawable.dot_focus else R.drawable.dot_normal
)
}
}
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
distanceX: Float,
distanceY: Float
): Boolean {
return false
}
override fun onLongPress(e: MotionEvent?) {
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
return gestureDetector.onTouchEvent(event)
}
}
今ここで私が書いたのはオフセットがあれば変化して、本当の実現の中で私たちは彼に一定のしきい値を与えることができて、そのしきい値に達してこそページの変化を行うことができます.
ViewPager
ViewFlipperが実装したガイドページのページめくりを実現するにはいくつかの突起があり、直接飛び越えたので、グラデーションの効果は一つもなく、グラデーションの効果を実現するにはViewPagerを使用しなければならない.現在のページに基づいて異なるFragmentを表示し、ページをめくって指示標の状態を変えるだけでいいです.activity_view_pager.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="30dp"
android:orientation="horizontal" />
FrameLayout>
ここでは特に簡単な色でどのFragmentにあるかを区別します.fragment_content.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contentRLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp"
android:gravity="center"
android:text=" "
android:textSize="22sp" />
RelativeLayout>
そしてFragmentを実現し,その中で伝達されたパラメータによってどの色がロードされているかを判断し,最後の1枚であればボタンを表示する状態にする.ContentFragment.kt
package com.xjh.bootpagedemo.viewpager
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.xjh.bootpagedemo.MainActivity
import com.xjh.bootpagedemo.R
import kotlinx.android.synthetic.main.fragment_content.view.*
class ContentFragment : Fragment() {
private val bgRes = arrayOf(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_content, null)
arguments?.getInt("index")?.let {
view.contentRLayout.setBackgroundResource(bgRes[it])
view.btn.setOnClickListener {
startActivity(Intent(activity, MainActivity::class.java))
}
view.btn.visibility = if (it == 2) View.VISIBLE else View.GONE
}
return view
}
}
すぐにViewPagerのAdapterを実現しますが、実は簡単です.FragmentPagerAdapterに継承し、関連するデータリストを渡せばいいので、対応する戻りはリストのいずれかでいいです.ViewPagerAdapter.kt
package com.xjh.bootpagedemo.viewpager
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
class ViewPagerAdapter(fm: FragmentManager, private var fragments: List<Fragment>) :
FragmentPagerAdapter(fm) {
override fun getCount(): Int {
return fragments.size
}
override fun getItem(position: Int): Fragment {
return fragments[position]
}
}
最後に最も重要なActivityは、対応する必要なFragmentをすべて実現し、それによって関連するAdapterを実現し、ViewPagerにロードすることです.最後に、関連するナビゲーションバーを初期化し、ViewPagerの変化を監視する必要があります.ViewPagerActivity.kt
package com.xjh.bootpagedemo.viewpager
import android.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import androidx.core.view.get
import androidx.core.view.marginLeft
import androidx.core.view.marginRight
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.xjh.bootpagedemo.R
import kotlinx.android.synthetic.main.activity_view_pager.*
class ViewPagerActivity : AppCompatActivity() {
private lateinit var adapter: PagerAdapter
private val fragments = ArrayList<Fragment>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_pager)
for (index in 0..2) {
val fragment = ContentFragment()
val bundle = Bundle()
bundle.putInt("index", index)
fragment.arguments = bundle
fragments.add(fragment)
}
adapter = ViewPagerAdapter(supportFragmentManager, fragments)
viewPager.adapter = adapter
initIndicator()
viewPager.setOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
for (i in 0 until fragments.size) {
indicator[i].setBackgroundResource(
if (i == position) R.drawable.dot_focus else R.drawable.dot_normal
)
}
}
override fun onPageSelected(position: Int) {
}
})
}
private fun initIndicator() {
val width =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
20f,
resources.displayMetrics
).toInt()
val lp = ActionBar.LayoutParams(width, width)
lp.rightMargin = 2 * width
lp.leftMargin = 2 * width
for (i in 0 until fragments.size) {
val view = View(this)
view.id = i
view.setBackgroundResource(if (i == 0) R.drawable.dot_focus else R.drawable.dot_normal)
view.layoutParams = lp
indicator.addView(view, i)
}
}
}
ScrollView
もし私たちがドラッグ効果のガイドページを実現するにはどうすればいいのでしょうか.ここではScrollViewを使用します.単純にドラッグを使用するだけであれば、ScrollViewコントロールを直接使用することができます.アニメーション効果を追加するには、カスタムコントロールを使用してこの操作を完了する必要があります.まず、私たちは上下にスライドしているので、onScrollChangedメソッドでは垂直方向のオフセットに関心を持ってインタフェースに渡し、Activityに渡して処理する必要があります.MyScrollView.kt
package com.xjh.bootpagedemo.scrollview
import android.content.Context
import android.util.AttributeSet
import android.widget.ScrollView
class MyScrollView(context: Context, attrs: AttributeSet?) : ScrollView(context, attrs) {
private lateinit var onScrollViewListener: OnScrollChangeListener
override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
super.onScrollChanged(l, t, oldl, oldt)
onScrollViewListener.onScrollChange(t, oldt)
}
interface OnScrollChangeListener {
fun onScrollChange(top: Int, oldTop: Int)
}
fun setOnScrollChangeListener(onScrollChangeListener: OnScrollChangeListener) {
this.onScrollViewListener = onScrollChangeListener
}
}
次に、このコントロールを直接使用して、必要な背景activityを定義します.scroll_view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.xjh.bootpagedemo.scrollview.MyScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text=" "
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="20dp"
android:src="@mipmap/ic_launcher" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<LinearLayout
android:id="@+id/animLLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="invisible">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="20dp"
android:src="@drawable/dot_yellow" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="20dp"
android:src="@drawable/dot_blue" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="20dp"
android:src="@drawable/dot_black" />
LinearLayout>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="50dp"
android:src="@drawable/dot_white" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginBottom="30dp"
android:gravity="center"
android:text=" "
android:textSize="22sp" />
LinearLayout>
com.xjh.bootpagedemo.scrollview.MyScrollView>
RelativeLayout>
その後、このコントロールをそのまま使用して、上下スライドのずれ量で上に移動するか下に移動するかを判断し、判断時に現在の状態に対する判断を加えて、繰り返し設定状態を防止しました.ScrollViewActivity.kt
package com.xjh.bootpagedemo.scrollview
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.animation.AnimationUtils
import com.xjh.bootpagedemo.MainActivity
import com.xjh.bootpagedemo.R
import kotlinx.android.synthetic.main.activity_scroll_view.*
import kotlinx.android.synthetic.main.activity_view_flipper.*
import kotlinx.android.synthetic.main.activity_view_flipper.btn
class ScrollViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scroll_view)
btn.setOnClickListener {
startActivity(Intent(this, MainActivity::class.java))
}
val context = this
scrollView.setOnScrollChangeListener(object : MyScrollView.OnScrollChangeListener {
override fun onScrollChange(top: Int, oldTop: Int) {
if (top > oldTop && animLLayout.visibility == View.INVISIBLE) {
val anim = AnimationUtils.loadAnimation(context, R.anim.show)
animLLayout.visibility = View.VISIBLE
animLLayout.startAnimation(anim)
} else if (top < oldTop && animLLayout.visibility == View.VISIBLE) {
val anim = AnimationUtils.loadAnimation(context, R.anim.close)
animLLayout.visibility = View.INVISIBLE
animLLayout.startAnimation(anim)
}
}
})
}
}
プロジェクトGithubアドレス:転送ゲート