1、概述
RecyclerView的出现让我们在实现列表的横竖向展示、网格布局、瀑布流等样式得以简化。RecyclerView提供了一种插拔式的体验,在实现各种展示和样式的时候更加的高效。
1.1 LayoutManager
RecyclerView的内部类,实现线性布局(横竖都行)、网格布局。
可以通过RecyclerView的setLayoutManager(LayoutManager layout)方法来设置
1.2 ItemDecoration
RecyclerView的内部类,可以绘item的制分割线,可以自定各种样式的分割线。
可以通过RecyclerView的addItemDecoration(ItemDecoration decor)方法来设置。
1.3 ItemAnimator
RecyclerView的内部类,给item添加动画。
可以通过RecyclerView的setItemAnimator(ItemAnimator animator)来设置
2、示例需求
实现如下图的布局
也就是简单的网格布局,加上图片周边的分割线,这里在Fragment中使用RecyclerView来实现,图片的数据来源是写了个爬虫从网上爬的图片地址,然后记录图片url的文件放入assets目录下,通过方法读取出来;
下面一步步来实现:
1)RecyclerView的引入
使用RecyclerView需要导入support-v7的包,build.gradle文件中导入依赖
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:recyclerview-v7:26.1.0'
}
2)布局文件,一个是整体的Fragment的layout,一个是RecyclerView的adapter的item使用的layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_ly"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recyler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/beige">
<ImageView
android:id="@+id/ivImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:src="@drawable/image_default"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>
</LinearLayout>
3)代码实现,重点看initView 方法中对于RecyclerView的使用
fragment的代码:
public class FragmentOne extends BaseFragment implements View.OnClickListener {
private View mRootView;
private SwipeRefreshLayout mSwipeLayout;
private RecyclerView mRecyclerView;
private PhotoAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = inflater.inflate(R.layout.layout_fragment_mm, container, false);
initView(mRootView);
loadData();
}
return mRootView;
}
private void initView(View rootView) {
initPullToFresh(rootView);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.main_recyler_view);
mRecyclerView.setHasFixedSize(true);
//添加默认的动画(看起来似乎没什么特别的效果)
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
//添加竖向分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
//添加横向分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.HORIZONTAL));
adapter = new PhotoAdapter(new PhotoAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClickListener(View v, int position) {
ArrayList<String> total = getData();
ArrayList<String> gallery = new ArrayList<>();
for(int i = position; i< position + 100 && position + 100 <= total.size(); i++) {
gallery.add(total.get(i));
}
ImagePreviewActivity.startActivity(getActivity(), gallery.get(0), gallery);
}
});
mRecyclerView.setAdapter(adapter);
}
private ArrayList<String> getData() {
return getFromAssets("girl.txt");
}
public ArrayList<String> getFromAssets(String fileName) {
ArrayList<String> urls = new ArrayList<>();
try {
InputStream in = getActivity().getAssets().open(fileName);
InputStreamReader inputReader = new InputStreamReader(in, "UTF-8");
BufferedReader bufReader = new BufferedReader(inputReader);
String line = "";
while ((line = bufReader.readLine()) != null)
if (!TextUtils.isEmpty(line.trim())) {
urls.add(line.trim());
}
} catch (Exception e) {
e.printStackTrace();
return urls;
}
return urls;
}
private void initPullToFresh(View rootView) {
mSwipeLayout = rootView.findViewById(R.id.swipe_ly);
mSwipeLayout.setColorSchemeResources(R.color.theme_color);
mSwipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
adapter.replaceAll(getData());
hideProgressDialog();
}
});
mHandler.sendEmptyMessage(REFRESH_LIST);
}
private void loadData() {
showProgressDialog();
adapter.replaceAll(getData());
hideProgressDialog();
}
@Override
public void onClick(View v) {
}
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
private void showProgressDialog() {
if (mSwipeLayout != null) {
mSwipeLayout.setRefreshing(true);
}
}
private void hideProgressDialog() {
if (mSwipeLayout != null && mSwipeLayout.isRefreshing()) {
mSwipeLayout.setRefreshing(false);
}
}
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case REFRESH_LIST:
if (mSwipeLayout.isRefreshing()) {
mSwipeLayout.setRefreshing(false);
}
break;
}
}
;
};
}
下面主要看initView中的部分代码,来看RecyclerView怎么使用
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.main_recyler_view);
mRecyclerView.setHasFixedSize(true);
//添加默认的动画(看起来似乎没什么特别的效果)
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
//添加竖向分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
//添加横向分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.HORIZONTAL));
adapter = new PhotoAdapter(new PhotoAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClickListener(View v, int position) {
ArrayList<String> total = getData();
ArrayList<String> gallery = new ArrayList<>();
for(int i = position; i< position + 100 && position + 100 <= total.size(); i++) {
gallery.add(total.get(i));
}
ImagePreviewActivity.startActivity(getActivity(), gallery.get(0), gallery);
}
});
mRecyclerView.setAdapter(adapter);
1)布局管理器
在获取到RecyclerView的实例之后,我们一定设置布局管理器,也就是LayoutManager,否则页面时展示不出来的:
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
这里使用了网格布局,如果是线性的使用LinearLayoutManager
2)设置动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
3)设置分割线
添加竖向分割线:mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
添加横向分割线:mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.HORIZONTAL));
当然如果是线性布局只需要二选一,视情况而定
4)然后就是adapter
dapter = new PhotoAdapter(new PhotoAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClickListener(View v, int position) {
ArrayList<String> total = getData();
ArrayList<String> gallery = new ArrayList<>();
for(int i = position; i< position + 100 && position + 100 <= total.size(); i++) {
gallery.add(total.get(i));
}
ImagePreviewActivity.startActivity(getActivity(), gallery.get(0), gallery);
}
});
mRecyclerView.setAdapter(adapter);
5)item的点击事件,在adapter中定义了一个接口,通过其构造函数传入实现,adapter的代码如下:
public class PhotoAdapter extends RecyclerView.Adapter<BaseViewHolder> {
public interface OnRecyclerViewItemClickListener {
void onItemClickListener(View v, int position);
}
private ArrayList<String> dataList = new ArrayList<>();
private OnRecyclerViewItemClickListener mItemClickListener;
public PhotoAdapter(OnRecyclerViewItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
}
public void replaceAll(ArrayList<String> list) {
dataList.clear();
if (list != null && list.size() > 0) {
dataList.addAll(list);
}
notifyDataSetChanged();
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_one, parent, false);
OneViewHolder viewHolder = new OneViewHolder(layout);
return viewHolder;
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.setData(position);
}
@Override
public int getItemCount() {
return dataList != null ? dataList.size() : 0;
}
private class OneViewHolder extends BaseViewHolder {
private ImageView ivImage;
public OneViewHolder(View view) {
super(view);
ivImage = (ImageView) view.findViewById(R.id.ivImage);
int width = ((Activity) ivImage.getContext()).getWindowManager().getDefaultDisplay().getWidth();
ViewGroup.LayoutParams params = ivImage.getLayoutParams();
//设置图片的相对于屏幕的宽高比
params.width = width / 3;
params.height = params.width * 4 / 3;
ivImage.setLayoutParams(params);
}
@Override
void setData(final int position) {
String dataStr = dataList.get(position);
if (!TextUtils.isEmpty(dataStr)) {
ImageLoadUtils.bindImage(itemView.getContext(), ivImage, dataStr);
}
ivImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mItemClickListener.onItemClickListener(ivImage, position);
}
});
}
}
}
public class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
}
void setData(int position) {
}
}
以上是大致使用RecyclerView实现一个网格布局的图片展示页面,有完整可运行git项目地址如下,可以直接使用构建自己的应用,
https://github.com/cmyeyi/smm.git