91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中封裝RecyclerView實現添加頭部和底部示例代碼

發布時間:2020-09-14 06:01:05 來源:腳本之家 閱讀:938 作者:lin墨 欄目:移動開發

前言

我們大家都知道ListView具有添加頭部和添加底部的方法,但是RecyclerView并沒有這樣子的方法。所以RecyclerView是不能添加底部和頭部的,但是能不能仿造ListView來實現RecyclerView添加頭部和底部呢?答案當然是可行的。本文就來給大家介紹了關于Android封裝RecyclerView添加頭部和底部的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

首先看下實現的效果:

Android中封裝RecyclerView實現添加頭部和底部示例代碼

代碼如下:

public class WrapMyRecyclerView extends RecyclerView {

 private Adapter mAdapter;
 private ArrayList<View> mHeaderViewInfos = new ArrayList<>();//保存headerView
 private ArrayList<View> mFooterViewInfos = new ArrayList<>();//保存footerView

 public WrapMyRecyclerView(Context context) {
  super(context);
 }

 public WrapMyRecyclerView(Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
 }

 public WrapMyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }

 /**
  * 添加headerView
  * @param v
  */
 public void addHeaderView(View v) {
  mHeaderViewInfos.add(v);
  // Wrap the adapter if it wasn't already wrapped.
  if (mAdapter != null) {
   if (!(mAdapter instanceof RecyclerHeaderViewListAdapter)) {
    wrapHeaderListAdapterInternal();
   }
  }
 }

 /**
  * 添加一個footerView
  * @param v
  */
 public void addFooterView(View v) {
  mFooterViewInfos.add(v);
  // Wrap the adapter if it wasn't already wrapped.
  if (mAdapter != null) {
   if (!(mAdapter instanceof RecyclerHeaderViewListAdapter)) {
    wrapHeaderListAdapterInternal();
   }
  }
 }

 /**
  * 設置一個Adapter
  * @param adapter
  */
 @Override
 public void setAdapter(Adapter adapter) {

  if (mHeaderViewInfos.size() > 0 || mFooterViewInfos.size() > 0) {
   mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);
  } else {
   mAdapter = adapter;
  }
  super.setAdapter(mAdapter);
 }

 private void wrapHeaderListAdapterInternal() {
  mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, mAdapter);
 }

 /**
  * 新建一個RecyclerHeaderViewListAdapter對象
  * 最終的adapter實現它
  * @param headerViewInfos
  * @param footerViewInfos
  * @param adapter
  * @return
  */
 protected RecyclerHeaderViewListAdapter wrapHeaderListAdapterInternal(
   ArrayList<View> headerViewInfos,
   ArrayList<View> footerViewInfos,
   Adapter adapter) {
  return new RecyclerHeaderViewListAdapter(headerViewInfos, footerViewInfos, adapter);
 }

}

這就是封裝的RecyclerView,里面主要有三個方法addHeaderView、 addFooterView和重寫的setAdapter。這里的唯一的思想就是偷梁換柱,當我們添加頭部、尾部或者設置adapter時,真正的adapter并不是我們傳入的adapter,而是重新new 了一個RecyclerHeaderViewListAdapter。這才是RecyclerView最終設置的adapter。

其實我們看到ListView也是通過這樣子的思想來添加頭部和尾部的。

Android中封裝RecyclerView實現添加頭部和底部示例代碼

這就是ListView的addHeaderView方法,它會偷偷的創建HeaderViewListAdapter這個adapter。最終添加的header和footer在HeaderViewListAdapter里面實現。

public class RecyclerHeaderViewListAdapter extends RecyclerView.Adapter {

 private final ArrayList<View> mHeaderViewInfos;//保存headerview數據
 private final ArrayList<View> mFooterViewInfos;//保存footerView數據
 private RecyclerView.Adapter mAdapter;   //用戶自己構造的adapter
 private static final int RECYCLER_HEADER_VIEW = 0x001;//headerview類型
 private static final int RECYCLER_FOOTER_VIEW = 0x002;//footerView類型


 /**
  * 構造方法
  * 初始化
  * @param headerViewInfos
  * @param footerViewInfos
  * @param adapter
  */
 public RecyclerHeaderViewListAdapter(ArrayList<View> headerViewInfos,
           ArrayList<View> footerViewInfos,
           RecyclerView.Adapter adapter) {

  mAdapter = adapter;
  if (headerViewInfos == null) {
   mHeaderViewInfos = new ArrayList<>();
  } else {
   mHeaderViewInfos = headerViewInfos;
  }

  if (footerViewInfos == null) {
   mFooterViewInfos = new ArrayList<>();
  } else {
   mFooterViewInfos = footerViewInfos;
  }
 }

 /**
  * 根據getItemViewType返回的條目類型
  * 創建不同的itemview
  * 傳入的adapter,回調它的onCreateViewHolder即可
  * @param parent
  * @param viewType
  * @return
  */
 @Override
 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  if (viewType == RECYCLER_HEADER_VIEW){
   return new HeaderViewLayout(mHeaderViewInfos.get(0));
  }else if (viewType == RECYCLER_FOOTER_VIEW){
   return new HeaderViewLayout(mFooterViewInfos.get(0));
  }
  return mAdapter.onCreateViewHolder(parent,viewType);
 }

 /**
  * 綁定數據
  * headerview和footerview不需要綁定數據,直接return即可
  * 傳入的adapter需要回調它的onBindViewHolder即可
  * @param holder
  * @param position
  */
 @Override
 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  //header
  int numHeaders = getHeadersCount();
  if (position < numHeaders) {
   return ;
  }
  //adapter body
  final int adjPosition = position - numHeaders;
  int adapterCount = 0;
  if (mAdapter != null) {
   adapterCount = mAdapter.getItemCount();
   if (adjPosition < adapterCount) {
    mAdapter.onBindViewHolder(holder, adjPosition);
    return ;
   }
  }
  //footer
 }

 /**
  * 返回條目的類型
  * 傳入的adapter,回調它的getItemViewType即可
  * @param position
  * @return
  */
 @Override
 public int getItemViewType(int position) {
  // Header
  int numHeaders = getHeadersCount();
  if (position < numHeaders) {
   return RECYCLER_HEADER_VIEW;
  }
  // Adapter
  final int adjPosition = position - numHeaders;
  int adapterCount = 0;
  if (mAdapter != null) {
   adapterCount = mAdapter.getItemCount();
   if (adjPosition < adapterCount) {
    return mAdapter.getItemViewType(position);
   }
  }
  // Footer (off-limits positions will throw an IndexOutOfBoundsException)
  return RECYCLER_FOOTER_VIEW;
 }

 /**
  * 總條目即:footerview的條目+headerview的條目+穿入的adapter條目
  * @return
  */
 @Override
 public int getItemCount() {
  if (mAdapter != null) {
   return getFootersCount() + getHeadersCount() + mAdapter.getItemCount();
  } else {
   return getFootersCount() + getHeadersCount();
  }
 }

 /**
  * 獲取headerview的條目
  * @return
  */
 public int getHeadersCount() {
  return mHeaderViewInfos.size();
 }

 /**
  * 獲取footervie的條目
  * @return
  */
 public int getFootersCount() {
  return mFooterViewInfos.size();
 }

 /**
  * 這是footerview和headerview的ViewHolder需要
  * 這里只是提供一個構造器即可,實際上用處不大
  */
 private static class HeaderViewLayout extends RecyclerView.ViewHolder{

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

}

這是實現添加header、footer和傳入adapter的RecyclerHeaderViewListAdapter。具體的邏輯都在文件的注釋里面有說明。邏輯是仿造ListView的HeaderViewListAdapter來實現的。

其實就是創建一個adapter,然后根據不同的條目類型來創建條目和綁定條目的數據即可。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="com.wrap.recycler.WrapRecyclerViewActivity">

 <com.lwj.wrap.recycler.WrapMyRecyclerView
  android:id="@+id/wrap_recyclerview"
  android:layout_width="match_parent"
  android:layout_height="match_parent"/>

</LinearLayout>

這是布局文件

public class WrapRecyclerViewActivity extends AppCompatActivity {
 private WrapMyRecyclerView mRecyclerView;
 private MyAdapter mMyAdapter;
 private List<String> mList01 = new ArrayList<>();
 private static final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_wrap_recycler_view);
  getData();
  mRecyclerView = (WrapMyRecyclerView) this.findViewById(R.id.wrap_recyclerview);
  mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

  //加入headerView
  ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(WC,WC);
  ImageView headerView = new ImageView(this);
  headerView.setImageResource(R.drawable.timg);
  headerView.setLayoutParams(params);
  mRecyclerView.addHeaderView(headerView);
  //設置adapter
  mMyAdapter = new MyAdapter(this,mList01);
  mRecyclerView.setAdapter(mMyAdapter);
  //加入footerView
  params = new ViewGroup.LayoutParams(WC,WC);
  ImageView footerView = new ImageView(this);
  footerView.setImageResource(R.drawable.hhfj);
  footerView.setLayoutParams(params);
  mRecyclerView.addFooterView(footerView);
  mMyAdapter.notifyDataSetChanged();

 }
 public void getData() {
  for (int i = 0; i < 3; i++) {
   String data ="adapter...." + i;
   mList01.add(data);
  }
 }
}

使用直接調用addHeaderView、addFooterView即可。

除了這種方式來實現addHeaderView和addFooterView,另外一種方式就是封裝Adapter來實現,原理還是保持不變:根據不同的條目類型來創建條目和綁定條目的數據。

public class MyCircleRecycViewAdapter extends RecyclerView.Adapter {
 public List<CircleInfo.CirclePageInfo> infos = null;
 private Context mContext;
 private ListViewImgLoader mLoader;
 private View VIEW_FOOTER;//尾部
 private View VIEW_HEADER;//頭部
 //Type
 private int TYPE_NORMAL = 1000;
 private int TYPE_HEADER = 1001;
 private int TYPE_FOOTER = 1002;
 private int tagType = TYPE_NORMAL;

 public MyCircleRecycViewAdapter(Context context,List<CircleInfo.CirclePageInfo> datas) {
  this.infos = datas;
  this.mContext = context;
  mLoader = new ListViewImgLoader();
  mLoader.setMemoryCacheSize(1024 * 1024);
  mLoader.setVisibleItemCount(12);
 }

 @Override
 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  if (viewType == TYPE_FOOTER) {
   tagType = TYPE_FOOTER;
   return new MyCircleItemHolder(VIEW_FOOTER);
  } else if (viewType == TYPE_HEADER) {
   tagType = TYPE_HEADER;
   return new MyCircleItemHolder(VIEW_HEADER);
  } else {
   tagType = TYPE_NORMAL;
   View view = LayoutInflater.from(mContext).inflate(R.layout.circle_gridview_items, parent,false);
   return new MyCircleItemHolder(view);
  }
 }

 @Override
 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  if (!isHeaderView(position) && !isFooterView(position)) {
   if (haveHeaderView()) position--;
   MyCircleItemHolder viewHolder = (MyCircleItemHolder)holder;
   CircleInfo.CirclePageInfo mInfo = infos.get(position);
   setData(viewHolder,mInfo);
  }
 }

 @Override
 public int getItemCount() {
  int count = (infos == null ? 0 : infos.size());
  if (VIEW_FOOTER != null) {
   count++;
  }
  if (VIEW_HEADER != null) {
   count++;
  }
  return count;
 }

 @Override
 public int getItemViewType(int position)
 {
  if (isHeaderView(position)) {
   return TYPE_HEADER;
  } else if (isFooterView(position)) {
   return TYPE_FOOTER;
  } else {
   return TYPE_NORMAL;
  }
 }
 public void addHeaderView(View headerView) {
  if (haveHeaderView()) {
   throw new IllegalStateException("hearview has already exists!");
  } else {
   //避免出現寬度自適應
   ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(Utils.getRealPixel(30), Utils.getRealPixel(230));
   headerView.setLayoutParams(params);
   VIEW_HEADER = headerView;
   notifyItemInserted(0);
  }
 }
 public void addFooterView(View footerView) {
  if (haveFooterView()) {
   throw new IllegalStateException("footerView has already exists!");
  } else {
   ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
   footerView.setLayoutParams(params);
   VIEW_FOOTER = footerView;
//   ifGridLayoutManager();
   notifyItemInserted(getItemCount() - 1);
  }
 }

 private boolean haveHeaderView() {
  return VIEW_HEADER != null;
 }

 public boolean haveFooterView() {
  return VIEW_FOOTER != null;
 }

 private boolean isHeaderView(int position) {
  return haveHeaderView() && position == 0;
 }

 private boolean isFooterView(int position) {
  return haveFooterView() && position == getItemCount() - 1;
 }


 private void setData(final MyCircleItemHolder viewHolder, final CircleInfo.CirclePageInfo mInfo) {
  if(mInfo == null || mInfo == viewHolder.tagInfo)
  {
   return;
  }else{
   viewHolder.tagInfo = mInfo;
   if(!StrUtils.isEnpty(mInfo.thread_unread)){
    if(mInfo.thread_unread.equals("0")){
     viewHolder.threaduUnreadTv.setVisibility(View.INVISIBLE);
    }else{
     viewHolder.threaduUnreadTv.setVisibility(View.VISIBLE);
     viewHolder.threaduUnreadTv.setText(mInfo.thread_unread);
    }
   }else{
    viewHolder.threaduUnreadTv.setVisibility(View.INVISIBLE);
   }

   if (!TextUtils.isEmpty(viewHolder.tagUrl)){
    if(mInfo.circle_img_path != null && !(mInfo.circle_img_path.equals(viewHolder.tagUrl))){
     setImage(viewHolder.mImageView,mInfo.circle_img_path);
    }
   }else{
    setImage(viewHolder.mImageView,mInfo.circle_img_path);
   }
   if (!TextUtils.isEmpty(mInfo.circle_img_path)){
    viewHolder.tagUrl = mInfo.circle_img_path;
   }
   if(mInfo.circleName != null){
    if(mInfo.circleName.length() > 5){
     String s = mInfo.circleName.substring(0,5) + "...";
     viewHolder.textView.setText(s);
    }else{
     viewHolder.textView.setText(mInfo.circleName);
    }
   }

  }
 }

 private void setImage(final ColorFilterImageView mImageView, final String imgUrl){
  mImageView.setBackgroundColor(0xffadadad);
  mImageView.setImageBitmap(null);
  if(!TextUtils.isEmpty(imgUrl))
  {
   mLoader.loadImage(mImageView.hashCode(), imgUrl, 300, new DnImg.OnDnImgListener()
   {

    @Override
    public void onProgress(String url, int downloadedSize, int totalSize)
    {
     // TODO Auto-generated method stub

    }

    @Override
    public void onFinish(String url, String file, Bitmap bmp)
    {
     if(url.equals(imgUrl))
     {
      mImageView.setImageBitmap(bmp);
     }
    }
   });
  }else{
   mImageView.setBackgroundColor(0xffadadad);
   mImageView.setImageBitmap(null);
  }
 }


 class MyCircleItemHolder extends RecyclerView.ViewHolder{
  private ColorFilterImageView mImageView;
  private TextView textView;
  private CircleInfo.CirclePageInfo tagInfo;
  private String tagUrl;
  private TextView threaduUnreadTv;

  public MyCircleItemHolder(final View itemView) {
   super(itemView);
   if(tagType == TYPE_NORMAL){
    mImageView = (ColorFilterImageView)itemView.findViewById(R.id.quan_icon);
    mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    textView = (TextView)itemView.findViewById(R.id.quan_name);
    threaduUnreadTv = (TextView)itemView.findViewById(R.id.quan_num);
    mImageView.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
      if (mListener != null){
       mListener.oncliItem(itemView,tagInfo,threaduUnreadTv);
      }
     }
    });
   }

  }
 }
 public OnclickMyCircleItemListener mListener;
 public void setOnclickMyCircleItemListener(OnclickMyCircleItemListener l){
  this.mListener = l;
 }
 public interface OnclickMyCircleItemListener{
  void oncliItem(View view,CircleInfo.CirclePageInfo info,View threadNumTv);
 }

 public void pauseLoader(){
  if(mLoader != null)
  {
   mLoader.pause();
  }
 }
 public void resumeLoader(){
  if(mLoader != null)
  {
   mLoader.resume();
  }
 }
 public void closeLoader(){
  if(mLoader != null)
  {
   mLoader.close();
  }
 }

}

總結

以上就是這篇文章的全部內容了,希望本文的內容對各位Android開發者們的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兰州市| 龙里县| 康乐县| 嘉禾县| 新竹市| 和林格尔县| 仙桃市| 高邮市| 博客| 余庆县| 大冶市| 睢宁县| 西乌| 邹城市| 葫芦岛市| 合阳县| 通榆县| 七台河市| 云南省| 长宁区| 安义县| 台东市| 宜丰县| 城固县| 长岭县| 济阳县| 新干县| 康定县| 射洪县| 宜君县| 白银市| 兴隆县| 台北市| 深水埗区| 专栏| 酒泉市| 墨脱县| 天等县| 黎川县| 门头沟区| 泽普县|