Android 中RecyclerView多种item布局的写法(头布局+脚布局)
程序员文章站
2024-02-23 15:13:58
recyclerview多个item布局的写法(头布局+脚布局)
上图
github
下载源码
initial commit第一次提交的代码,为本文内容...
recyclerview多个item布局的写法(头布局+脚布局)
上图
下载源码
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布局的写法(头布局+脚布局),希望对大家有所帮助