本文为学习类文档,通过学习B站up主longway777的视频,再加上自己的总结与理解的学习类文章,如有侵权,请联系博主进行删除
制作简易画廊,在第一个界面中显示缩略图,界面采用recyclerView呈现内容,整体布局使用GridLayoutManage(spanCount = 2)实现每行两个信息的布局,并采用ListAdapter进行驱动。LstAdapter中的数据使用ViewModel和LiveData提供。创建网络工具类,使用Pixabay网站的API通过Http请求方式获取数据,Http请求工具采用谷歌自家的Volley+Gson进行内容解析。由于Volley的使用不够便捷,在图片加载时使用Glide工具库,用户通过点击选择进入选择的图片(显示原图即分辨率很高的图)进行展示。二者界面通过navigation连接,并通过parcelable的序列化将数据传递。支持手势的放大缩小。
除此之外,还使用了ShimmerLayout、下拉刷新库swiperefreshlayout、图片放大缩小工具PhotoView(ImageView强化版)
Volley 概览
Volley 是一个可让 Android 应用更轻松、(最重要的是)更快捷地联网的 HTTP 库。您可以在 GitHub 上获取 Volley。
Volley 具有以下优势:
自动网络请求调度。
多个并发网络连接。
透明磁盘和具有标准 HTTP 缓存一致性的内存响应缓存。
支持请求优先级。
取消请求 API。您可以取消单个请求,也可以设置要取消的请求的时间段或范围。
可轻松自定义,例如自定义重试和退避时间。
强大的排序功能,让您可以轻松使用从网络异步提取的数据正确填充界面。
调试和跟踪工具。
Volley 在用于填充界面的远程过程调用 (RPC) 类型的操作方面表现出色,例如以结构化数据的形式获取搜索结果页面。它可以轻松集成任何协议,并且开箱后即支持原始字符串、图片和 JSON。Volley 提供对您所需功能的内置支持,因此您无需编写样板代码,且可以专注于特定于应用的逻辑。
Volley 不适用于下载大量内容的操作或流式传输操作,因为在解析过程中,Volley 会将所有响应存储在内存中。对于下载大量内容的操作,请考虑使用 DownloadManager 等替代方法。
核心 Volley 库是在 GitHub 上开发的,其中包含主要请求分派管道以及一组位于 Volley“工具箱”中的通用实用程序。要将 Volley 添加到您的项目,最简单的方法是将以下依赖项添加到应用的 build.gradle 文件中:
dependencies {
...
implementation 'com.android.volley:volley:1.1.1'
}
您还可以克隆 Volley 代码库并将其设置为一个库项目:
git clone https://github.com/google/volley
按照创建 Android 库中的说明,将下载的源代码作为 Android 库模块导入您的应用项目中。
dependencies {
...
implementation 'com.android.volley:volley:1.1.1'
}
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "mylog";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = findViewById(R.id.imageView);
String url = "http://a0.att.hudong.com/64/76/20300001349415131407760417677.jpg";
RequestQueue queue = Volley.newRequestQueue(this);
ImageLoader imageLoader = new ImageLoader(queue, new ImageLoader.ImageCache() { //两个参数:队列,cache
private LruCache cache = new LruCache<>(50) //least recently used 即最近最少使用算法LRU
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url,bitmap);
}
});
imageLoader.get(url, new ImageLoader.ImageListener() { //两个参数:网址,监听器
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
imageView.setImageBitmap(response.getBitmap());
}
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: ",error );
}
});
}
}
关于 Glide
Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。
Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。
虽然Glide 的主要目标是让任何形式的图片列表的滚动尽可能地变得更快、更平滑,但实际上,Glide几乎能满足你对远程图片的拉取/缩放/显示的一切需求。
API
Glide 使用简明的流式语法API,这是一个非常棒的设计,因为它允许你在大部分情况下一行代码搞定需求:
Glide.with(fragment)
.load(url)
.into(imageView);
使用Gradle:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
dependencies {
...
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "mylog";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = findViewById(R.id.imageView);
String url = "http://a0.att.hudong.com/64/76/20300001349415131407760417677.jpg";
RequestQueue queue = Volley.newRequestQueue(this);
Glide.with(this)
.load(url)
.placeholder(R.drawable.ic_launcher_background)
.listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(imageView);
}
}
属于Android扩展库:
声明依赖项
要添加 SwipeRefreshLayout 的依赖项,您必须将 Google Maven 代码库添加到项目中。有关详情,请阅读 Google 的 Maven 代码库。
在应用或模块的 build.gradle 文件中添加所需工件的依赖项:
dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
}
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "mylog";
String url1 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1587552186960&di=f1ab44449bdae672c4f9a5f00dee9c7d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2Fd009b3de9c82d1587e249850820a19d8bd3e42a9.jpg";
String url2 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1587551075414&di=ff5bb8c599c07c26c453a12edb602fa9&imgtype=0&src=http%3A%2F%2Fa3.att.hudong.com%2F14%2F75%2F01300000164186121366756803686.jpg";
private ImageView imageView;
private SwipeRefreshLayout swipeRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
imageView = findViewById(R.id.imageView);
RequestQueue queue = Volley.newRequestQueue(this);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
loadImage();
}
});
}
void loadImage(){
Random random = new Random();
String url = random.nextBoolean()? url1 : url2;
Glide.with(this)
.load(url)
.placeholder(R.drawable.ic_launcher_background)
.listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
return false;
}
})
.into(imageView);
}
}