19、GIF动图显示
程序员文章站
2022-03-11 10:35:47
...
有时候需要显示动图,可安卓有没有现成的控件,很烦。用过GifView(一个开源的第三方GIF显示控件),后来用android-gif-drawable(另一个GIF开源控件)。简单点可以用第一种,这里选第二种。
GitHub下载地址:https://github.com/koral--/android-gif-drawable-eclipse-sample(eclipse的一个例程,需要其他请百度)
点击Download ZIP下载:
将libs文件夹下所有文件夹拷到工程目录libs下(如:.\Dp Notes\libs)下,将src下lp文件夹拷到工程目录src下(如:.\Dp Notes\src)。
ADT工程名上右键刷新:
好吧,报了一堆的错,应该是库有更新,错误原因呢主要是ADT的SDK版本太低,解决办法当然是更新SDK(更新太慢?算了,不更新了),每个文件改错。
首先,import android.support.annotation.x报错:
百度,下载support-annotations-23.0.1.jar放libs下,地址:http://download.csdn.net/download/lvshaorong/9399501,CSDN的免积分。
然后,类似final ConcurrentLinkedQueue<AnimationListener> mListeners = new ConcurrentLinkedQueue<AnimationListener>();
类似catch (Exception ignored)
类似
// @TargetApi(Build.VERSION_CODES.LOLLIPOP)
// public GifImageView(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
// super(context, attrs, defStyle, defStyleRes);
// postInit(GifViewUtils.initImageView(this, attrs, defStyle, defStyleRes));
// }
最后,有错的大胆注释,没错为止。
简单显示测试,Activity_main.xml中最后加入:
gif_smaple是一个GIF动图文件,运行:
注:这是一个.gif动图,ctrl点击图片查看
ADT这个工具确实是要被淘汰了,最后一次用。
代码怎么添加一个GifImageView并显示一个动图?其实和安卓自带的控件一样,new一个设置属性即可,在上节的ListView Item中直接实现:
类似于图片加载完毕的一个GIF加载完毕监听器:
附上GifDrawable加载的类,类似于图片Drawable的加载:
运行看看:
注:这是一个.gif动图,ctrl点击图片查看
GitHub下载地址:https://github.com/koral--/android-gif-drawable-eclipse-sample(eclipse的一个例程,需要其他请百度)
点击Download ZIP下载:
将libs文件夹下所有文件夹拷到工程目录libs下(如:.\Dp Notes\libs)下,将src下lp文件夹拷到工程目录src下(如:.\Dp Notes\src)。
ADT工程名上右键刷新:
好吧,报了一堆的错,应该是库有更新,错误原因呢主要是ADT的SDK版本太低,解决办法当然是更新SDK(更新太慢?算了,不更新了),每个文件改错。
首先,import android.support.annotation.x报错:
百度,下载support-annotations-23.0.1.jar放libs下,地址:http://download.csdn.net/download/lvshaorong/9399501,CSDN的免积分。
然后,类似final ConcurrentLinkedQueue<AnimationListener> mListeners = new ConcurrentLinkedQueue<AnimationListener>();
类似catch (Exception ignored)
类似
// @TargetApi(Build.VERSION_CODES.LOLLIPOP)
// public GifImageView(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
// super(context, attrs, defStyle, defStyleRes);
// postInit(GifViewUtils.initImageView(this, attrs, defStyle, defStyleRes));
// }
最后,有错的大胆注释,没错为止。
简单显示测试,Activity_main.xml中最后加入:
<pl.droidsonroids.gif.GifImageView android:id="@+id/giv_demo" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/gif_smaple"/>
gif_smaple是一个GIF动图文件,运行:
注:这是一个.gif动图,ctrl点击图片查看
ADT这个工具确实是要被淘汰了,最后一次用。
代码怎么添加一个GifImageView并显示一个动图?其实和安卓自带的控件一样,new一个设置属性即可,在上节的ListView Item中直接实现:
if("gif".equals(data.type)){//要显示GIF if(holder.tv_gifctrl!=null){//GIF控制先移除 holder.rl_data.removeView(holder.tv_gifctrl); } if(holder.giv_data!=null){//GIF显示先移除 holder.giv_data.setVisibility(View.GONE); } RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); holder.tv_gifctrl=new TextView(activity);//生成GIF控制 holder.tv_gifctrl.setText("GIF");//设置一些TextView属性 holder.tv_gifctrl.setGravity(Gravity.CENTER_HORIZONTAL); holder.tv_gifctrl.setTextColor(activity.getResources().getColor(R.color.white_dark)); holder.tv_gifctrl.setTextSize(TypedValue.COMPLEX_UNIT_PX,activity.getResources().getDimension(R.dimen.text_level1)); int padding=(int)activity.getResources().getDimension(R.dimen.padding_n); GradientDrawable gd = new GradientDrawable(); gd.setColor(activity.getResources().getColor(R.color.black_normal_88)); gd.setCornerRadius(padding); holder.tv_gifctrl.setBackground(gd);//设置圆角背景 holder.tv_gifctrl.setPadding(padding,padding,padding,padding); lp1.addRule(RelativeLayout.CENTER_IN_PARENT); holder.tv_gifctrl.setLayoutParams(lp1); holder.tv_gifctrl.setTag(tagctrlgif);//设置TAG holder.rl_data.addView(holder.tv_gifctrl);//添加到布局 OnClickListener listener=new OnClickListener() {//点击的监听器 @Override public void onClick(View v) { // TODO Auto-generated method stub v.setOnClickListener(null);//清除监听器 v.findViewWithTag(tagctrlgif).setVisibility(View.GONE);//通过TAG找到GIF控制,隐藏 if(holder.giv_data!=null){ //GIF显示先移除 holder.rl_data.removeView(holder.giv_data); } RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); //生成GIF显示 holder.giv_data=new GifImageView(activity); holder.giv_data.setLayoutParams(lp); holder.giv_data.setTag(tagdata);//设置TAG holder.rl_data.addView(holder.giv_data);//加到布局 //载入GIF图片资源 GifDrawable drawable=gifload.loadImage(viewparent,tagdata,data.dataurl,glcallback); if(drawable!=null){//已经加载过 drawable.start();//开始播放,设置 holder.giv_data.setBackground(drawable); } else{//添加一个进度条 RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); holder.pb_load=new ProgressBar(activity,null,android.R.attr.progressBarStyleSmall); lp1.addRule(RelativeLayout.CENTER_IN_PARENT); holder.pb_load.setLayoutParams(lp1); holder.pb_load.setTag(tagloadgif); holder.rl_data.addView(holder.pb_load); } } }; holder.rl_data.setOnClickListener(listener);//设置监听器 }
类似于图片加载完毕的一个GIF加载完毕监听器:
private GifLoadCallback glcallback=new GifLoadCallback() { @SuppressLint("NewApi") @Override public void onSuccess(GifDrawable drawable, int tag, View viewParent) { // TODO Auto-generated method stub if(drawable!=null){ //通过TAG找到GIF显示 GifImageView giv_data=(GifImageView)viewParent.findViewWithTag(tag); if(giv_data!=null){//找到,设置显示 // LayoutParams lp=rl_data.getLayoutParams(); // lp.height=itemWidth*drawable.getMinimumHeight()/drawable.getMinimumWidth(); // rl_data.setLayoutParams(lp); drawable.start(); giv_data.setBackground(drawable); viewParent.findViewWithTag(tag+1).setVisibility(View.GONE);//GIF控制隐藏 viewParent.findViewWithTag(tag-1).setVisibility(View.GONE);//GIF加载进度条隐藏 } } } };
附上GifDrawable加载的类,类似于图片Drawable的加载:
public class GifLoad { private Context context; private Map<String, GifDrawable> imageMap; private ThreadPoolExecutor executor = null; BlockingQueue<Runnable> queue =null; private String path=Environment.getExternalStorageDirectory()+"/Dp Notes/Cache/GifImage"; private int threadMaxNum=Runtime.getRuntime().availableProcessors()>1?Runtime.getRuntime().availableProcessors():2; private int cacheMaxNum=1; @SuppressLint("NewApi") public GifLoad(Context context){ this.context=context; imageMap=new LinkedHashMap<String, GifDrawable>(); queue =new ArrayBlockingQueue<Runnable>(this.threadMaxNum); executor=new ThreadPoolExecutor(this.threadMaxNum,this.threadMaxNum,1,TimeUnit.MINUTES,queue,new ThreadPoolExecutor.CallerRunsPolicy()); // File dir=new File(this.path); // if(!dir.exists()){ // dir.mkdirs(); // } } public void setcacheMaxNum(int maxNum){ this.cacheMaxNum=maxNum; } public GifDrawable loadImage(final View viewParent,final int viewTag,final String imageUrl,final GifLoadCallback callback){ if (imageMap.containsKey(imageUrl)) { GifDrawable drawable=imageMap.get(imageUrl); return drawable; } // int index=imageUrl.lastIndexOf("/"); // index=index>=0?index:0; // String filename=imageUrl.substring(index); // final String filepath=path+filename+".0"; // // final File mf=new File(filepath); // if(mf.exists()){ // //文件读取待加入 // if(draw!=null){ // imageMap.put(imageUrl,draw); // chackMapSize(); // return draw; // } // } imageMap.put(imageUrl,null); final Handler handler = new Handler() { @SuppressLint("HandlerLeak") public void handleMessage(Message message) { if(callback!=null){ if(message.what==1){ callback.onSuccess((GifDrawable)message.obj,viewTag,viewParent); } } } }; executor.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub URL url = null; InputStream inputStream = null; try { url = new URL(imageUrl); inputStream = url.openStream(); ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[512]; int rc = 0; try { while ((rc = inputStream.read(buff, 0, 512)) > 0) { swapStream.write(buff, 0, rc); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { swapStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } GifDrawable drawable=null; if(swapStream.size()>0){ drawable=new GifDrawable(swapStream.toByteArray()); Message message=handler.obtainMessage(1,drawable); handler.sendMessage(message); imageMap.put(imageUrl,drawable); chackMapSize(); } else{ Message message=handler.obtainMessage(1,drawable); handler.sendMessage(message); imageMap.remove(imageUrl); } // if(drawable!=null){ // FileOutputStream fout=null; // try { // if(!mf.exists()){ // mf.createNewFile(); // } // fout=new FileOutputStream(mf); // fout.write(swapStream.toByteArray()); // fout.flush(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } finally { // try { // if(fout!=null){ // fout.close(); // } // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } // } } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }); return null; } private void chackMapSize(){ if(imageMap.size()>cacheMaxNum){ for(Entry<String, GifDrawable> m:imageMap.entrySet()){ imageMap.remove(m.getKey()); break; } } } public interface GifLoadCallback { public void onSuccess(GifDrawable drawable,int tag,View viewParent); } }
运行看看:
注:这是一个.gif动图,ctrl点击图片查看
不要气馁——2017/06/07