Android 中RecyclerView多种item布局的写法(头布局+脚布局)

RecyclerView多个item布局的写法(头布局+脚布局)

上图

github

下载源码

Initial commit第一次提交的代码,为本文内容

以下的为主要代码,看注释即可,比较简单

MainActivity

含上拉加载更多

package com.anew.recyclerviewall;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
  private RecyclerView mRecyclerView;
  private List<String> mHeadList;
  private List<String> mBodyList;
  private List<String> mFootList;
  private MyAdapter mAdapter;
  private LinearLayoutManager mLayoutManager;
  Handler mHandler = new Handler();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mHeadList = new ArrayList<>();
    for (int i = 0; i < 1; i++) {
      mHeadList.add("head" + i);
    }
    mBodyList = new ArrayList<>();
    for (int i = 'A'; i < 'L'; i++) {
      mBodyList.add("" + (char) i);
    }
    mFootList = new ArrayList<>();
    for (int i = 0; i < 1; i++) {
      mFootList.add("foot" + i);
    }
    mRecyclerView = (RecyclerView) findViewById(R.id.rv);
//    使用默认的api绘制分割线
    mRecyclerView.addItemDecoration
        (new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL));
//    设置增加删除item的动画效果
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//    瀑布流
//    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mAdapter = new MyAdapter(this, mHeadList, mBodyList, mFootList);
    mRecyclerView.setAdapter(mAdapter);
    // 当目前的可见条目是所有数据的最后一个时,开始加载新的数据
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        int lastCompletelyVisibleItemPosition = mLayoutManager.findLastCompletelyVisibleItemPosition();
        if (lastCompletelyVisibleItemPosition + 1 == mAdapter.getItemCount()) {
          mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
              List<String> mMoreList = new ArrayList<>();
              for (int i = 0; i < 3; i++) {
                mMoreList.add("more" + i);
              }
              mBodyList.addAll(mMoreList);
              mAdapter.notifyItemInserted(mAdapter.getItemCount() - 2);
            }
          }, 1500);
          Log.e("qqq", "到底了" + lastCompletelyVisibleItemPosition);
        }
        int firstCompletelyVisibleItemPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
        if (firstCompletelyVisibleItemPosition == 0&&dy<0) {
          Log.e("eeeee", "开始刷新呀呀呀");
        }
      }
    });
  }
}

MyAdapter

对外部:头布局list、身体布局list、脚布局list,所有的list单独计数

内部:对position进行调整,这里需要耐心调整position

package com.anew.recyclerviewall;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
/**
 * Created by a on 2017/1/7.
 */
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
  private Context context;
  private List<String> mHeadList;
  private List<String> mBodyList;
  private List<String> mFootList;
  private static final int HEAD_TYPE = 1;
  private static final int BODY_TYPE = 2;
  private static final int FOOT_TYPE = 3;
  public MyAdapter(Context context, List<String> headList, List<String> bodyList, List<String> footList) {
    this.context = context;
    this.mHeadList = headList;
    this.mBodyList = bodyList;
    this.mFootList = footList;
  }
  //  ★ 1. 定义规则,什么情况,是哪一种ViewType
  @Override
  public int getItemViewType(int position) {
    int viewType = -1;
    if (position < getHeadCount()) {
      viewType = HEAD_TYPE;
    } else if (position > getHeadCount() + getBodyCount() - 1) {
      //这里最后要减去1,慢慢地去数
      viewType = FOOT_TYPE;
    } else {
      viewType = BODY_TYPE;
    }
    return viewType;
  }
  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = null;
    //  ★ 2. 根据viewType来确定加载那个布局,返回哪一个ViewHolder
    switch (viewType) {
      case HEAD_TYPE:
        view = inflater.inflate(R.layout.item_head, parent, false);
        return new HeadHolder(view);
      case BODY_TYPE:
        view = inflater.inflate(R.layout.item_body, parent, false);
        return new BodyHolder(view);
      case FOOT_TYPE:
        view = inflater.inflate(R.layout.item_foot, parent, false);
        return new FootHolder(view);
    }
    return null;
  }
  @Override
  public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
// ★ 3. 根据holder是哪一个ViewHolder的实例,来确定操作哪一个布局的UI
    if (holder instanceof HeadHolder) {
      HeadHolder headHolder = (HeadHolder) holder;
      headHolder.mTvHead.setText(mHeadList.get(position) + "");
      headHolder.mTvHead.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          addData();
        }
      });
    }
    if (holder instanceof BodyHolder) {
      final BodyHolder bodyHolder = (BodyHolder) holder;
      bodyHolder.mTvBody.setText(mBodyList.get(position - getHeadCount()) + "");
      bodyHolder.mTvBody.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          removeData(bodyHolder.getAdapterPosition());
        }
      });
    }
    if (holder instanceof FootHolder) {
      final FootHolder footHolder = (FootHolder) holder;
      footHolder.mTvFoot.setText(mFootList.get(position - getHeadCount() - getBodyCount()) + "");
      footHolder.mTvFoot.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          Toast.makeText(context, footHolder.getAdapterPosition() + "",
              Toast.LENGTH_SHORT).show();
        }
      });
    }
  }
  @Override
  public int getItemCount() {
    return getHeadCount() + getBodyCount() + getFootCount();
  }
  private int getFootCount() {
    return mFootList.size();
  }
  private int getBodyCount() {
    return mBodyList.size();
  }
  private int getHeadCount() {
    return mHeadList.size();
  }
  public void addData(int position) {
    mBodyList.add(position, "Insert One");
//    ★★★★ 使用notifyItemInserted去更新数据,否则没有动画效果
    notifyItemInserted(position);
  }
  /**
   * 增加bodyList条目
   */
  public void addData() {
    mBodyList.add("1");
    mBodyList.add("2");
    mBodyList.add("3");
//    ★★★★ 使用notifyItemInserted去更新数据,否则没有动画效果
    notifyItemRangeInserted(0, 3);
  }
  /**
   * 删除bodyList条目
   */
  public void removeData(int position) {
//    经测试疯狂点击删除条目,会产生负数,导致越界异常
    if (!(position - getHeadCount() < 0)) {
//    ★★★★ 防止角标越界异常,要减去头布局数量,总之去数数吧
      mBodyList.remove(position - getHeadCount());
      notifyItemRemoved(position);
    }
  }
  /**
   * 头布局Holder
   */
  static class HeadHolder extends RecyclerView.ViewHolder {
    private TextView mTvHead;
    public HeadHolder(View itemView) {
      super(itemView);
      mTvHead = (TextView) itemView.findViewById(R.id.tv_head);
    }
  }
  /**
   * 身体布局Holder
   */
  static class BodyHolder extends RecyclerView.ViewHolder {
    private TextView mTvBody;
    public BodyHolder(View itemView) {
      super(itemView);
      mTvBody = (TextView) itemView.findViewById(R.id.tv_body);
    }
  }
  /**
   * 脚布局Holder
   */
  static class FootHolder extends RecyclerView.ViewHolder {
    private TextView mTvFoot;
    public FootHolder(View itemView) {
      super(itemView);
      mTvFoot = (TextView) itemView.findViewById(R.id.tv_foot);
    }
  }
}

item_body

item_head和item_foot类似就不粘贴了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/ll"
       android:layout_width="match_parent"
       android:layout_height="40dp"
       android:layout_marginRight="11px"
       android:layout_marginBottom="11px"
       android:background="@color/colorPrimary"
       android:orientation="vertical">
  <TextView
    android:id="@+id/tv_body"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:textSize="17sp"
    android:layout_gravity="center"
    android:text="Hello World!"/>
</LinearLayout>

以上所述是小编给大家介绍的Android 中RecyclerView多种item布局的写法(头布局+脚布局),希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • Android中RecyclerView点击Item设置事件

    在上一篇Android RecylerView入门教程中提到,RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件,这就需要开发者自己实现.博客最下面有Demo程序运行动画. 奉上Demo的Github链接. 在调研过程中,发现有同学修改RecyclerView源码来实现Item的点击监听,但认为这不是一个优雅的解决方案,最终决定在RecyclerView.ViewHolder上做文章. 思路是:因为ViewH

  • Android RecyclerView显示Item布局不一致解决办法

    RecyclerView显示Item布局不一致 在自定义RecyclerAdapter的时候,在重写onCreateViewHolder方法是使用了 @Override public H onCreateViewHolder(ViewGroup parent, int viewType) { View view=View.inflate(context,layoutId,null); return view; } 进行生成布局,结果发现生成的布局没有LayoutParams.以前自定义View的

  • android RecyclerView实现条目Item拖拽排序与滑动删除

    效果演示 需求和技术分析 RecyclerView Item拖拽排序::长按RecyclerView的Item或者触摸Item的某个按钮. RecyclerView Item滑动删除:RecyclerView Item滑动删除:RecyclerView的Item滑动删除. 实现方案与技术 利用ItemTouchHelper绑定RecyclerView.ItemTouchHelper.Callback来实现UI更新,并且实现动态控制是否开启拖拽功能和滑动删除功能. 实现步骤 继承抽象类ItemTo

  • android使用ItemDecoration给RecyclerView 添加水印

    前言 项目中有使用到水印效果,如下图所示.在实现过程中,最终选用ItemDecoration来实现,其中有两大步骤:自定义Drawable来完成水印图片.使用ItemDecoration来布局水印. Demo在 WatermarkFragment 中,效果图如下: 1. 自定义Drawable完成水印图片 public class MyDrawable extends Drawable { Paint mPaint; public MyDrawable() { mPaint = new Pain

  • Android RecyclerView的Item点击事件实现整理

    自从开始使用RecyclerView代替ListView,会发现有很多地方需要学习.前一段时间的学习记录有: RecyclerView的滚动事件研究 - DevWiki RecyclerView的ViewHolder和Adapter的封装优化 - DevWiki RecyclerView问题记录 - DevWiki 实现 RecyclerView的Item的点击事件有三种方式: 在创建 ItemView时添加点击监听 当 ItemView attach RecyclerView时实现 通过Rec

  • Android RecyclerView的Item自定义动画及DefaultItemAnimator源码分析

    这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默认会使用DefaultItemAnimator,所以如果我们需要自定义动画,那么应该好好的读读这个类的源代码,这样不仅仅是学习怎么自定义,还要学习Android的设计模式. 先弄明白一件事,DefaultItemAnimator继承自SimpleItemAnimator,SimpleItemAnim

  • Android中RecyclerView的item宽高问题详解

    前言 本文主要给大家介绍了关于Android中RecyclerView的item宽高问题的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在创建viewholder传入的View时,如果不指定其viewgroup,就会出现宽高只包裹显示内容的问题. View view = LayoutInflater.from(context).inflate(R.layout.test_test,null); 上面的做法就会出问题 改成这样就可以正常显示设置的宽高 View vie

  • Android RecyclerView选择多个item的实现代码

    模仿网易新闻客户端阅读偏好的频道选择,先看实现的页面: 直接上代码: import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import an

  • Android 中RecyclerView多种item布局的写法(头布局+脚布局)

    RecyclerView多个item布局的写法(头布局+脚布局) 上图 github 下载源码 Initial commit第一次提交的代码,为本文内容 以下的为主要代码,看注释即可,比较简单 MainActivity 含上拉加载更多 package com.anew.recyclerviewall; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivi

  • Android中RecyclerView实现Item添加和删除的代码示例

    本文介绍了Android中RecyclerView实现Item添加和删除的代码示例,分享给大家,具体如下: 先上效果图: RecyclerView简介: RecyclerView用以下两种方式简化了数据的展示和处理: 1. 使用LayoutManager来确定每一个item的排列方式. 2. 为增加和删除项目提供默认的动画效果,也可以自定义. RecyclerView项目结构如下: Adapter:使用RecyclerView之前,你需要一个继承自RecyclerView.Adapter的适配器

  • Android中RecyclerView拖拽、侧删功能的实现代码

    废话不多说,下面展示一下效果. 这是GridView主文件实现. public class GridViewActivity extends AppCompatActivity { RecyclerView mRecyclerView; List<String> mStringList; RecyclerAdapter mRecyAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { s

  • Android 中RecyclerView通用适配器的实现

    Android 中RecyclerView通用适配器的实现 前言: SDK的5.0版本出来已经N久了,可以说是已经经过许多人的检验了,里面的新控件不能说是非常完美,但也是非常好用了,其中最让我喜爱的就是RecyclerView了,可以完美替代ListView和GridView(除了添加headerview和footview了,网上有许多解决方式.这个下面会以一种简单的方式顺带解决,肯定为大家省心),而且可以代码动态切换这两种布局方式以及瀑布流布局.相关切换方式网上有很多,大家自行搜索,我就不贴连

  • Android中recyclerView底部添加透明渐变效果

    前言 最近实现一个recyclerView透明渐变的效果,遇到了一些坑,尝试了一些方法,这里记录一下. 效果图 图片在上面显示2列,文字在下面显示1列:底部要有个透明渐变的效果,直到完全看不到. gridLayoutManager动态设置列数 大概是分两类,一类以图片为item 一行2个,一类以文字为item 一行一个. 这个第一反应是用viewType去区分图片类型,但是由于起初不知道gridLayout可以动态列数.就在上面两列,下面一列上为难起来了. 如果统一用一列吧,那就把两个image

  • Android 中RecyclerView顶部刷新实现详解

    Android 中RecyclerView顶部刷新实现详解 1. RecyclerView顶部刷新的原理 RecyclerView顶部刷新的实现通常都是在RecyclerView外部再包裹一层布局.在这个外层布局中,还包含一个自定义的View,作为顶部刷新时的指示View.也就是说,外层布局中包含两个child,一个顶部刷新View,一个RecyclerView,顶部刷新View默认是隐藏不可见的.在外层布局中对滑动事件进行处理,当RecyclerView滑动到顶部并继续下滑的时候,根据滑动的距

  • Android中RecyclerView实现横向滑动代码

    RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好.本文给大家介绍Android中RecyclerView实现横向滑动代码,一起看看吧. android.support.v7.widget.RecyclerView 功能:RecyclerView横向滑动 控件:<android.support.v7.widget.RecyclerView /> Java类:RecyclerView.GalleryAdap

  • Android中ListView的item点击没有反应的解决方法

    如果stu_item.xml里面包括button或者checkbox等控件,默认情况下list的item会失去焦点,导致无法响应item的事件,最常用的解决办法是在stu_item.xml的布局文件中设置descendantFocusability属性. 该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系. 属性的值有三种: beforeDescendants:viewgroup会优先其子类控件而获取到焦点 afterDescendants:viewgroup只有

随机推荐