【转载】最好用的通用adapter——BaseQuickAdpater详解(1)

helper.setText(R.id.student_name,item.getName())

.setText(R.id.student_age,item.getAge()+“”)

.setText(R.id.student_address,item.getAddress())

.addOnClickListener(R.id.student_icon)

.addOnClickListener(R.id.student_name)

.addOnLongClickListener(R.id.student_address);

Glide.with(mcontext).load(item.getIcon()).into((ImageView) helper.getView(R.id.student_icon));

}

然后在设置子控件点击事件

adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {

@Override

public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {

switch (view.getId()) {

case R.id.student_icon:

//获取其他控件,如下,获取student_name

TextView textView=(TextView) adapter.getViewByPosition(recycleview, position, R.id.student_name);

Toast.makeText(CommonAdapterActivity.this, “点击”+textView.getText().toString()+“的头像”, Toast.LENGTH_SHORT).show();

break;

case R.id.student_name:

Toast.makeText(CommonAdapterActivity.this, “点击了名字”, Toast.LENGTH_SHORT).show();

break;

}

}

});

然后在设置子控件长按事件

adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {

@Override

public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {

if (view.getId() == R.id.student_address)

Toast.makeText(CommonAdapterActivity.this, “长按了address”, Toast.LENGTH_SHORT).show();

return false;

}

});

注意:设置子控件的事件,如果不在adapter中绑定,点击事件无法生效,因为无法找到你需要设置的控件。

如果需要获取item中其他控件,上述代码有表现, adapter.getViewByPosition()方法进行初始化

TextView textView=(TextView) adapter.getViewByPosition(recycleview, position, R.id.student_name);

ps:如果有header的话需要处理一下position加上 headerlayoutcount。即如果header有的话,postion的点击postion实际上为postion+headerlayoutcount.

动画


开启动画(默认为渐显效果)

adapter.openLoadAnimation();

默认提供5种方法(渐显、缩放、从下到上,从左到右、从右到左)

public static final int ALPHAIN = 0x00000001;

public static final int SCALEIN = 0x00000002;

public static final int SLIDEIN_BOTTOM = 0x00000003;

public static final int SLIDEIN_LEFT = 0x00000004;

public static final int SLIDEIN_RIGHT = 0x00000005;

切换动画

quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);

自定义动画

quickAdapter.openLoadAnimation(new BaseAnimation() {

@Override

public Animator[] getAnimators(View view) {

return new Animator[]{

ObjectAnimator.ofFloat(view, “scaleY”, 1, 1.1f, 1),

ObjectAnimator.ofFloat(view, “scaleX”, 1, 1.1f, 1)

};

}

});

动画默认只执行一次,如果想重复执行可设置

mQuickAdapter.isFirstOnly(false);

因为有些人不希望第一页看到动画,或者说希望前几个条目加载不需要有动画,所以可以

设置不显示动画数量

adapter.setNotDoAnimationCount(count);

添加头部、尾部


mQuickAdapter.addHeaderView(getView());

mQuickAdapter.addFooterView(getView());

删除指定view

mQuickAdapter.removeHeaderView(getView);

mQuickAdapter.removeFooterView(getView);

删除所有

mQuickAdapter.removeAllHeaderView();

mQuickAdapter.removeAllFooterView();

默认出现了头部就不会显示Empty,和尾部,配置以下方法也支持同时显示:

setHeaderAndEmpty

setHeaderFooterEmpty

默认头部尾部都是占满一行,如果需要不占满可以配置:

setHeaderViewAsFlow

setFooterViewAsFlow

加载更多


此adapter封装加载更多其实并不好用,因此我更建议采用传统的根据recyclerview判断item位置进行判断,自动加载更多

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

@Override

public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

super.onScrollStateChanged(recyclerView, newState);

lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

firstVisibleItem=linearLayoutManager.findFirstVisibleItemPosition();

if (newState == RecyclerView.SCROLL_STATE_IDLE&&linearLayoutManager.getItemCount() >0&&lastVisibleItem + 1 == linearLayoutManager.getItemCount()) {

new Handler().postDelayed(() -> loadData(),300) ;

}

}

@Override

public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

super.onScrolled(recyclerView, dx, dy);

lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

firstVisibleItem=linearLayoutManager.findFirstVisibleItemPosition();

}

});

LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();

屏幕中最后一个可见子项的position

int lastVisibleItem = layoutManager.findLastVisibleItemPosition();

//当前屏幕所看到的子项个数

layoutManager.getChildCount();

//当前RecyclerView的所有子项个数

layoutManager.getItemCount();

//RecyclerView的滑动状态

recyclerView.getScrollState();

如果想要预加载也很简单,只需要修改当前最下方item的postion和总条目之间的差值即可。

分组布局


此adapter分组布局,不是类似于那种黏性头部的分组,而是把头布局作为一个item进行多布局的封装。

头布局也支持点击事件,头布局内部的控件也支持点击事件。和普通布局一般无二。

把需要加头布局的实体类用一个新的实体类包裹起来,比如作者举例的Video,用MySection 包裹了Video,这样的MySection内部有两个构造方法,一个是头布局的构造方法,一个是实体类的构造方法,举例如下

public class MySection extends SectionEntity {

private boolean isMore;

public MySection(boolean isHeader, String header, boolean isMroe) {

super(isHeader, header);

this.isMore = isMroe;

}

public MySection(Video t) {

super(t);

}

public boolean isMore() {

return isMore;

}

public void setMore(boolean mroe) {

isMore = mroe;

}

}

你可以在构造方法中加上自己需要的字段来以便给头布局赋值;上述代码加入了一个ismore字段,用来判断是否有展开更多字段。

adapter需要实现BaseSectionQuickAdapter,convertHead用来绑定头布局数据,convert用来绑定一般数据。

public class SectionAdapter extends BaseSectionQuickAdapter<MySection, BaseViewHolder> {

public SectionAdapter(int layoutResId, int sectionHeadResId, List data) {

super(layoutResId, sectionHeadResId, data);

}

@Override

protected void convertHead(BaseViewHolder helper, final MySection item) {

helper.setText(R.id.header, item.header)

.setVisible(R.id.more, item.isMore())

.addOnClickListener(R.id.more);

}

@Override

protected void convert(BaseViewHolder helper, MySection item) {

Video video = (Video) item.t;

switch (helper.getLayoutPosition() %

  1. {

case 0:

helper.setImageResource(R.id.iv, R.mipmap.m_img1);

break;

case 1:

helper.setImageResource(R.id.iv, R.mipmap.m_img2);

break;

}

helper.setText(R.id.tv, video.getName());

}

}

当然数据初始化的时候要注意,同一头布局下的需要写在一起:

public static List getSampleData() {

List list = new ArrayList<>();

list.add(new MySection(true, “Section 1”, true));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(true, “Section 2”, false));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(true, “Section 3”, false));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(true, “Section 4”, false));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD)));

}

多布局


实体类必须实现MultiItemEntity,在设置数据的时候,需要给每一个数据设置itemType

public class MultipleItem implements MultiItemEntity {

public static final int TEXT = 1;

public static final int IMG = 2;

private int itemType;

public MultipleItem(int itemType) {

this.itemType = itemType;

}

@Override

public int getItemType() {

return itemType;

}

}

adapter需要继承BaseMultiItemQuickAdapter,addItemType用来绑定itemType和item布局。

public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter<MultipleItem, BaseViewHolder> {

public MultipleItemQuickAdapter(List data) {

super(data);

addItemType(1, R.layout.text_view);

addItemType(2, R.layout.image_view);

}

@Override

protected void convert(BaseViewHolder helper, MultipleItem item) {

switch (helper.getItemViewType()) {

case 1:

helper.setImageUrl(R.id.tv, item.getContent());

break;

case 2:

helper.setImageUrl(R.id.iv, item.getContent());

break;

}

}

}

设置空布局


mQuickAdapter.setEmptyView(getView());

添加拖拽、滑动删除


拖拽和滑动删除的回调方法

OnItemDragListener onItemDragListener = new OnItemDragListener() {

@Override

public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos){}

@Override

public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {}

@Override

public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {}

}

OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() {

@Override

public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {}

@Override

public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {}

@Override

public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {}

};

adapter需要继承BaseItemDraggableAdapter

public class ItemDragAdapter extends BaseItemDraggableAdapter<String, BaseViewHolder> {

public ItemDragAdapter(List data) {

super(R.layout.item_draggable_view, data);

}

@Override

protected void convert(BaseViewHolder helper, String item) {

helper.setText(R.id.tv, item);

}

}

Activity使用代码

mAdapter = new ItemDragAdapter(mData);

ItemDragAndSwipeCallback itemDragAndSwipeCallback = new ItemDragAndSwipeCallback(mAdapter);

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);

itemTouchHelper.attachToRecyclerView(mRecyclerView);

// 开启拖拽

mAdapter.enableDragItem(itemTouchHelper, R.id.textView, true);

mAdapter.setOnItemDragListener(onItemDragListener);

// 开启滑动删除

mAdapter.enableSwipeItem();

mAdapter.setOnItemSwipeListener(onItemSwipeListener);

默认不支持多个不同的 ViewType 之间进行拖拽,如果开发者有所需求:

重写ItemDragAndSwipeCallback里的onMove()方法,return true即可

树形列表


例子:三级菜单

// if you don’t want to extent a class, you can also use the interface IExpandable.

// AbstractExpandableItem is just a helper class.

public class Level0Item extends AbstractExpandableItem {…}

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!


《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
ner);

// 开启滑动删除

mAdapter.enableSwipeItem();

mAdapter.setOnItemSwipeListener(onItemSwipeListener);

默认不支持多个不同的 ViewType 之间进行拖拽,如果开发者有所需求:

重写ItemDragAndSwipeCallback里的onMove()方法,return true即可

树形列表


例子:三级菜单

// if you don’t want to extent a class, you can also use the interface IExpandable.

// AbstractExpandableItem is just a helper class.

public class Level0Item extends AbstractExpandableItem {…}

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

[外链图片转存中…(img-HL04WXWq-1714841936236)]

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

[外链图片转存中…(img-K9aKwi5r-1714841936236)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值