1.先添加一下anko库
依赖:implementation "org.jetbrains.anko:anko:$anko_version"
版本:ext.anko_version='0.10.8'
2.新建Activity和Fragment的两个基类,方便以后使用
abstract class BaseActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(getLayoutId()) initData(); onListener(); } abstract fun getLayoutId(): Int;//继承此类必须先实现此方法 protected open fun initData(){ } protected open fun onListener() { }
//
abstract class BaseFragment:Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initData() } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return initView(); } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) onListener() } abstract fun initView():View? protected open fun initData(){ } protected open fun onListener(){ } }
3.底部导航
方案一:bottombar
依赖:implementation 'com.roughike:bottom-bar:2.3.1'
activity_main.xml改成LinearLayout布局,设置垂直布局
<FrameLayout android:id="@+id/contentContainer" android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="1"/> <com.roughike.bottombar.BottomBar android:id="@+id/bottomBar" android:layout_width="match_parent" android:layout_height="56dp" app:bb_tabXmlResource="@xml/bottombar_tabs"/>
新建xml Directory,添加bottombar_tabs.xml
<?xml version="1.0" encoding="utf-8"?> <tabs> <tab id="@+id/tab_homepage" icon="@drawable/homepage_icon" title="主页" /> <tab id="@+id/tab_favorites" icon="@drawable/favorites_icon" title="收藏" /> <tab id="@+id/tab_message" icon="@drawable/message_icon" title="消息" /> <tab id="@+id/tab_personal" icon="@drawable/personal_icon" title="我的" /> </tabs>
添加图标资源到drawable-xxhdpi目录中(不能直接添加到drawable中)
添加监听很简单
override fun initData() { bottomBar.setOnTabSelectListener{ //it即是tab的id // println(it) }
接下来准备点击切换的四个fragment,都继承自BaseFragment,例如
class FavoritesFragment:BaseFragment() { override fun initView(): View? { var textView:TextView=TextView(activity) //getActivity()返回与之关联的activity textView.text="收藏" return textView } }
再准备一个管理fragment的类FragmentManage
class FragmentManage { fun getFragment(tab_id:Int):BaseFragment?{ when(tab_id){ R.id.tab_homepage->return HomePageFragment() R.id.tab_favorites->return FavoritesFragment() R.id.tab_message->return MessageFragment() R.id.tab_personal->return Personal() } return null } }
优化后的代码,创建单例模式,采用懒加载定义变量
class FragmentManage private constructor(){ val homePageFragmeng by lazy{HomePageFragment()} val favoritesFragment by lazy{FavoritesFragment()} val messageFragment by lazy{MessageFragment()} val PersonalFragment by lazy{Personal()} companion object{ val fragmentManage by lazy{ FragmentManage() } } fun getFragment(tab_id:Int):BaseFragment?{ when(tab_id){ R.id.tab_homepage->return homePageFragmeng R.id.tab_favorites->return favoritesFragment R.id.tab_message->return messageFragment R.id.tab_personal->return PersonalFragment } return null } }
这里可能找不到id,重启一下就可以了。R资源路径app\build\generated\not_namespaced_r_class_sources\debug\r\com\vocus\justtest
在MainActivity中设置对bottomBar的监听,并动态添加fragment
override fun initData() { bottomBar.setOnTabSelectListener { //it即是tab的id // println(it) val transAction = supportFragmentManager.beginTransaction() //transAction.replace(R.id.contentContainer,FragmentManage().getFragment(it) as BaseFragment, it.toString()) transAction.replace(R.id.contentContainer,FragmentManage.fragmentManage.getFragment(it)!!,it.toString()) transAction.commit() } }
效果:
方案二:BottomNavigationView
null
4.主界面,设置HomePageFragment
设置状态栏背景透明
null
广告图片轮播(ViewPager)
设置homepagefragment布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.viewpager.widget.ViewPager android:id="@+id/vp_homePageAd" android:layout_width="match_parent" android:layout_height="300dp"> </androidx.viewpager.widget.ViewPager> <LinearLayout android:id="@+id/dot_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerHorizontal="true" android:layout_alignBottom="@+id/vp_homePageAd" android:layout_marginBottom="10dp"> </LinearLayout> </RelativeLayout>
新建HomePageAdAdapter类
class HomePageAdAdapter(): PagerAdapter(){ private val imageViewList=ArrayList<ImageView>() constructor(imageViewList:ArrayList<ImageView>):this(){ this.imageViewList.addAll(imageViewList) } override fun isViewFromObject(view: View, `object`: Any): Boolean { return view==`object` } override fun instantiateItem(container: ViewGroup, position: Int): Any { // var textView= TextView(container.context) // textView.text="test" // container.addView(textView) // return textView container.addView(imageViewList.get(position)) return imageViewList.get(position) } override fun getCount(): Int { return imageViewList.size } override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { container.removeView(`object` as View) } }
在HomePageFragment中添加代码
-
重写onListener方法(在onActivityCreated的声明周期里)
-
定义资源
/定义图片资源,一共五张
var imagesId=listOf(R.drawable.pic1,R.drawable.pic2,R.drawable.pic3,R.drawable.pic4,R.drawable.pic5) //定义五个图片控件,用于加载图片资源 var imageViewList=ArrayList<ImageView>() for(i in 0 until 5){ var imageView:ImageView=ImageView(activity) imageView.setImageResource(imagesId[i]) imageViewList.add(imageView) }
- 添加监听
// var vp_homePage:ViewPager=view!!.findViewById(R.id.vp_homePageAd) // vp_homePage.adapter=HomePageAdAdapter() vp_homePageAd.adapter=HomePageAdAdapter(imageViewList) // //添加页面改变监听 vp_homePageAd.addOnPageChangeListener(object :ViewPager.OnPageChangeListener{ override fun onPageScrollStateChanged(state: Int) { } //页面滚动的时候 override fun onPageScrolled( position: Int, positionOffset: Float, positionOffsetPixels: Int ) { } override fun onPageSelected(position: Int) { //添加圆点导航 addDots(position) } }) }
-
增加圆点导航方法
//偷懒的方法
fun addDots(position:Int){ dot_container.removeAllViews() var dots=arrayOf<TextView>(TextView(activity),TextView(activity),TextView(activity),TextView(activity),TextView(activity)) dots.forEach { it.text="." it.setTextColor(Color.GRAY) it.textSize=30f } for(i in 0 until 5) { dot_container.addView(dots[i]) } dots[position].setTextColor(Color.WHITE) }
The specified child already has a parent. You must call removeView() on the child's parent first
我在把同一个TextView多次添加到布局中发生此错误,因为添加一次之后TextView就有parent了,直接在for循环中使用(textView.parent as ViewGroup?)!!.removeView(textView)也不行,因为循环的第二次会把第一次添加的移除。所以只能创建多个textview
错误代码为:
fun addDots(position:Int){ var dots=ArrayList<TextView>() var textView=TextView(context) textView.text="." textView.setTextColor(Color.RED) textView.textSize=30f for(i in 0 until 5) { if ((textView.parent as ViewGroup?) != null) { (textView.parent as ViewGroup?)!!.removeView(textView) } dot_container.addView(textView) } }
继续完善
-
增加无限翻页
将getCount()返回值设置为Integer.MAX_VALUE,资源列表用到position取值的地方,要按5取模position%5,这样可以实现向后无限翻页;为了保证向前也能无限翻页,将PagerView的当前页设置为Integer.MAX_VALUE/2,同时-Integer.MAX_VALUE/2%5保证为5的倍数
vp_homePageAd.currentItem=Integer.MAX_VALUE/2-Integer.MAX_VALUE/2%5
-
循环播放
val handler: Handler =object:Handler(){ override fun handleMessage(msg: Message) { super.handleMessage(msg) vp_homePageAd.currentItem+=1 sendEmptyMessageDelayed(0,4000) } }
调用:handler.sendEmptyMessageDelayed(0,4000)
-
添加点击事件参考
vp_homePageAd.setOnTouchListener(object:View.OnTouchListener{ override fun onTouch(p0: View?, p1: MotionEvent?): Boolean { //Toast.makeText(context,"-x:${p1.x},y:${p1.y}",Toast.LENGTH_SHORT).show(); var flag:Int=0 when(p1!!.action){ MotionEvent.ACTION_DOWN->flag=0 //MotionEvent.ACTION_UP->flag=1 MotionEvent.ACTION_MOVE->flag=2 } println(flag.toString()) if(p1!!.action==MotionEvent.ACTION_UP&& flag==0){ val currentPage=vp_homePageAd.currentItem%5 when(currentPage+1){ 1->Toast.makeText(context,"1",Toast.LENGTH_SHORT).show() 2->Toast.makeText(context,"2",Toast.LENGTH_SHORT).show() 3->Toast.makeText(context,"3",Toast.LENGTH_SHORT).show() 4->Toast.makeText(context,"4",Toast.LENGTH_SHORT).show() 5->Toast.makeText(context,"5",Toast.LENGTH_SHORT).show() } } return false } })
(这个有问题。。。)
-
其他
·第一次进去程序没有圆点导航,需要初始化一下
·可以给每个页面添加文字说明
·用户按住某个页面时,应该停止轮播
效果
源码:
链接:https://pan.baidu.com/s/1NOoX2E7tV9js9QuNr-i5Hw
提取码:fwva
来源:https://www.cnblogs.com/vocus/p/12340067.html