先看效果图,有波浪纹的是我点击的~~~:
可以看出,这个 RcyclerView 我想让它滑动置顶它就会到顶部,想点击置顶也可以到顶部。那么如何实现的呢,具体看下面,因为下面内容太多。如果不想了解,可以直接下载下面的例子,下面是下载地址:
GitHub 下载地址:https://github.com/wuqingsen/RecyclerViewTop
下面是讲的主要内容:
- MainActivity 和 activity_main 主要代码
- MainAdapter
1. MainActivity 和 activity_main 主要代码
public class MainActivity extends AppCompatActivity {
private MainAdapter adapter;
private RecyclerView recyclerView;
private List<String> mDatas;
private View include;
private String str;
//目标项是否在最后一个可见项之后
private boolean mShouldScroll;
//记录目标项位置
private int mToPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
include = findViewById(R.id.include);
recyclerView = findViewById(R.id.recyclerView);
//添加数据
addData();
adapter = new MainAdapter(MainActivity.this, mDatas);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
//滑动监听
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//定位初始点坐标
View stickyInfoView = recyclerView.findChildViewUnder(recyclerView.getMeasuredWidth() / 2, 1);
if (stickyInfoView != null) {
TextView typeName = stickyInfoView.findViewById(R.id.typeName);
if (typeName != null) {
str = typeName.getText().toString();
}
//标题为聊天室榜单部分的标识、筛选为筛选部分的标识,内容为数据内容的标识
if (str.equals("标题")) {
include.setVisibility(View.GONE);
} else if (str.equals("筛选")) {
include.setVisibility(View.VISIBLE);
} else if (str.equals("内容")) {
include.setVisibility(View.VISIBLE);
}
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) {
mShouldScroll = false;
smoothMoveToPosition(recyclerView, mToPosition);
}
}
});
//点击置顶
adapter.setmOnItemClickListerer(new MainAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (position != -1) {
smoothMoveToPosition(recyclerView, position);
}
}
});
}
private void addData() {
mDatas = new ArrayList<>();
//手动添加两条数据,adapter判断的依据
mDatas.add("0");
mDatas.add("1");
//for循环加入30条数据
for (int i = 1; i <= 30; i++) {
mDatas.add("这是第" + i + "条数据");
}
}
/**
* 平滑的滑动到指定位置
*/
private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
// 第一个可见位置
int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
// 最后一个可见位置
int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));
if (position < firstItem) {
// 第一种可能:跳转位置在第一个可见位置之前
mRecyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 第二种可能:跳转位置在第一个可见位置之后
int movePosition = position - firstItem;
if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
int top = mRecyclerView.getChildAt(movePosition).getTop();
mRecyclerView.smoothScrollBy(0, top);
}
} else {
// 第三种可能:跳转位置在最后可见项之后
mRecyclerView.smoothScrollToPosition(position);
mToPosition = position;
mShouldScroll = true;
}
}
}
看一下上面的注释,其实很好理解,不明白回复我~~。下面是 activity_main 的代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- 这是筛选布局 -->
<include
android:id="@+id/include"
layout="@layout/adapter_one"
android:visibility="gone" />
</RelativeLayout>
代码内只有一个 RecyclerView 和一个筛选布局。
2. MainAdapter 和布局文件
public class MainAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private final int type_zero = 0;
private final int type_one = 1;
private final int type_two = 2;
private List<String> mDatas;
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
public MainAdapter.OnItemClickListener mOnItemClickListerer;
public void setmOnItemClickListerer(MainAdapter.OnItemClickListener listerer) {
this.mOnItemClickListerer = listerer;
}
public MainAdapter(Context context, List<String> mDatas) {
this.context = context;
this.mDatas = mDatas;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == type_zero) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_zero, parent, false);
return new ZeroViewHolder(view);
} else if (viewType == type_one) {
//排序
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_one, parent, false);
return new OneViewHolder(view);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_other, parent, false);
}
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
case type_zero:
ZeroViewHolder zeroViewHolder = (ZeroViewHolder) holder;
//聊天室榜单,逻辑
break;
case type_one:
OneViewHolder oneViewHolder = (OneViewHolder) holder;
//筛选,adapter点击置顶
oneViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListerer.onItemClick(view,position);
}
});
break;
default:
MyViewHolder myViewHolder = (MyViewHolder) holder;
//内容,写逻辑
myViewHolder.tv_text.setText(mDatas.get(position));
break;
}
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return type_zero;
} else if (position == 1) {
return type_one;
} else {
return type_two;
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
class ZeroViewHolder extends RecyclerView.ViewHolder {
public ZeroViewHolder(View itemView) {
super(itemView);
}
}
public class OneViewHolder extends RecyclerView.ViewHolder {
public OneViewHolder(View itemView) {
super(itemView);
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_text;
public MyViewHolder(View itemView) {
super(itemView);
tv_text = itemView.findViewById(R.id.tv_text);
}
}
}
Adapter 中主要判断为 position == 0 是聊天室榜单, position == 1 是筛选,其他的为显示的数据。
欢迎提出意见~~~