Android uses GridView to load (weak reference) network pictures asynchronously (click to view)
In the current Android development, more and more app s use the album function of Android. Using the album will use GridView to load pictures, but when loading a large number of pictures, there will be a black screen because the loading process is slow, and because more and more pictures cause the problem of OOM. In this case, you need to use threads to load images and display them asynchronously.
First look at the renderings:
- **
- A GridView control
- Adapter
- A custom class loaded asynchronously
- A dialog to load the original image
- **
activity_mail.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context="activity.cc.com.demo014.MainActivity"
android:orientation="vertical">
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"/>
</LinearLayout>
Note: only one GridView control is included
MainActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//Get control and implement click event
gridView = (GridView) findViewById(R.id.gridview);
gridView.setOnItemClickListener(this);
//The GetData method is to populate the data
getDatas();
//Using adapter to fill in data
gridViewAdapter = new GridViewAdapter(this, datas, gridView);
gridView.setAdapter(gridViewAdapter);
}
GridViewAdapter.java:
package activity.cc.com.demo014;
import android.app.Activity;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by admin on 2017/12/11.
*/
public class GridViewAdapter extends BaseAdapter {
List<GridViewData> datas = new ArrayList<GridViewData>();
GridView gridview;
Activity activity;
LayoutInflater inflater;
AsyncImageLoader asyncImageLoader;
/**
* Instantiate adapter and receive the passed data
* @param activity
* @param datas
* @param gridview
*/
public GridViewAdapter(Activity activity, List<GridViewData> datas, GridView gridview){
this.activity = activity;
this.datas = datas;
this.gridview = gridview;
//Instantiate layoutinflate
inflater = activity.getLayoutInflater();
//Instantiate a class that loads pictures asynchronously
asyncImageLoader = new AsyncImageLoader();
}
/**
* This method is to display the number of pictures
* @return Depends on the size of the data
*/
@Override
public int getCount() {
return datas.size();
}
/**
* Get the data of each item
* @param position
* @return
*/
@Override
public GridViewData getItem(int position) {
return datas.get(position);
}
/**
* getItemId
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* One system call per load
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//When the recycled view is empty, get it again
if(convertView == null){
convertView = inflater.inflate(R.layout.gridview_item, null);
}
convertView.setTag(position);
//Get the value of each item
GridViewData info = getItem(position);
//Using class of asynchronous loading picture to load picture and implement callback
asyncImageLoader.loadDrawable(position, info.img_url, new AsyncImageLoader.ImageCallback() {
@Override
public void onImageLoad(Integer t, Bitmap bitmap) {
View view = gridview.findViewWithTag(t);
if(view != null){
Log.i("TAG", "Loading succeeded...");
ImageView img_url = view.findViewById(R.id.img_url);
img_url.setImageBitmap(bitmap);
}
}
@Override
public void onError(Integer t) {
View view = gridview.findViewWithTag(t);
if(view != null){
Log.i("TAG", "Load failed...");
ImageView img_url = view.findViewById(R.id.img_url);
//Loading or failed to load. The app icon is loaded by default
img_url.setBackgroundResource(R.mipmap.ic_launcher);
}
}
});
TextView txt_name = convertView.findViewById(R.id.txt_name);
txt_name.setText(info.name);
return convertView;
}
}
GridViewData.java:
package activity.cc.com.demo014;
/**
* Created by admin on 2017/12/11.
*/
public class GridViewData {
public GridViewData(String img_url, String name){
this.img_url = img_url;
this.name = name;
}
public String img_url, name;
public String getImg_url() {
return img_url;
}
public void setImg_url(String img_url) {
this.img_url = img_url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "GridViewData{" +
"img_url='" + img_url + '\'' +
", name='" + name + '\'' +
'}';
}
}
Note: note that the attribute value is public. The asynchronous loading of pictures is over here. Next, click the image to view the original image.
MainActivity.java:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.i("TAG", "" + position);
showImageDialog(position);
}
private void showImageDialog(int position) {
//A friendly prompt box will pop up, prompting the user to confirm to log out?
new CommomDialog(this, position, R.style.dialog, datas.get(position).getImg_url(), new CommomDialog.OnCloseListener() {
@Override
public void onClick(Dialog dialog, boolean confirm) {
if(confirm){
dialog.dismiss();
}
}
}).setTitle(datas.get(position).getName()).show();
}
CommomDialog.java:
package activity.cc.com.demo014;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Encapsulated dialog
*/
public class CommomDialog extends Dialog implements View.OnClickListener {
private TextView textview_name;
private ImageView image_url;
private Context mContext;
private String img_url;
private OnCloseListener listener;
private String positiveName;
private String negativeName;
private String title;
int position;
AsyncImageLoader asyncImageLoader;
public CommomDialog(Context context) {
super(context);
this.mContext = context;
}
public CommomDialog(Context context, int themeResId, String img_url) {
super(context, themeResId);
this.mContext = context;
this.img_url = img_url;
}
public CommomDialog(Context context, int position, int themeResId, String img_url, OnCloseListener listener) {
super(context, themeResId);
this.mContext = context;
this.position = position;
this.img_url = img_url;
this.listener = listener;
asyncImageLoader = new AsyncImageLoader();
}
protected CommomDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
this.mContext = context;
}
public CommomDialog setTitle(String title){
this.title = title;
return this;
}
public CommomDialog setPositiveButton(String name){
this.positiveName = name;
return this;
}
public CommomDialog setNegativeButton(String name){
this.negativeName = name;
return this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imgae_view);
setCanceledOnTouchOutside(false);
initView();
initData();
}
private void initData() {
asyncImageLoader.loadDrawable(position, img_url, new AsyncImageLoader.ImageCallback() {
@Override
public void onImageLoad(Integer t, Bitmap bitmap) {
image_url.setImageBitmap(bitmap);
}
@Override
public void onError(Integer t) {
image_url.setBackgroundResource(R.mipmap.ic_launcher);
}
});
textview_name.setText(title);
}
private void initView(){
image_url = findViewById(R.id.image_url);
textview_name = findViewById(R.id.textview_name);
image_url.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int temdId = v.getId();
if(temdId == R.id.image_url){
dismiss();
}
// switch (v.getId()){
// case R.id.cancel:
// if(listener != null){
// listener.onClick(this, false);
// }
// this.dismiss();
// break;
// case R.id.submit:
// if(listener != null){
// listener.onClick(this, true);
// }
// break;
// }
}
public interface OnCloseListener{
void onClick(Dialog dialog, boolean confirm);
}
}
imgae_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
<TextView
android:id="@+id/textview_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView"
android:textColor="#000000" />
<ImageView
android:id="@+id/image_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/ic_launcher" />
</LinearLayout>
Note: so far, the function has been realized.
Optimization: the image shown here is displayed according to the original size. If you need to fix the size and fill the layout, add android:scaleType= ”fitXY "this line of code is good.
GAME OVER!!!
Click to download the source code
CSDN doesn't seem to have the option to download resources for free. So, if you need source code and no points, please leave a message