简介
UltimateRecyclerView 是一个 RecyclerView(Android中ListView的高级灵活版),具有刷新、加载更多、动画等多种功能。
功能
- 滑动刷新
- 多种动画
- 滑动关闭
- 视差或正常头部视图
- 拖放项目
- 到达最后一项时加载更多(无限滚动)
- 加载更多的自定义视图
- 滚动时显示或隐藏工具栏和浮动按钮
- 滚动条
- 多彩风格的刷卡刷新
- 像 instagram 这样的粘性标题
- 支持适配器中的不同布局
- 加载带有动画的适配器
- recyclerview 中的可扩展视图
效果图
使用
1. 添加依赖
repositories {
jcenter()
}
dependencies {
...
implementation 'com.marshalchen.ultimaterecyclerview:library:0.9.0'
}
2. 布局文件
- main_activity.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.qmuiteam.qmui.widget.QMUITopBar
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="60dp"
app:qmui_topbar_title_bold="true"
app:qmui_topbar_title_color="@color/white"
android:background="@color/app_color_theme_8"
tools:ignore="MissingConstraints" />
<com.marshalchen.ultimaterecyclerview.UltimateRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:recyclerviewClipToPadding="true"
app:recyclerviewDefaultSwipeColor="@array/google_colors"
app:recyclerviewFloatingActionView="@layout/floating_view"
app:recyclerviewScrollbars="vertical" />
</androidx.constraintlayout.widget.ConstraintLayout>
- exp_parent.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@id/exp_section_ripple_wrapper_click"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="0dp"
android:background="@color/teal_200"
android:padding="0dp">
<RelativeLayout
android:id="@id/exp_section_adjustment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:clickable="false"
android:focusable="false"
android:padding="0dp">
<!-- android:foreground="?android:attr/selectableItemBackground"
-->
<TextView
android:id="@id/exp_section_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/exp_section_notification_number"
android:layout_toStartOf="@id/exp_section_notification_number"
android:gravity="left"
android:lines="1"
android:text="sample menu item parent"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="@android:color/black"
android:textSize="16sp"
tools:ignore="RtlCompat" />
<TextView
android:id="@id/exp_section_notification_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/exp_indication_arrow"
android:elegantTextHeight="false"
android:gravity="center_horizontal"
android:maxLength="5"
android:singleLine="true"
android:text="(99)"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="12sp"
android:textStyle="bold" />
<ImageView
android:id="@id/exp_indication_arrow"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="16sp"
android:scaleType="fitCenter"
android:src="@mipmap/ic_item_swipe_right" />
</RelativeLayout>
</RelativeLayout>
- exp_child.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@id/exp_section_ripple_wrapper_click"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="0dp"
android:padding="0dp">
<RelativeLayout
android:id="@id/exp_section_adjustment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:clickable="false"
android:focusable="false"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="0dp">
<TextView
android:id="@id/exp_section_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:lines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="@android:color/black"
android:textSize="12sp" />
</RelativeLayout>
</RelativeLayout>
3. Bean 类
- Category.java
public class Category extends easyTemplateParent<SmartItem, RelativeLayout, TextView> {
public Category(View itemView) {
super(itemView);
}
}
- SubCategory.java
public class SubCategory extends easyTemplateChild<SmartItem, TextView, RelativeLayout> {
public SubCategory(View itemView) {
super(itemView);
}
}
4. 适配器
public class ExpCustomAdapter extends customizedAdapter<Category, SubCategory> {
public ExpCustomAdapter(Context context) {
super(context);
}
public static List<SmartItem> getPreCodeMenu(String[] a, String[] b, String[] c) {
List<SmartItem> e = new ArrayList<>();
e.add(SmartItem.parent("世界名著", "open", DataUtil.getSmallList(a)));
e.add(SmartItem.parent("推荐书籍", "open", DataUtil.getSmallList(b)));
e.add(SmartItem.parent("体育明星", "open", DataUtil.getSmallList(c)));
return e;
}
/**
* please do work on this id the custom object is true
*
* @param parentview the inflated view
* @return the actual parent holder
*/
protected Category iniCustomParentHolder(View parentview) {
return new Category(parentview);
}
/**
* please do work on this if the custom object is true
*
* @param childview the inflated view
* @return the actual child holder
*/
protected SubCategory iniCustomChildHolder(View childview) {
return new SubCategory(childview);
}
protected int getLayoutResParent() {
return R.layout.exp_parent;
}
protected int getLayoutResChild() {
return R.layout.exp_child;
}
protected List<SmartItem> getChildrenByPath(String path, int depth, int position) {
return null;
}
public RecyclerView.ViewHolder newFooterHolder(View view) {
return new UltimateRecyclerviewViewHolder(view);
}
public RecyclerView.ViewHolder newHeaderHolder(View view) {
return new UltimateRecyclerviewViewHolder(view);
}
}
5. MainActivity.java
public class MainActivity extends AppCompatActivity {
private static String[] sampledatagroup1 = {
"《论语》", "http://google",
"《三国演义》", "http://google",
"《红与黑》", "http://google",
"《老人与海》", "http://google"
};
private static String[] sampledatagroup2 = {
"《第一行代码》", "http://google",
"《代码整洁之道》", "http://google",
"《重构》", "http://google",
"《程序员的职业素养》", "http://google",
"《如何阅读》", "http://google"
};
private static String[] sampledatagroup3 = {
"科比", "http://google",
"C罗", "http://google",
"林丹", "http://google",
"刘德华", "http://google",
"周杰伦", "http://google"
};
(R.id.recycler_view)
UltimateRecyclerView mRecyclerView;
(R.id.topbar)
QMUITopBar mTopBar;
private ExpCustomAdapter simpleRecyclerViewAdapter = null;
private LinearLayoutManager linearLayoutManager;
private ActionMode actionMode;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
}
private void initView() {
mTopBar.setTitle("二级列表");
mTopBar.addLeftBackImageButton().setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
mRecyclerView.setHasFixedSize(false);
simpleRecyclerViewAdapter = new ExpCustomAdapter(this);
simpleRecyclerViewAdapter.addAll(ExpCustomAdapter.getPreCodeMenu(sampledatagroup1, sampledatagroup2, sampledatagroup3), 0);
linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setAdapter(simpleRecyclerViewAdapter);
mRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#ffffff"));
addExpandableFeatures();
}
private void addExpandableFeatures() {
mRecyclerView.getItemAnimator().setAddDuration(100);
mRecyclerView.getItemAnimator().setRemoveDuration(100);
mRecyclerView.getItemAnimator().setMoveDuration(200);
mRecyclerView.getItemAnimator().setChangeDuration(100);
}
}