【RecyclerView与Glide】实现一个Android电子书阅读APP
http://www.cnblogs.com/xfangs/
欢迎在本文下方评论,小方很需要鼓励支持!!!
本系列教程仅供学习交流
前言
在上一篇文章中,我们实现了ViewPager的基本功能,按照计划,制作咱们的电子书阅读app需要使用ViewPager插入两页视图,一个用来显示当前书架,一个用来展示不同的分类。这一节,我们将在被标记为find的页面上实现分类选项。
涉及组件或框架:RecyclerView、Glide
首先·布局
同样的,在这里,小方因为水平有限只能简单介绍RecyclerView的基本使用方法,涉及到更深奥的操作部分,就无能为力了。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView
android:id="@+id/recyler_view_find_book"
android:layout_margin="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </LinearLayout>
没有复杂的步骤,我们只需要把RecyclerView加入到之前ViewPager的两个布局之一中,就完成了整个列表布局。
当然,你也许会遇到一些意外。
这是说明我们还没有引入RecyclerView这个库,进入Design界面,从左边的组件中找到RecyclerView,单击,将会弹出选择框。
在加入了库之后,我们就能看到RecyclerView正确无误的显示在界面上了。
适配器
这次我们工作的主战场在上一节提到的Fragment,也就是ViewPager的两个页面之一。
回顾一下代码。
public static class FindBooksFragment extends Fragment { public FindBooksFragment() {
} @Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.pager_book_find, container, false); return rootView;
} }
之前说了,ViewPager会在创建这个页面的时候调用onCreateView这个函数,所以我们在这里进行初始化操作。
在这之前,我们需要先完成RecyclerView的适配器,同样的,这里适配器起到将数据和页面结合到一起的作用,具体地说,假设一个列表中的项目可以分为三类,我们就为这三类元素分别设计布局,然后将每一项的数据传给适配器,适配器可以根据数据选择对应的布局,然后把每一项显示出来。
首先,新建一个类。
关于RecyclerView的适配器,网络上已经有很多博客描述了, 随意找一篇看的过去的文章,先大体了解一下。
。。。搜索时间。。。
了解过后,我们知道需要为列表项写布局,这在前面也间接提到了。
那么,新建一个布局文件
book_find_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bookFind_cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"> <ImageView
android:id="@+id/bookFind_image"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
tools:src="@color/cardview_dark_background"/> <TextView
android:id="@+id/bookFind_class"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:textColor="#FFFFFF"
android:textStyle="normal|bold"
android:textSize="14sp"
android:gravity="center"
tools:text="123"/> </android.support.v7.widget.CardView>
在这里,我们又使用了一个新的组件,CardView,它体现了安卓最新设计风格,恰到好处的圆角、逼真的阴影、点击特效、等等,有多种属性可供调整。
尤其要说的是上面代码中加粗的字体,一个新的命名空间 tools ,在使用它之前,我们首先要在最外层的部件上声明。
只要打出前面几个字母,android studio 就会自动补全好。
tools 命名空间提供了测试的效果,以他为名号的属性在程序运行期间是被忽略的,只供测试预览使用,使得开发更加方便了。下图就是我们预览时得到的效果,
当程序运行起来时, 还会是如图所示的样子吗?
(必然不是)
制作好了布局文件,我们就可以开始对适配器进行编写了。
首先制作一个接口,用来获取点击事件。
private OnItemClickListener listener; public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
} public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
然后在适配器的类中再新建一个类。
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
View tocView;
private TextView textview_bookFindClass;
private ImageView imageView;
private OnItemClickListener listener; public ViewHolder(View itemView, OnItemClickListener l) {
super(itemView);
tocView = itemView;
textview_bookFindClass = (TextView) itemView.findViewById(R.id.bookFind_class);
imageView = (ImageView) itemView.findViewById(R.id.bookFind_image);
listener = l;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
} @Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(v, getAdapterPosition());
}
} @Override
public boolean onLongClick(View v) {
if (listener != null) {
listener.onItemLongClick(v, getAdapterPosition());
}
return false;
}
}
可能略显复杂,这个类的作用是缓存列表项,具体比较低层的东西小方就不太清楚了,上网搜了搜,就不现学现卖了,欢迎有兴趣的同学一起讨论。
ViewHolder 类继承自 RecyclerView.ViewHolder,为了实现点击监听,还要接入两个接口,一个是单击的接口,一个是长按的接口。
从构造函数开始一点一点理解,构造函数接收两个参数,一个是每一项的View,一个是每一项的点击监听器。初始化组件之后,设置监听器,按照之前设置的接口的设定,将View和位置传给借口。
如果还不是很清楚,那么先将代码复制过去,使用次数多了,自然就理解了。
然后,在AdapterBookFind这个类中,完成它的构造函数,这里是根据需要自行设定的,在这里我们需要将分类名称传给适配器,显示在每一项上,所以传送了一个字符串列表。你也可以根据自己的需要传送想要传送的数据。
private ArrayList<String> myCategory; public AdapterBookFind(ArrayList<String> category) {
this.myCategory = category;
}
下面我们需要重写一个函数,用来获取一个ViewHolder的实例。
private Context context;
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.book_find_item, parent, false);
context = parent.getContext();
final ViewHolder holder = new ViewHolder(view, listener); return holder;
}
在这里,我们又声明了一个叫做context的变量,并初始化,具体作用后面再表。
@Override
public int getItemCount() {
return myCategory.size();
}
类似ViewPager的适配器一样,我们同样需要重写取数目的函数,根据数据返回一个值。
马上就到最后一步了,我们将要对列表的每一项设置不同的内容。
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.textview_bookFindClass.setText(myCategory.get(position));
switch (position) {
case 0:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 1:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 2:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 3:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 4:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 5:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 6:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
case 7:
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
break;
default: break;
}
holder.imageView.setColorFilter(Color.parseColor("#55555555")); }
因为我们的布局文件中只有两个组件能体现数据的内容,TextView和ImageView。
第三行是根据不同的位置选择不同的字符串进行设置,没有难度。
在说switch之前,我们先来看最后一行
holder.imageView.setColorFilter(Color.parseColor("#55555555"));
给imageView设置滤色,因为我想要在图片之上显示一个白色的文字,适当的使图片变暗,能凸显文字。
switch当然也能看得懂,但是出现了一个陌生的东西 Glide。
实际不难理解,这个switch的作用还是根据不同的位置选择不同的文件进行显示,我们当然可以使用ImageView自带的方法来设置图片,但是ImageView只能设置本地或者APK之中的图片资源,对于网络图片或者诸多不支持的图片类型(如GIF)就毫无办法,不仅如此,当本地图片较大时,还会不可避免的出现卡顿现象。
这时候Glide出现了,它能快速加载各种图片,根据显示大小自动对图片进行压缩,同样一条语句,如果传入图片链接还能加载网络图片,并缓存。
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
如上面代码所示的一句话,就能加载APK资源中的一张图片,这里我们只有图标一个文件,所以将图标文件传给了imageView。
不过如果你只是把刚刚的代码复制粘贴到你的工程,你的程序应该会报错,显示没有找到Glide这个东西,这是因为Glide不是官方提供的,我们需要手动引入。
找到上面那个文件。
加入最后一行,选择同步。
这样,我们就引入了Glide。
整合
public static class FindBooksFragment extends Fragment { public FindBooksFragment() {
} private RecyclerView recyclerView;
private StaggeredGridLayoutManager staggeredGridLayoutManager;
private AdapterBookFind bookAdapterBookFind; @Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { final ArrayList<String> bookClass = new ArrayList<>();
bookClass.add("//玄幻");
bookClass.add("//武侠");
bookClass.add("//都市");
bookClass.add("//历史");
bookClass.add("//游戏");
bookClass.add("//科幻");
bookClass.add("//女生");
bookClass.add("//所有"); View rootView = inflater.inflate(R.layout.pager_book_find, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyler_view_find_book); staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
bookAdapterBookFind = new AdapterBookFind(bookClass);
recyclerView.setAdapter(bookAdapterBookFind); bookAdapterBookFind.setOnItemClickListener(new AdapterBookFind.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e(TAG, "onItemClick: 111" );
} @Override
public void onItemLongClick(View view, int position) {
Log.e(TAG, "onItemLongClick: 222" );
}
}); return rootView;
} private static final String TAG = "FindBooksFragment";
}
首先初始化我们的字符串列表。StaggeredGridLayoutManager是我们列表的布局管理器,安卓提供了三种布局管理器,用来实现不同的列表效果,多行列表,瀑布流列表,不同的滑动方向都可以进行设置,大家可以百度其他的布局管理器。
所以在27-30行,我们分别为RecyclerView设置了列表管理器和适配器,32行开始,为适配器设置点击监听器,咱们暂时不设置功能,使用log工具将其输出在Android Monitor(log语句有快捷键)。
效果
运行程序,你将见到
我们又完成了新的一节,现在可以尝试更换不同的图片,尝试使用网络图片(不要忘记加入网络访问权限)。
未完待续...下一篇文章讲述使用 litePal 完成书架,敬请期待!!!
【RecyclerView与Glide】实现一个Android电子书阅读APP的更多相关文章
- [前言] 实现一个Android电子书阅读APP
大家好,我是小方,我将在接下来的几篇文章中从零实现一个网络小说阅读器,从安卓编程最基础的部分讲起,直至成功完成我们的应用,从新建一个项目开始,不断添加新的代码,添加新的界面,循序渐进,涵盖所有我们需要 ...
- 【新建项目&使用viewPager】实现一个Android电子书阅读APP
本章结尾处已放出应用DEMO,已经实现所有本文及后续文章所述全部功能,大家可以先下载下来玩玩看,欢迎在本文下方评论,小方很需要鼓励支持!!! 新建一个项目 呼-我们即将步入安卓开发之旅了,首先要新建一 ...
- 使用 Vue 和 epub.js 制作电子书阅读器
ePub 简介 ePub 是一种电子书的标准格式,平时我看的电子书大部分是这种格式.在手机上我一般用"多看"阅读 ePub 电子书,在 Windows 上找不到用起来比较顺心的软件 ...
- 分分钟教你做出自己的新闻阅读APP
分分钟教你做出自己的新闻阅读APP 引子 曾经不小心发现了一些好的看新闻的网站,但是电脑又不是随身携带,因此想要下载一个这个网站的手机APP来看新闻,但是问题来了,这个网站根本没有做Android端! ...
- Android RecyclerView利用Glide加载大量图片into(Target)导致OOM异常
学过android的人应该都知道Glide是一个无比强大的图片加载库,它内部已经提供了很好的缓存机制供我们选择,我们只需一个参数调用即可(DiskCacheStrategy()),而不必像Univer ...
- 第一行代码阅读笔记---详解分析第一个Android程序
以下是我根据作者的思路,创建的第一个Android应用程序,由于工具强大,代码都自动生成了,如下: package com.example.first_app; import android.os.B ...
- 基于React实现的【绿色版电子书阅读器】,支持离线下载
代码地址如下:http://www.demodashi.com/demo/12052.html MyReader 绿色版电子书阅读器 在线地址:http://myreader.linxins.com ...
- android电子书App、自定义图表、仿腾讯漫画App、仿淘宝优惠券、3D选择容器等源码
Android精选源码 仿支付宝记账本功能,饼状图:数字键盘 android一款功能完善的电子书应用源码 Android自定义图标库,使用方便,扩展性强 android 3D立体无限旋转容器源码 an ...
- 2020互联网寒冬之下,作为一个Android老码农,是如何进入腾讯的?
由于众所周知的原因,原生Android开发如今已经日渐凋敝,作为一个Android程序员,不仅要会Java,Kotlin,JavaScript,Css,Html,还要会Flutter,C++,FFmp ...
随机推荐
- Android中支持的距离单位
px(像素):每个px对应屏幕上的一个点 dip或dp(device independent pixels,设备独立像素):一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dip=1px.但 ...
- HTML 颜色名
目前所有浏览器都支持以下颜色名. 141个颜色名称是在HTML和CSS颜色规范定义的(17标准颜色,再加124).下表列出了所有颜色的值,包括十六进制值. 提示: 17标准颜色:黑色,蓝色,水,紫红 ...
- C#如何给PDF文档添加注释
整理文档时,我们可能会需要在一些或一段文字上添加注释加以说明,那如何以编程的方式实现呢?本文将实例讲述C#中如何使用免费组件给PDF文档添加文本注释,包括自由文本注释.自由文本注释能允许我们自定义它的 ...
- Unable to find setter method for attribute: 属性名
tld文件里面的名称和标签内的属性名要一致.
- java7 invokedynamic命令深入研究
在看java虚拟机字节码执行引擎的时候,里面提到了java虚拟机里调用方法的字节码指令有5种: invokestatic //调用静态方法 invokespecial //调用私有方法.实例构造器方法 ...
- ArcGIS 网络分析[1] 介绍与博文目录【更新中】
网络分析是个热点,理论上是属于计算机图形学和数据结构的,GIS以此为基础做出应用. 以下列举本人在学习中遇到的网络分析问题与经验总结. 平台:Windows 10操作系统,ArcGIS for Des ...
- (@WhiteTaken)设计模式学习——单例模式
单例模式,个人理解就是,使用了这个模式,可以保证一个类只生成唯一的实例对象.就是在整个程序中,这个类只存在一个实例对象. GoF对单例模式的定义:保证一个类,只有一个实例存在,同时提供能对该实例加以访 ...
- 详解Google Chrome浏览器(操作篇)(一)
开篇概述 在上篇博客中详解Google Chrome浏览器(理论篇)一文中,主要讲解了Chrome 搜索引擎使用.Chrome安装和基本操作.Chrome 基本架构.多线程等原理性问题,这篇将重点讲解 ...
- 随机生成并排序 C,去同,有序数组合并排序
#include<iostream> #include<stdlib.h> #include<time.h> using namespace std; int ma ...
- linux 下安装eclipse和pydev插件用来开发python程序
1.网上的教程要求必须要安装java虚拟机,但是我觉得不用,但是为了不出意外就装吧. (1)去官网下载安装包www.sun.com (2)安装包是.tar.gz的可以用 tar -xzvf +压缩包路 ...