使用第三方控件GifImageView加载网络Gif图片,并且在ListView或RecycleView里面加载

最近因为做项目要用到Gif图片,但是网上的介绍有点乱,可能有点不适合我吧,所以就结合网上的自己做了一个Demo。希望可以帮到大家

1.使用第三方控件GifImageView加载网络图片

工具:
  • Android studio
第三方工具类:
  • GifImageView
  • OkHttp, 自己去maven库搜okhttp和okio就行了
  • EventBus,自己去maven库搜索compile ‘org.greenrobot:eventbus:3.0.0’就行

使用OKHttp异步加载数据,然后使用EventBus将数据发出去。网址是随便从网上找的,有点重口,慎用!!
第三方工具(okhttp和okio我直接用的jar包):

compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'
compile 'org.greenrobot:eventbus:3.0.0'

HttpOk.java:

import org.greenrobot.eventbus.EventBus;
import java.io.IOException;

import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Response;

/**
 * Created by Administrator on 2016/11/3.
 */

public class HttpOk {


    public void doGetData(){
        OkHttpClient okHttpClent = new OkHttpClient();
        okhttp3.Request request = new okhttp3.Request.Builder().url("http://dimg.spriteapp.cn/ugc/2016/11/02/5819746890d01.gif").addHeader("User-Agent","BiLiBiLi WP Client/4.20.0 (orz@loli.my)").build();
        okhttp3.Call call = okHttpClent.newCall(request);
        call.enqueue(
                new okhttp3.Callback() {
                    @Override
                    public void onFailure(okhttp3.Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(okhttp3.Call call, Response response) throws IOException {
                        int code = response.code();
                        if (code ==200) {
                            byte[] data = response.body().bytes();
                            HttpUrl reqUrl = call.request().url();
                            EventBus.getDefault().post(data);
                        }
                    }
                }
        );
    }
}

然后就是展示了,因为EvevtBus传回来的数据不是在UI线程,所以不能在onEvent里面直接接收数据更新界面,所以我使用了一个handle进行线程间的通信

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.IOException;

import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;


public class MainActivity extends AppCompatActivity {
    private final String tag = "MainActivity-->";
    private GifImageView gif1;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    Object obj = msg.obj;
                    if (obj instanceof byte[]) {
                        byte[] data = (byte[]) obj;
                        GifDrawable gifFrom = null;
                        try {
                            gifFrom = new GifDrawable(data);
                            gif1.setImageDrawable(gifFrom);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gif1 = (GifImageView) this.findViewById(R.id.info_gif1);
        HttpOk httpOk = new HttpOk();
        httpOk.doGetData();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(byte[] data) {
        Message message = handler.obtainMessage(1);
        message.obj = data;
        handler.sendMessage(message);
    }
}

MainActivity的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.dddddemo.MainActivity">

    <pl.droidsonroids.gif.GifImageView
        android:id="@+id/info_gif1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="fitXY"
        />
</RelativeLayout>

2.ListView或RecycleView加载网络动态图片

工具:

  • Android studio

使用到的第三方:

compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'

上面的回调数据是在子线程,那么我想要在ListView的adapter里面进行图片的绑定该怎么办呢?因为知道的很少,不知道能不能在adapter里面使用handle进行线程间数据的通信,这个等会试一下再说,估计也不会试,有人试了跟我说一声,哈哈。现在我用的是另外一个方法,使用异步任务进行数据的加载,那样就不会就可以解决数据加载到控件上(里面添加了LRU的缓存)。

网络请求的异步任务的类:(GifImageLoader.java)

import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.RequiresApi;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

/**
 * Created by Administrator on 2016/11/3.
 */

public class GifImageLoader extends AsyncTask<String, Void, GifDrawable> {

    private GifImageView gifImageView;
    private String url;

    public GifImageLoader(GifImageView gifImageView) {
        this.gifImageView = gifImageView;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        GifImageLoader loader = (GifImageLoader) gifImageView.getTag();
        if (loader != null) {
            loader.cancel(false);
        }
        gifImageView.setTag(this);
    }

    @Override
    protected GifDrawable doInBackground(String... params) {
        url = params[0];
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            int code = connection.getResponseCode();
            if (code == 200) {
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] bytes = new byte[10240];
                int len = 0;
                while ((len = inputStream.read(bytes)) != -1) {
                    baos.write(bytes, 0, len);
                }
                byte[] data = baos.toByteArray();
                GifDrawable gifDrawable = new GifDrawable(data);
                return gifDrawable;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(GifDrawable gifDrawable) {
        super.onPostExecute(gifDrawable);
        if (gifDrawable != null) {
            try {
                gifImageView.setImageDrawable(gifDrawable);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {

        }
        gifImageView.setTag(null);
    }

    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1)
    @Override
    protected void onCancelled(GifDrawable gifFrom) {
        if (gifFrom != null) {
            GifUtil.cache.put(url, gifFrom);
        }
    }
}

然后是实现图片缓存功能的类()

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.LruCache;

import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

/**
 * Created by Administrator on 2016/11/3.
 */

@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1)
public class GifUtil {
    static LruCache<String, GifDrawable> cache = new LruCache<String, GifDrawable>(5);

    public static void loadImage(GifImageView gifImageView, String url) {
        GifDrawable gifDrawable = cache.get(url);
        if (gifDrawable != null) {
        '//TODO:'
            gifImageView.setImageDrawable(gifDrawable);
        } else {
            new GifImageLoader(gifImageView).execute(url);
        }
    }
}

接下来是GifView控件直接加载图片的语句代码,这句代码直接加载你的adapter里面要加载Gif图片的地方就行了

previewImage = ((GifImageView) itemView.findViewById(R.id.recommend_gif_previewImage));
'//gifUrl是图片的网址,previewImage是加载的控件对象'
 GifUtil.loadImage(previewImage,gifUrl);

Gif布局(里面的属性自己随意):

<pl.droidsonroids.gif.GifImageView
            android:id="@+id/recommend_gif_previewImage"
            android:layout_width="400dp"
            android:layout_height="300dp"
            android:layout_gravity="center_horizontal"
            android:scaleType="fitXY" />
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
尝试着写web下的listview控件listview一般有四种显示模式——平铺、图标、列表和详细信息。这些显示模式唯一的共同点就是数据是相同的,显示效果完全不一样。这时候xml的优势就完全体现出来了。 第一步,就是建立一个自定义格式的xml,用来保存listview数据 第二步,xsl可以解析xml生成html,所以就针对listview的每一种显示效果设计了一个对应的xsl。这样前面定义的xml数据和不同的xsl一起就可以显示出不同的效果。 第三步,htc在开发web控件时,非常灵活和功能强大,可以采用客户端脚本如js,可以对控件进行封装,使之有自己的属性、方法和事件等。利用htc封装的listview控件中对外有两个属性CfgXMLSrc(配置文件,设置listview的每一种显示模式对应的xsl文件路径等信息)和Viewlistview的显示模式),在htc中根据listviewView属性来选择不同的xsl文件和xml数据文件生成html,并输出。 这样就可以通过改变listview控件view属性来切换listview的不同显示效果。 在线演示 打包下载 以前写换皮肤的控件,都是通过更换css和图片路径来做的(可以看看http://www.stedy.com),局限性很大,例如toolbar,在winxp和win2000下差别很大,只靠通过换css和图片路径无法应付这种情况。通过开发listview的经验,从中悟到了一种更好的开发换皮肤的web控件的模式: 首先将控件的相关数据用xml描述出来,对于每一种Theme(皮肤/主题样式),有一个相关的配置文件,配置文件中记载了该控件所用到的xsl、css、图片路径、htc等信息。在控件相关的htc中,根据Theme属性组合这些。从而可以灵活的应付各种情况。 例如刚才说的toolbar,假如入我们有三种风格:winxp蓝色、winxp银色和windows经典,前面两种基本差不多,只是样式和图片不一样,而后面一种和前面的两种差别比较大。那么我们需要写两个xsl,三个css文件,三个图片文件夹,组合一下就可以生成这三种风格的toolbar了。 这种控件开发模式会慢慢流行起来并在asp.net控件中发挥重要作用的
如果你的ListView中包含其他控件,比如Button、EditText等,那么在滑动ListView时,这些控件可能会重复加载或者错位,这是常见的问题。解决这个问题的方法是在ListView的Adapter中正确地使用ViewHolder模式。 ViewHolder模式是一种优化ListView性能的技术,它通过缓存View的引用,避免重复加载和findViewById操作,从而提高ListView的滑动流畅度。在Adapter的getView()方法中,需要使用ViewHolder来缓存View的引用,比如: ```java public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); holder = new ViewHolder(); holder.textView = convertView.findViewById(R.id.text_view); holder.button = convertView.findViewById(R.id.button); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 设置控件的值 holder.textView.setText(data[position]); holder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 处理按钮点击事件 } }); return convertView; } static class ViewHolder { TextView textView; Button button; } ``` 在上面的代码中,我们定义了一个ViewHolder类来缓存TextView和Button的引用,在getView()方法中使用convertView来复用已经创建好的View,如果convertView为null,则创建一个新的View,并将ViewHolder保存到View的Tag中。在设置控件的值时,我们通过ViewHolder来获取控件的引用,从而避免重复加载和findViewById操作。这样做可以确保ListView中的控件不会重复加载或者错位。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值