android中添加头部视图的功能怎么实现

 我来答
在晴天的雨伞
2016-06-13 · TA获得超过6869个赞
知道大有可为答主
回答量:5761
采纳率:86%
帮助的人:1220万
展开全部
ListView是有addHeaderView和 addFooterView两个方法的.
但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法。
那么如果使用RecyclerView实现这两个方法的效果该怎么做呢?
网上查询了很久,试过各种各样的实现方式,终于让我发现一个还不错的实现方法,那么就给大家推荐一下。
项目地址(别人写的,非博主的)https://github.com/jczmdeveloper/XCRecyclerView
我看了下这个源码,很简单,即写了一个继承RecyclerView的控件,自己实现addHeaderView和addFooterView两个方法

?
code

package com.xqx.com.recyclerviewheaderdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class XCRecyclerView extends RecyclerView{

private ArrayList<View> mHeaderViews = new ArrayList<>();
private ArrayList<View> mFooterViews = new ArrayList<>();
private RecyclerView.Adapter mAdapter;
private RecyclerView.Adapter mWrapAdapter;
private static final int TYPE_HEADER = -101;
private static final int TYPE_FOOTER = -102;
private static final int TYPE_LIST_ITEM = - 103;
public XCRecyclerView(Context context) {
this(context, null);
}
public XCRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public XCRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context){

}

@Override
public void setAdapter(Adapter adapter) {
mAdapter = adapter;
mWrapAdapter = new WrapAdapter(mHeaderViews, mFooterViews, adapter);
super.setAdapter(mWrapAdapter);
mAdapter.registerAdapterDataObserver(mDataObserver);
}
public void addHeaderView(View view){
mHeaderViews.clear();
mHeaderViews.add(view);
}
public void addFooterView(View view){
mFooterViews.clear();
mFooterViews.add(view);
}
public int getHeaderViewsCount(){
return mHeaderViews.size();
}
public int getFooterViewsCount(){
return mFooterViews.size();
}
private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
mWrapAdapter.notifyDataSetChanged();
}

@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
}

// @Override
// public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
// mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
// }

@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
}

@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
}

@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
}
};
private class WrapAdapter extends RecyclerView.Adapter<ViewHolder>{

private Adapter mAdapter;
private List<View> mHeaderViews;
private List<View> mFooterViews;
public WrapAdapter(List<View> headerViews,List<View> footerViews,Adapter adapter){
this.mAdapter = adapter;
this.mHeaderViews = headerViews;
this.mFooterViews = footerViews;
}

public int getHeaderCount(){
return this.mHeaderViews.size();
}
public int getFooterCount(){
return this.mFooterViews.size();
}
public boolean isHeader(int position){
return position >= 0 && position < this.mHeaderViews.size();
}
public boolean isFooter(int position){
return position < getItemCount() && position >= getItemCount() - this.mFooterViews.size();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEADER){
return new CustomViewHolder(this.mHeaderViews.get(0));
}else if(viewType == TYPE_FOOTER){
return new CustomViewHolder(this.mFooterViews.get(0));
}else{
return this.mAdapter.onCreateViewHolder(parent,viewType);
}
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(isHeader(position)) return;
if(isFooter(position)) return;
int rePosition = position - getHeaderCount();
int itemCount = this.mAdapter.getItemCount();
if(this.mAdapter != null){
if(rePosition < itemCount){
Log.v("czm","rePosition/itemCount="+rePosition+"/"+itemCount);
this.mAdapter.onBindViewHolder(holder,rePosition);
return;
}
}
}
@Override
public long getItemId(int position) {
if (this.mAdapter != null && position >= getHeaderCount()) {
int rePosition = position - getHeaderCount();
int itemCount = this.mAdapter.getItemCount();
if (rePosition < itemCount) {
return this.mAdapter.getItemId(rePosition);
}
}
return -1;
}
@Override
public int getItemViewType(int position) {
if(isHeader(position)){
return TYPE_HEADER;
}
if(isFooter(position)){
return TYPE_FOOTER;
}
int rePosition = position - getHeaderCount();
int itemCount = this.mAdapter.getItemCount();
if(rePosition < itemCount){
return this.mAdapter.getItemViewType(position);
}
return TYPE_LIST_ITEM;
}
@Override
public int getItemCount() {
if(this.mAdapter != null){
return getHeaderCount() + getFooterCount() + this.mAdapter.getItemCount();
}else{
return getHeaderCount() + getFooterCount();
}
}

@Override
public void registerAdapterDataObserver(AdapterDataObserver observer) {
if(this.mAdapter != null){
this.mAdapter.registerAdapterDataObserver(observer);
}
}

@Override
public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
if(this.mAdapter != null){
this.mAdapter.unregisterAdapterDataObserver(observer);
}
}

private class CustomViewHolder extends ViewHolder{

public CustomViewHolder(View itemView) {
super(itemView);
}
}
}
}

XCRecyclerView
使用方法github里也写的清清楚楚的
?
code

private MyAdapter mAdapter;
private XCRecyclerView mRecyclerView;
private List<String> mData;
private View mHeaderView;
private View mFooterView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mData = new ArrayList<String>();
for(int i = 0; i < 10 ;i++){
mData.add("item_" + i);
}
mAdapter = new MyAdapter(mData);
mRecyclerView = (XCRecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mHeaderView = LayoutInflater.from(this).inflate(R.layout.layout_header,mRecyclerView,false);
mFooterView = LayoutInflater.from(this).inflate(R.layout.layout_footer,mRecyclerView,false);
mRecyclerView.addHeaderView(mHeaderView);
mRecyclerView.addFooterView(mFooterView);
mRecyclerView.setAdapter(mAdapter);
}

注意点:
addHeaderView之后 列表的数据坐标即相应发生变化!即addHeadView一次,列表第一个数据的下坐标+1(0-->1)
微测检测5.10
2023-05-10 广告
您好!建议咨 深圳市微测检测有限公司,已建立起十余个专业实验室,企业通过微测检测就可以获得一站式的测试与认 证解决方案;(EMC、RF、MFi、BQB、QI、USB、安全、锂电池、快充、汽车电子EMC、汽车手机互 联、语音通话质量),认证遇... 点击进入详情页
本回答由微测检测5.10提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式