Hướng dẫn sử dụng thư viện Glide Image
Bài đăng này đã không được cập nhật trong 3 năm
Tải một hình ảnh từ Internet là khá dễ dàng bằng cách sử dụng thư viện Volley. Nhưng tôi sẽ giới thiệu một giải pháp tốt hơn nhiều so với thư viện hình ảnh Glide của volley. Khi so sánh với Volley, Glide thể hiện tốt hơn trong nhiều trường hợp về hiệu suất và khả năng sử dụng. Dưới đây là những ưu điểm của Glide so với Volley
Hỗ trợ tìm nạp, giải mã, và hiển thị ảnh tĩnh, hình ảnh, và GIF động
Trình giữ chỗ có thể được thêm vào trước khi tải phương tiện
Tải hình thu nhỏ đầu tiên (mờ) trước rồi tải hình ảnh có độ phân giải cao như trong WhatsApp hoặc Facebook.
Tác động qua lại giữa các phương tiện truyền thông
Hỗ trợ chuyển đổi hình ảnh tùy ý như tải hình ảnh trong hình tròn hoặc bất kỳ hình dạng khác.
Bộ nhớ và cơ chế lưu trữ trên đĩa
Hoạt động tốt với cả hai thư viện Volley và OkHttp
VIDEO DEMO
Sử dụng Glide Image bằng cách nào
Trước tiên thêm glide dependency vào build.gradle của bạn.
build.gradle
dependencies {
// glide
compile 'com.github.bumptech.glide:glide:3.7.0'
}
Thứ hai tải hình ảnh vào ImageView sử dụng đoạn mã dưới đây.
String imgUrl = "http://api.androidhive.info/images/glide/medium/deadpool.jpg";
ImageView imageView = (ImageView) view.findViewById(R.id.thumbnail);
Glide.with(mContext).load(imgUrl)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
Mẫu JSon
Để xây dựng ứng dụng thư viện, chúng ta sử dụng một mẫu JSON chứa url hình ảnh được yêu cầu. Mỗi hình ảnh được nén và thay đổi kích cỡ ở ba độ phân giải khác nhau, cao, trung bình và nhỏ. Để hiển thị dạng grid, chúng ta tải hình ảnh có độ phân giải trung bình và với việc hiển thị hình ảnh toàn màn hình, chúng ta tải hình ảnh có độ phân giải cao hơn.
Liên kết JSON: http://api.androidhive.info/json/glide.json
[{
"name": "Deadpool",
"url": {
"small": "http://api.androidhive.info/images/glide/small/deadpool.jpg",
"medium": "http://api.androidhive.info/images/glide/medium/deadpool.jpg",
"large": "http://api.androidhive.info/images/glide/large/deadpool.jpg"
},
"timestamp": "February 12, 2016"
},
{
"name": "Batman vs Superman",
"url": {
"small": "http://api.androidhive.info/images/glide/small/bvs.png",
"medium": "http://api.androidhive.info/images/glide/medium/bvs.png",
"large": "http://api.androidhive.info/images/glide/large/bvs.png"
},
"timestamp": "March 25, 2016"
}]
Xây dựng ứng dụng Image Gallery
Bước 1
Tạo một dự án mới trong Android Studio từ File ⇒ New Project. Sau đó chọn Activity default, sau đó chọn Next
Bước 2
Mở build.gradle và thêm Glide, Volley và RecyclerView dependencies. Volley được sử dụng để tải json thư viện bằng cách thực hiện gọi HTTP. RecyclerView được sử dụng để hiển thị hình ảnh thư viện trong một mô hình dạng Grid
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.android.support:support-v4:23.2.1'
// RecyclerView
compile 'com.android.support:recyclerview-v7:23.1.1'
// volley
compile 'com.android.volley:volley:1.0.0'
// Glide
compile 'com.github.bumptech.glide:glide:3.7.0'
}
Bước 3
Tạo thêm packages có tên là activity, adapter, app, model and helper giúp tổ chức cho dự án.
Bước 4
Tạo một lớp có tên AppController.java trong packages app. Đây là một lớp singleton, trong đó chúng ta khởi tạo các đối tượng cốt lõi của volley.
AppController.java
package info.androidhive.glide.app;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class AppController extends Application {
public static final String TAG = AppController.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Bước 5
Mở AndroidManifest.xml và thêm thẻ AppController vào <application>. Thêm quyền INTERNET vì chúng ta cần phải thực hiện gọi HTTP.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.glide">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".app.AppController"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chúng ta hãy bắt đầu thêm gallery vào trước.
Thêm Grid Gallery View vào ứng dụng
Bước 6
Mở file lâyout của main activity và thêm RecyclinglerView. Đối với main activity, có hai file layout activity_main.xml và content_main.xml
Activity_main.xml chứa AppBar và Toolbar.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:fitsSystemWindows="true"
tools:context=".activity.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
Content_main.xml có chứa các recyclerView để tải các hình ảnh trong grid.
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="info.androidhive.glide.activity.MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</RelativeLayout>
Bước 7
Trong package helper, tạo một lớp có tên SquareLayout.java. Lớp này giúp các hình ảnh để hiển thị trong tỷ lệ vuông trong grid view.
SquareLayout.java
package info.androidhive.glide.helper;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* Created by Lincoln on 05/04/16.
*/
class SquareLayout extends RelativeLayout {
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Set a square layout.
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
Bước 8
Trong res ⇒ layout, tạo ra một layout có tên là gallery_thumbnail.xml. Layout này chứa ImageView để hiển thị hình thu nhỏ trong chế độ xem qua.
gallery_thumbnail.xml
<?xml version="1.0" encoding="utf-8"?>
<info.androidhive.glide.helper.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
</info.androidhive.glide.helper.SquareLayout>
Bước 9
Trong package adapter, tạo một lớp có tên GalleryAdapter.java Đây là một lớp adapter, nó inflates gallery_thumbnail.xml và hiển thị các hình ảnh trong recyclerView.
GalleryAdapter.java
package info.androidhive.glide.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.List;
import info.androidhive.glide.R;
import info.androidhive.glide.model.Image;
/**
* Created by Lincoln on 31/03/16.
*/
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.MyViewHolder> {
private List<Image> images;
private Context mContext;
public class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView thumbnail;
public MyViewHolder(View view) {
super(view);
thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
}
}
public GalleryAdapter(Context context, List<Image> images) {
mContext = context;
this.images = images;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.gallery_thumbnail, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Image image = images.get(position);
Glide.with(mContext).load(image.getMedium())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.thumbnail);
}
@Override
public int getItemCount() {
return images.size();
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private GalleryAdapter.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final GalleryAdapter.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
Bước 10
Cuối cùng mở MainActivity.java và thực hiện các thay đổi dưới đây
Tải xuống json bằng cách yêu cầu http volley. FetchImages () được sử dụng với mục đích này
Parse json và thêm models vào array list.
Đưa danh sách mảng vào lớp adapter adapter của recyclerView.
MainActivity.java
package info.androidhive.glide.activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import info.androidhive.glide.R;
import info.androidhive.glide.adapter.GalleryAdapter;
import info.androidhive.glide.app.AppController;
import info.androidhive.glide.model.Image;
public class MainActivity extends AppCompatActivity {
private String TAG = MainActivity.class.getSimpleName();
private static final String endpoint = "http://api.androidhive.info/json/glide.json";
private ArrayList<Image> images;
private ProgressDialog pDialog;
private GalleryAdapter mAdapter;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
pDialog = new ProgressDialog(this);
images = new ArrayList<>();
mAdapter = new GalleryAdapter(getApplicationContext(), images);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
/* recyclerView.addOnItemTouchListener(new GalleryAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new GalleryAdapter.ClickListener() {
@Override
public void onClick(View view, int position) {
Bundle bundle = new Bundle();
bundle.putSerializable("images", images);
bundle.putInt("position", position);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
newFragment.setArguments(bundle);
newFragment.show(ft, "slideshow");
}
@Override
public void onLongClick(View view, int position) {
}
}));*/
fetchImages();
}
private void fetchImages() {
pDialog.setMessage("Downloading json...");
pDialog.show();
JsonArrayRequest req = new JsonArrayRequest(endpoint,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
pDialog.hide();
images.clear();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Image image = new Image();
image.setName(object.getString("name"));
JSONObject url = object.getJSONObject("url");
image.setSmall(url.getString("small"));
image.setMedium(url.getString("medium"));
image.setLarge(url.getString("large"));
image.setTimestamp(object.getString("timestamp"));
images.add(image);
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req);
}
}
Nếu bạn chạy ứng dụng, bạn có thể xem các hình ảnh được hiển thị theo kiểu lưới. Hãy chắc chắn rằng thiết bị của bạn được kết nối với internet.
Fullscreen Image Slideshow
Bước 11
Tạo một layout có tên image_fullscreen_preview.xml theo định dạng res ⇒. layout, nó được sử dụng để hiển thị hình ảnh trong chế độ xem toàn màn hình.
image_fullscreen_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<ImageView
android:id="@+id/image_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="fitCenter" />
</RelativeLayout>
Bước 12
Trong package activity, tạo một lớp có tên SlideshowDialogFragment.java. Đây là một lớp fragment kế thừa từ DialogFragment.
DialogFragment.java
package info.androidhive.glide.activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
import info.androidhive.glide.R;
import info.androidhive.glide.model.Image;
public class SlideshowDialogFragment extends DialogFragment {
private String TAG = SlideshowDialogFragment.class.getSimpleName();
private ArrayList<Image> images;
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private TextView lblCount, lblTitle, lblDate;
private int selectedPosition = 0;
static SlideshowDialogFragment newInstance() {
SlideshowDialogFragment f = new SlideshowDialogFragment();
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_image_slider, container, false);
viewPager = (ViewPager) v.findViewById(R.id.viewpager);
lblCount = (TextView) v.findViewById(R.id.lbl_count);
lblTitle = (TextView) v.findViewById(R.id.title);
lblDate = (TextView) v.findViewById(R.id.date);
images = (ArrayList<Image>) getArguments().getSerializable("images");
selectedPosition = getArguments().getInt("position");
Log.e(TAG, "position: " + selectedPosition);
Log.e(TAG, "images size: " + images.size());
myViewPagerAdapter = new MyViewPagerAdapter();
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
setCurrentItem(selectedPosition);
return v;
}
private void setCurrentItem(int position) {
viewPager.setCurrentItem(position, false);
displayMetaInfo(selectedPosition);
}
// page change listener
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
displayMetaInfo(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
};
private void displayMetaInfo(int position) {
lblCount.setText((position + 1) + " of " + images.size());
Image image = images.get(position);
lblTitle.setText(image.getName());
lblDate.setText(image.getTimestamp());
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
// adapter
public class MyViewPagerAdapter extends PagerAdapter {
private LayoutInflater layoutInflater;
public MyViewPagerAdapter() {
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.image_fullscreen_preview, container, false);
ImageView imageViewPreview = (ImageView) view.findViewById(R.id.image_preview);
Image image = images.get(position);
Glide.with(getActivity()).load(image.getLarge())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageViewPreview);
container.addView(view);
return view;
}
@Override
public int getCount() {
return images.size();
}
@Override
public boolean isViewFromObject(View view, Object obj) {
return view == ((View) obj);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}
Bước 13
Mở MainActivity.java và thêm các sự kiện click để recyclerView trong onCreate () .
MainActivity.java
recyclerView.addOnItemTouchListener(new GalleryAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new GalleryAdapter.ClickListener() {
@Override
public void onClick(View view, int position) {
Bundle bundle = new Bundle();
bundle.putSerializable("images", images);
bundle.putInt("position", position);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
newFragment.setArguments(bundle);
newFragment.show(ft, "slideshow");
}
@Override
public void onLongClick(View view, int position) {
}
}));
Chạy ứng dụng một lần nữa và thử nhấn vào hình thu nhỏ. Bạn sẽ thấy thanh trượt hình ảnh toàn màn hình có bật chức năng swiping.
All rights reserved