Android入门第62天-Glide显示网络图片高版本的使用

Posted TGITCIC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android入门第62天-Glide显示网络图片高版本的使用相关的知识,希望对你有一定的参考价值。

开篇

        一旦我们进入了MVVM,那么MVVM一发不可收拾了。有了MVVM,我们再也不用漫天遍野的去look layout里的UI组件id了,想用时直接dataBinding.layout驼峰命名,即可到处使用这个组件了。

        我们之前的Glide为了演示,显示的是本地图片用法。它从@mipmap里得到一个image的id,是一个int值,即可把图片传到ImageView里进行显示了。

        但是实际生产级别android应用,我们一般会遵照以下原则在Android里进行图片显示:

  1. 小图标、按钮背景、输入框背景使用本地mipmap的图片;
  2. 内容、可变图片一律需要来自于网络(CDN)图片即这个图片不在本地保留的而是一个url;

      所以,当图片的使用场景增多了,我们的Glide的使用场景也随之增多。

      但是Glide新版本>4.9版本在加载网络图片时会有一些问题,最著名的就是它在加载图片时会抛出一个“Failed to find GeneratedAppGlideModule”的Exception。

        要解决这个问题其实非常简单,下面我们直接来看项目。

项目整体情况

        一个手机APP,通常来说都是在后台维护各种CMS素材图片。

  1. 图片上传至后台在数据库里存储成这样的格式“/img/petthecat/pet_the_cat_1.jpg”;
  2. 后台会实时/定时跑批处理把图片往云的CDN上传上去,传完后会得到CDN返还的一个该图片成功上传CDN后的url,把这个url存在DB的cdn_url字段;
  3. 把这样的地址通过手机APP的获取商品信息接口从数据存储的cdn_url字段拿出来,和其它相关的数据、内容一起拼成JSON报文返回给到前台APP;
  4. 前台APP通过Glide把图片的URL前面再拼上一个CDN的地址,然后显示该图片;

所以为此我们自己搭了一个nginx来模拟“CDN”。

Nginx中hosting物理小图片存储目录。

Nginx配置

Glide组件使用

gradle文件中的依赖

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

        我们在此用的是Glide4.11.0,是属于高版本的Glide了。因此,我们需要书写一个类

这个类是继承自AppGlideModule,其内容如下。

MyAppGlideModule.java

package com.mkyuan.aset.mall.android;

import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
@GlideModule
public class MyAppGlideModule extends AppGlideModule 


        内容为空即可,如果没有这个类在项目里,在使用Glide加载远程图片时,你就会遇到“ Failed to find GeneratedAppGlideModule”这个exception。为了解决这个异常提示特意新建了一个工具类,只要继承了AppGlideModule,在加载图片的时候Glide就会自己用到的。

        然后来看我们的使用。

package com.mkyuan.aset.mall.android.home.petthecat;

import android.widget.ImageView;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.databinding.BindingAdapter;
import com.bumptech.glide.Glide;
public class PetTheCatBean extends BaseObservable 
    @Bindable
    public String getPrice() 
        return price;
    

    public void setPrice(String price) 
        this.price = price;
        notifyChange();
    

    public PetTheCatBean(String petImg, String descrText, String price) 
        this.petImg = petImg;
        this.descrText = descrText;
        this.price = price;
    

    private String petImg;

    @Bindable
    public String getPegImg() 
        return petImg;
    

    public void setImgId(String petImg) 
        this.petImg = petImg;
        notifyChange();
    

    @Bindable
    public String getDescrText() 
        return descrText;
    

    public void setDescrText(String descrText) 
        this.descrText = descrText;
        notifyChange();
    
    //自定义属性  headUrl 是自定义的,在xml的imageView中引用
    @BindingAdapter("petImgUrl")
    public static void getImage(ImageView view, String petImgUrl) 
        Glide.with(view.getContext()).load(petImgUrl).into(view);
    

    private String descrText = "";
    private String price = "0";

         附上相应的layout xml

<ImageView
   android:id="@+id/ivPetCatImg"
   android:layout_width="90dp"
   android:layout_height="90dp"
   android:layout_gravity="center"
   android:scaleType="fitStart"
   app:petImgUrl="@petCatBean.pegImg" />

        在显示时我们只需要在这个layout inflate后,在需要setAdapter前如下操作即可正确显示远程网络图片了。

package com.mkyuan.aset.mall.android.home.petthecat;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;

import com.mkyuan.aset.mall.android.BR;
import com.mkyuan.aset.mall.android.R;
import com.mkyuan.aset.mall.android.databinding.PetTheCatBinding;
import com.mkyuan.aset.mall.android.home.DatabindingGridAdapter;
import com.mkyuan.aset.mall.android.util.AsetMallConstants;

import java.util.ArrayList;
import java.util.List;

public class FragmentPetTheCat extends Fragment 
    protected static final String TAG = "AsetMall";
    private Context ctx;
    //private Banner adBanner;
    private GridView petCatGridView;
    private PetTheCatBinding dataBinding;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        ctx = this.getActivity();
        dataBinding = DataBindingUtil.inflate(inflater, R.layout.pet_the_cat, container,
                false);
        petCatGridView = dataBinding.gridPetthecat;
        Log.i(TAG, ">>>>>FragmentPetTheCat->get dataBinding");
        initPetTheCatDataList();
        return dataBinding.getRoot();

    

    private void initPetTheCatDataList() 
        List<PetTheCatBean> list = new ArrayList<PetTheCatBean>();
        list.add(new PetTheCatBean(AsetMallConstants.CDN_URL + "/img/petthecat/pet_the_cat_1.jpg",
                "羊陀上门撸你", "23"));
        list.add(new PetTheCatBean(AsetMallConstants.CDN_URL + "/img/petthecat/pet_the_cat_2.jpg",
                "吸松鼠要么?", "128"));
        list.add(new PetTheCatBean(AsetMallConstants.CDN_URL + "/img/petthecat/pet_the_cat_3.png",
                "寄养傻狗7天", "500"));
        DatabindingGridAdapter<PetTheCatBean> adapter =
                new DatabindingGridAdapter<PetTheCatBean>(ctx,
                R.layout.pet_cat_detail, list,
                BR.petCatBean);
        petCatGridView.setAdapter(adapter);
    

         自己不妨动一下手试试看吧。

以上是关于Android入门第62天-Glide显示网络图片高版本的使用的主要内容,如果未能解决你的问题,请参考以下文章

Android入门第9天-Android读本地JSON文件并显示

Android入门第29天-Android里如何巧用Spinner做弹出选择对话框

Android零基础入门第62节:搜索框组件SearchView

glide4.0以上在Android9.0以上加载图片不显示解决方案

Android入门第10天-Android访问远程Spring Boot提供的Restful API接口

Android入门第21天-Android里TextClock的使用