前言
在android开发过程中,我们经常会遇到需要将列表展示的数据定位到某个具体的item,并将此item在列表中置顶展示的需求。那么,今天就来讲讲RecyclerView实现置顶显示某个具体的item的实现。
今天涉及内容:
- RecyclerView依赖
- 列表展示准备
- 封装的 PositionScroller 类实现滚动item置顶
- 实现滚动item置顶的另一种简单方式
- 滚动置顶在MainActivity中使用,MainActivity代码
- 效果图和项目结构图
- PositionScroller 类及 moveToPosition(Context context,int position) 方法源码
先看看效果图吧
一. RecyclerView依赖
以RecyclerView实现列表,这里我依赖的是 androidX中的RecyclerView,所以要在 app对应的module 中添加RecyclerView引用,如下:
implementation 'androidx.recyclerview:recyclerview:1.0.0-beta01'
二. 列表展示准备
下面以RecyclerView实现字符串列表展示为例。先需要写一个RecyclerView对应的列表适配器,下面贴出适配器 TestAdapter的代码:
package com.example.function;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.testdemo.R;
import java.util.List;
/**
* Description:
* <p>
* Author:pei
* Date: 2019/8/26
*/
public class TestAdapter<T>extends RecyclerView.Adapter {
protected Context mContext;
protected View mLayoutView;
protected List<T> mData;
public TestAdapter(Context context,List<T>data){
this.mContext=context;
this.mData=data;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mLayoutView= LayoutInflater.from(mContext).inflate(R.layout.item_layout,parent,false);
ViewHolder viewHolder=new ViewHolder(mLayoutView);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
String name=mData.get(position).toString();
((ViewHolder)holder).mTvName.setText(name);
}
@Override
public int getItemCount() {
return mData==null?0:mData.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView mTvName;
public ViewHolder(View view) {
super(view);
mTvName=(TextView)view.findViewById(R.id.tv_name);
}
}
}
TestAdapter对应的布局 item_layout 代码如下
<?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="wrap_content"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="30dp"
android:background="#ff0000"
android:layout_margin="5dp"
android:paddingLeft="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="@color/colorPrimary"
android:textSize="16sp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
然后在MainActivity中准备50个字符串方便测试:
mList=new ArrayList<>();
for (int i = 0; i < 50; i++) {
mList.add("同学"+i);
}
MainActivity中给RecyclerView做些基本配置
mTestAdapter=new TestAdapter(MainActivity.this,mList);
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
layoutManager.setSmoothScrollbarEnabled(true);
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mTestAdapter);
ok,这样RecyclerView列表显示已经准备好了。
三. 封装的 PositionScroller 类实现滚动item置顶
为了方便RecyclerView指定具体item置顶显示的功能,我将实现的代码封装到一个类 PositionScroller中。下面来讲讲PositionScroller中的方法
//PositionScroller 类初始化
public PositionScroller(RecyclerView recyclerView)
//滑动到指定位置
public void smoothMoveToPosition(int position)
注释已经很明了了,需要注意的是,PositionScroller方法中有传一个RecyclerView 参数进去,初始化方法内部还对RecyclerView 滚动做了监听,用于处理实现滚动具体item置顶的功能。
smoothMoveToPosition方法中传的是具体itemde下标。
ok,下面看看PositionScroller 在MainActivity中如何使用。
第一步,你需要初始化PositionScroller ,并传入一个RecyclerView 控件:
//声明PositionScroller
private PositionScroller mPositionScroller;
//PositionScroller初始化
mPositionScroller=new PositionScroller(mRecyclerView);
然后在调用的时候,你可以这样:
//mCurrentIndex为item的下标
mPositionScroller.smoothMoveToPosition(mCurrentIndex);
四. 实现滚动item置顶的另一种简单方式
利用PositionScroller类可以实现RecyclerView指定具体item置顶显示的功能,但是由于PositionScroller初始化时涉及到RecyclerView的滚动监听,当RecyclerView在使用的时候不涉及到滚动监听还好,如果涉及到滚动监听,势必会带来一些麻烦,也就是说PositionScroller由于单独封装的原因在使用的时候多少存在些隐患,还有就是PositionScroller类代码相对较多,因此我们还可以用另一个自己写的方法来实现滚动定位效果,这个方法是:
/***
* 滑动到指定位置(此position会列表置顶)
* @param context
* @param position
*/
public void moveToPosition(RecyclerView recyclerView,int position,Context context){
在需要使用的时候,你可以直接调用这个方法。
五. 滚动置顶在MainActivity中使用,MainActivity代码
下面贴出这两种方法在MainActivity中的使用代码:
package com.example.testdemo;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import com.example.function.PositionScroller;
import com.example.function.TestAdapter;
import com.util.ToastUtil;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtn;
private RecyclerView mRecyclerView;
private TestAdapter<String>mTestAdapter;
private List<String>mList;
private PositionScroller mPositionScroller;
private int mCurrentIndex=30;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
setListener();
}
private void initData() {
mBtn = findViewById(R.id.btn);
mRecyclerView = findViewById(R.id.rv);
mList=new ArrayList<>();
for (int i = 0; i < 50; i++) {
mList.add("同学"+i);
}
mTestAdapter=new TestAdapter(MainActivity.this,mList);
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
layoutManager.setSmoothScrollbarEnabled(true);
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mTestAdapter);
mPositionScroller=new PositionScroller(mRecyclerView);
}
private void setListener() {
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ToastUtil.shortShow("点击了:"+mCurrentIndex);
// mPositionScroller.smoothMoveToPosition(mCurrentIndex);
moveToPosition(mRecyclerView,mCurrentIndex,MainActivity.this);
mCurrentIndex++;
if(mCurrentIndex>49){
mCurrentIndex=0;
}
}
});
}
@Override
public void onClick(View v) {
}
//以下方法省略
//......
}
六. 效果图和项目结构图
效果图
项目结构图
七. PositionScroller 类及 moveToPosition(Context context,int position) 方法源码
讲了这么多,下面给出PositionScroller 类及 moveToPosition(Context context,int position) 方法源码
PositionScroller 类代码如下: