下面要讨论的是实现 recyclerview 多种 item 布局,先看效果图:
这上面是用的一个 RecyclerView ~听我慢慢道来,其中聊天室和榜单是 item1 ,中间的筛选的内容是 item2,剩下的数据内容则是剩下的item~~。还实现的滑动置顶,点击置顶。如何实现的,先给出 demo 下载链接,再慢慢看下面内容:
CSDN 下载 :https://download.csdn.net/download/wuqingsen1/10810684
GitHub 下载:https://github.com/wuqingsen/RecyclerViewTop
看不大明白的,可以直接下载 demo ,上面有清楚的注释内容~,下面主要看 adapter 的内容,和别的有什么不一样的:
/**
* Created by qd on 2018/2/2.
* wu
*/
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 分为了三块,对三块内容分别显示不同的内容,就是这么简单;再看 Activity 中的代码:
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 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;
}
}
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 + "条数据");
}
}
public void MoveToPosition(LinearLayoutManager manager, int n, boolean isMove) {
if (isMove) {
manager.scrollToPositionWithOffset(n, 0);
}
}
}
我在Activity 添加数据时,在最前面手动添加了两条,这样就不会导致 adapter 中的数据少了两条;剩下的内容,比如监听滑动变化等,都是为了筛选内容滑动置顶~~,在这里就不多说,不怎么明白的可以下载 demo 细细的看。