RecyclerView(1)简单使用

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

 

 

 

猜你喜欢

转载自blog.csdn.net/weixin_36709064/article/details/82055903