“我正在参加「掘金·启航计划」”
仿淘宝客户端ViewPager滑动到最后一页,再拖动的时候跳到详情的功能. 效果如下:
采用的方案是在ViewPager图片的后面再加一个view,然后滑动viewpager的时候去处理下就行了。
activity布局(ViewPager2来实现图片的滑动查看 更简洁):
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".viewpager2.MyActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="50dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="300dp"
android:layout_marginRight="20dp"
android:textColor="#ff00ff"
android:textSize="26sp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
为ViewPager2创建一个适配器:
适配器布局:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<ImageView
android:id="@+id/iv_datinghome_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_more_datinghome_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:background="#000000"
android:visibility="gone">
<ImageView
android:id="@+id/iv_more_datinghome_photo"
android:layout_width="9dp"
android:layout_height="12dp"
android:src="@mipmap/ic_apply_recomm"
android:layout_marginLeft="19dp"/>
<TextView
android:id="@+id/tv_more_datinghome_photo"
android:layout_width="12dp"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="12sp"
android:text="滑动查看更多"/>
</LinearLayout>
</FrameLayout>
适配器
package com.demo.cdh.cardswipedemo.viewpager2
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.demo.cdh.cardswipedemo.R
import com.demo.cdh.cardswipedemo.bean.CardBean
class MyAdapter (mContext: Context, attaches:MutableList<CardBean>): RecyclerView.Adapter<MyAdapter.ViewHolder>() {
var mContext: Context
var attaches:MutableList<CardBean>
var map:MutableMap<Int,MyAdapter.ViewHolder> = mutableMapOf()
init {
this.mContext=mContext
this.attaches=attaches
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_vp,parent,false))
}
fun changeMore(position: Int,s:String){
map.get(position)?.moreTv?.text="${s}查看更多"
if (s.equals("释放")){
map.get(position)?.moreIv?.setImageResource(R.mipmap.ic_remove)
}else{
map.get(position)?.moreIv?.setImageResource(R.mipmap.ic_apply_recomm)
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
map.put(position,holder)
if (position!=itemCount-1){
var bean=attaches?.get(position)
holder.iv.setImageResource(bean.cover)
holder.moreLl.visibility= View.GONE
}else{
holder.moreLl.visibility= View.VISIBLE
}
}
override fun getItemCount(): Int {
val size=attaches?.size?:0
if(size==0){
return 0
}
return size+1
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var iv: ImageView
var moreLl: LinearLayout
var moreIv: ImageView
var moreTv: TextView
init {
iv=itemView.findViewById(R.id.iv_datinghome_photo)
moreLl=itemView.findViewById(R.id.ll_more_datinghome_photo)
moreIv=itemView.findViewById(R.id.iv_more_datinghome_photo)
moreTv=itemView.findViewById(R.id.tv_more_datinghome_photo)
}
}
}
在activity中为ViewPager2设置适配器:
package com.demo.cdh.cardswipedemo.viewpager2
import android.content.Intent
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager2.widget.ViewPager2
import com.demo.cdh.cardswipedemo.MainActivity
import com.demo.cdh.cardswipedemo.R
import com.demo.cdh.cardswipedemo.bean.CardBean
class MyActivity : AppCompatActivity() {
var needJump=false
var lastOffset=0f
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
val vp=findViewById<ViewPager2>(R.id.vp)
val tv=findViewById<TextView>(R.id.tv)
val data: MutableList<CardBean> = ArrayList()
data.add(CardBean(R.mipmap.tu15))
data.add(CardBean(R.mipmap.tu16))
data.add(CardBean(R.mipmap.tu17))
tv.text="$1/${data.size}"
val mAdapter=MyAdapter(this,data)
vp.adapter=mAdapter
vp.registerOnPageChangeCallback(object :ViewPager2.OnPageChangeCallback(){
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
if (position==data.size-1){
if (positionOffsetPixels>300&&positionOffset>lastOffset){
needJump=true
mAdapter.changeMore(vp.currentItem+1,"释放")
}else{
needJump=false
mAdapter.changeMore(vp.currentItem+1, "滑动")
}
lastOffset=positionOffset
}
}
override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state)
// 1开始滑动 2滑动结束(最后一页再往下页方向滑不会走该状态) 0什么都没做
if (state==2&&needJump) {
needJump=false
startActivity(Intent(this@MyActivity, MainActivity::class.java))
}
}
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
var cur=position+1
tv.text="$cur/${data.size}"
if (position==data.size){
mAdapter.changeMore(vp.currentItem, "滑动")
vp.currentItem=position-1
}
}
})
}
}
总结
ViewPager2多加了一个view但是又不能让其选择到这个多加的view,所以需要在onPageSelected方法中判断当选择的是最后一个view时手动将选择的view只为前一个。 当按住向左拖动不松达到进入下一页的临界值后依然不松向右放回,最后松开,此时不应该跳转详情页,所以需要在onPageScrolled和onPageScrollStateChanged方法中配合处理,用positionOffset>lastOffset判断滑动后是否又放回了,state==2判断滑动是否结束了,这样跳转就合理了。