Android Kotlin学习(六)- TabLayout+ViewPager2

该文章展示了如何在Android应用中使用Kotlin语言,结合TabLayout和ViewPager2来创建一个主界面。内容包括:布局XML设计,使用ViewModel管理数据,用RecyclerView展示列表,Glide库加载图片以及CoordinatorLayout实现折叠效果。代码示例详细解释了各个组件的配置和使用方法。


按照TabLayout+ViewPager2写一个界面

主界面布局

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.ProjectActivity">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:ignore="MissingConstraints">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways" />
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabGravity="center"
                app:tabIndicatorHeight="3dp"
                app:layout_constraintTop_toBottomOf="@+id/appbar"
                app:tabMode="scrollable"></com.google.android.material.tabs.TabLayout>
        </com.google.android.material.appbar.AppBarLayout>


            <androidx.viewpager2.widget.ViewPager2
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"></androidx.viewpager2.widget.ViewPager2>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

ViewModel管理数据

import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.kotlin.demo.model.BaseResponse
import com.kotlin.demo.model.RetrofitUtil
import com.kotlin.demo.model.project.ProjectListResponse
import com.kotlin.demo.model.project.ProjectRequest
import com.kotlin.demo.model.project.ProjectResponse
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class ProjectViewModel(application: Application) : AndroidViewModel(application) {
    var TAG = "ProjectViewModel"
    var projectTreeLD:MutableLiveData<List<ProjectResponse>> = MutableLiveData();
    var projectListLD:MutableLiveData<ProjectListResponse> = MutableLiveData();
    var count = 0;
    lateinit var request:ProjectRequest;
    init {
        request = RetrofitUtil.instance.retrofit?.create(ProjectRequest::class.java)!!;
    }
    fun getTree(){
        var call = request.getProjectTree();
        call.enqueue(object :Callback<BaseResponse<List<ProjectResponse>>>{
            override fun onResponse(
                call: Call<BaseResponse<List<ProjectResponse>>>,
                response: Response<BaseResponse<List<ProjectResponse>>>
            ) {
                Log.i(TAG,"getTree = "+response.body()?.data?.size)
                projectTreeLD.postValue(response.body()?.data);
            }

            override fun onFailure(call: Call<BaseResponse<List<ProjectResponse>>>, t: Throwable) {
            }

        })
    }
    fun getProjectList(id:Int){
        var call = request.getProjectList(count,id)
        call.enqueue(object :Callback<BaseResponse<ProjectListResponse>>{
            override fun onResponse(
                call: Call<BaseResponse<ProjectListResponse>>,
                response: Response<BaseResponse<ProjectListResponse>>
            ) {
                projectListLD.postValue(response.body()?.data)
            }

            override fun onFailure(call: Call<BaseResponse<ProjectListResponse>>, t: Throwable) {
            }

        })
    }
}

数据展示

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.databinding.DataBindingUtil
import androidx.databinding.Observable
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.kotlin.demo.R
import com.kotlin.demo.adapter.ProjectViewPagerAdapter
import com.kotlin.demo.databinding.ActivityProjectBinding
import com.kotlin.demo.model.project.ProjectResponse
import com.kotlin.demo.viewmodel.ProjectViewModel

class ProjectActivity : AppCompatActivity() {
    var TAG = "ProjectActivity"
    lateinit var binding:ActivityProjectBinding;
    lateinit var mViewModel:ProjectViewModel
    lateinit var adapter:ProjectViewPagerAdapter
    var projectFragmentList = arrayListOf<ProjectListFragment>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_project);
        initVM();
        initToolBar();
    }

    private fun initToolBar() {
        setSupportActionBar(binding.toolbar);
        supportActionBar?.setDisplayShowTitleEnabled(true);
        binding.toolbar.setTitle("首页");
    }

    private fun initVM() {

        mViewModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(ProjectViewModel::class.java);
        mViewModel.projectTreeLD.observe(this,object:Observer<List<ProjectResponse>>{
            override fun onChanged(t: List<ProjectResponse>?) {
                t?.let { initTablayout(it) };
            }
        })
        binding.lifecycleOwner = this
        mViewModel.getTree()
    }
    fun initTablayout(prjectTreeList:List<ProjectResponse>){
        Log.i(TAG,"initTablayout = "+prjectTreeList.size);
        binding.viewPager.setCurrentItem(1)
        for (projectTree in prjectTreeList){
            projectFragmentList.add(ProjectListFragment.newInstance(projectTree.id))
        }
        adapter = ProjectViewPagerAdapter(projectFragmentList,this)
        binding.viewPager.adapter = adapter
        var mediator = TabLayoutMediator(binding.tabLayout,binding.viewPager,object:TabLayoutMediator.TabConfigurationStrategy{
            override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
                tab.setText(prjectTreeList.get(position).name)
            }
        })
        mediator.attach()
    }
}

RecyclerView Adapter

import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.kotlin.demo.R
import com.kotlin.demo.bean.ProjectDetail
import com.kotlin.demo.databinding.ProjectItemBinding

class ProjectListAdapter(projectDetailList:List<ProjectDetail>,context:Context): RecyclerView.Adapter<ProjectListAdapter.MyViewHolder>() {
    val TAG = "ProjectListAdapter"
    var projectDetailList = projectDetailList;
    var mContext = context;
    var itemClick:RecyclerViewItemClick?=null
    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        var inflater = LayoutInflater.from(mContext);
        var binding:ProjectItemBinding = DataBindingUtil.inflate(inflater,R.layout.project_item,parent,false)
        return MyViewHolder(binding.root)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        var binding: ProjectItemBinding? = DataBindingUtil.getBinding(holder.itemView)
        holder.itemView.setOnClickListener(object :View.OnClickListener{
            override fun onClick(v: View?) {
                Log.i(TAG,"onClick = "+itemClick)
                itemClick?.let {
                    Log.i(TAG,"onClick = "+position)
                    itemClick?.onItemClick(position)
                }
            }
        })
        binding?.pro = projectDetailList.get(position)
        binding?.executePendingBindings()
    }

    override fun getItemCount(): Int {
        return projectDetailList.size;
    }
}

Glide展示图片

需要添加id ‘kotlin-kapt’
class BingdingUtils {
companion object{
@BindingAdapter(“image”)
@JvmStatic
public fun loadImageUrl(iv:ImageView, url:String){
Glide.with(iv).load(url).apply(RequestOptions().circleCrop().error(R.mipmap.glide_def) //异常时候显示的图片
.placeholder(R.mipmap.glide_def) //加载成功前显示的图片
.fallback(R.mipmap.glide_def)).into(iv)
}
}
}

CoordinatorLayout折叠效果

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="detail"
            type="com.kotlin.demo.bean.ProjectDetail" />
    </data>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.ProjectDetailActivity">

        <com.google.android.material.appbar.AppBarLayout
            app:statusBarScrim="?attr/colorPrimary"
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            tools:ignore="MissingConstraints">

            <com.google.android.material.appbar.CollapsingToolbarLayout
                app:statusBarScrim="?attr/colorPrimary"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:expandedTitleMarginEnd="64dp"
                app:expandedTitleMarginStart="48dp"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
                app:title="@{detail.title}">

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"
                    app:image1="@{detail.envelopePic}"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.7" />

                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="@android:color/transparent"
                    app:layout_collapseMode="pin"
                    app:title="@{detail.title}" />
            </com.google.android.material.appbar.CollapsingToolbarLayout>


        </com.google.android.material.appbar.AppBarLayout>

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <WebView
                android:id="@+id/web_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </androidx.core.widget.NestedScrollView>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@mipmap/collect_sel"
            app:layout_anchor="@id/appbar"
            app:layout_anchorGravity="bottom|end" />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

效果

0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝加点糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值