# Volley之NetWorkImageView的源码解析与用法:
来源:互联网 发布:真正的绝望是什么知乎 编辑:程序博客网 时间:2024/06/07 05:30
- NetWorkImageView源码解析
- NetWorkImageView具体使用
- 总结
NetWorkImageView源码解析
/** * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.volley.toolbox;import android.content.Context;import android.text.TextUtils;import android.util.AttributeSet;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;import com.android.volley.VolleyError;import com.android.volley.toolbox.ImageLoader.ImageContainer;import com.android.volley.toolbox.ImageLoader.ImageListener;/** * *从URL中获取图像以及相关请求的生命周期把控。 *这个控件在被从父控件detach的时候, 会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题, *而且NetworkImageView还会根据你对图片设置的width和heigh自动压缩该图片不会产生多的内存,减少OOM *还有NetworkImageView在列表中使用不会图片错位 */public class NetworkImageView extends ImageView { /*网络加载的图片地址*/ private String mUrl; /** * *在网络加载之前用作占位符的图像的资源ID,即默认图片 */ private int mDefaultImageId; /** * * 如果网络响应失败,将显示失败的图像资源ID。 */ private int mErrorImageId; /*本地Volley封装的图片加载类ImageLoader*/ private ImageLoader mImageLoader; /*当前的图片容器,负责图片暂存和清除 private ImageContainer mImageContainer; public NetworkImageView(Context context) { this(context, null); } public NetworkImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public NetworkImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * *设置要加载到该视图中的图像ur,注意:通过ImageLoader可立即设置缓存的图像(如果有)或默认的图像指定 * @param url 加载图片的地址 * @param imageLoader 处理加载图片的类 */ public void setImageUrl(String url, ImageLoader imageLoader) { mUrl = url; mImageLoader = imageLoader; // 如果网址发生改变,看看是否需要加载 loadImageIfNecessary(false); } /** * 设置要用于此视图的默认图像资源ID, */ public void setDefaultImageResId(int defaultImage) { mDefaultImageId = defaultImage; } /** *网络加载失败后显示错误图像资源ID */ public void setErrorImageResId(int errorImage) { mErrorImageId = errorImage; } /** * 在没有赋值之前,进行图片布局尺判断(如宽、高) * @param isInLayoutPass 如果这是一个真正的isinlayoutpass布局通过调用,否则为假。 */ private void loadImageIfNecessary(final boolean isInLayoutPass) { int width = getWidth(); int height = getHeight(); boolean isFullyWrapContent = getLayoutParams() != null && getLayoutParams().height == LayoutParams.WRAP_CONTENT && getLayoutParams().width == LayoutParams.WRAP_CONTENT; // 如果视图的边界还不知道,而且不是一个内容包裹,关闭加载图像。 if (width == 0 && height == 0 && !isFullyWrapContent) { return; } // 如果在此视图中加载的URL为空,请取消任何旧请求并清除当前加载的图像。 if (TextUtils.isEmpty(mUrl)) { if (mImageContainer != null) { mImageContainer.cancelRequest(); mImageContainer = null; } setDefaultImageOrNull(); return; } // 如果此视图中有旧请求,请检查是否需要取消。 if (mImageContainer != null && mImageContainer.getRequestUrl() != null) { if (mImageContainer.getRequestUrl().equals(mUrl)) { // 如果请求来自同一URL,返回空,亲测这里设计有些小bug。 return; } else { // 如果它正在获取一个不同的URL。取消预先存在的请求,重设视图, mImageContainer.cancelRequest(); setDefaultImageOrNull(); } } // 此视图的预先存在的内容与当前URL不匹配。从网络加载新的图片。 ImageContainer newContainer = mImageLoader.get(mUrl, new ImageListener() { @Override public void onErrorResponse(VolleyError error) { if (mErrorImageId != 0) { setImageResource(mErrorImageId); } } @Override public void onResponse(final ImageContainer response, boolean isImmediate) { //如果这是一个即时的反应,不设置图像立即就会引发requestLayout方法。相反,推迟返回到主线程设置图像。 if (isImmediate && isInLayoutPass) { post(new Runnable() { @Override public void run() { onResponse(response, false); } }); return; } if (response.getBitmap() != null) { setImageBitmap(response.getBitmap()); } else if (mDefaultImageId != 0) { setImageResource(mDefaultImageId); } } }); // 更新imagecontainer成为新的位图容器 mImageContainer = newContainer; }/***图片为空或者加载失败,对应情况的处理*/ private void setDefaultImageOrNull() { if(mDefaultImageId != 0) { setImageResource(mDefaultImageId); } else { setImageBitmap(null); } }/***重写布局加载*/ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); loadImageIfNecessary(true); }/***重写从父容器移除的方法*/ @Override protected void onDetachedFromWindow() { //如果图片容器不为空,从父容器清空视图 if (mImageContainer != null) { // 从视图中取消并清除/输出图像。 mImageContainer.cancelRequest(); setImageBitmap(null); // 如有必要, 清除容器,以便我们可以重新加载图像。 mImageContainer = null; } super.onDetachedFromWindow(); }/***图片发生改变(宽高的属性等),立即更新视图*/ @Override protected void drawableStateChanged() { super.drawableStateChanged(); invalidate(); }}
NetWorkImageView具体使用:
布局文件中的xml中使用方法:
<com.android.volley.toolbox.networkimageview android:id="@+id/image_view" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginTop="10dp"/>
MainActivity网络请求展示图片
public class MainActivity extends Activity { private String path = "http://img.kaiyanapp.com/2729ed6cef6b267d456c9aacfad67b38.jpeg"; private NetworkImageView image_view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化控件image_view(NetworkImageView)findViewById(R.id.image_view);//图片加载 loadImageView(this, netWorkImageView, path); } /** * * @param mainActivity * */ private void loadImageView(MainActivity mainActivity, NetworkImageView iv,String url) { //实例化imageLoader ImageLoader imageLoader = new ImageLoader( Volley.newRequestQueue(mainActivity.getApplicationContext()), new ImageLoader.ImageCache() { @Override public Bitmap getBitmap(String s) { return null; } @Override public void putBitmap(String s, Bitmap bitmap) { } });iv.setDefaultImageResId(android.R.drawable.ic_menu_camera);iv.setErrorImageResId(android.R.drawable.ic_menu_delete);iv.setImageUrl(url, imageLoader); }}
总结
- 丛源码解析中可以看出,volley自带的图片控件可以显示不同状态的视图。
- 通过setImageUrl(String url, ImageLoader imageLoader)即可实现视图的展示,注意两次请求的地址一样,会返回空,不显示视图。
- 这里没有具体对图片颜色、质量等的处理,所以倘若要封装一个考虑到这些的图片控件,还是需要做些处理。
阅读全文
0 0
- # Volley之NetWorkImageView的源码解析与用法:
- Volley之ImageLoader与NetworkImageView
- Volley源码阅读——NetworkImageView
- Android Volley完全解析之Volley的基本用法
- volley的源码解析
- Volley库的NetworkImageView怎么用
- Android 网络连接:Volley(齐射)之ImageRequest与NetworkImageView网络图片下载
- Android之Volley 源码解析
- volley源码解析(六)--HurlStack与HttpClientStack之争
- Volley之ImageLoader用法解析
- Volley学习(三)ImageRequest、ImageLoader、NetworkImageView源码简读
- 【Volley】Volley源码解析
- 迟到的Volley源码解析
- Android Volley完全解析之从源码的角度理解Volley
- volley源码解析(三)--Volley核心之RequestQueue类
- AndroidFramework之Volley源码详细解析 (四)
- 使用Volley 的NetWorkImageView报空指针问题
- Android结合volley的netWorkImageview实现图片文件缓存
- 安装Mysql5.7并修改初始密码
- C++(qt)游戏实战项目:坦克大战(三)
- 关于L1和L2的一些思考
- c++实现链表 增,删,查,合并
- Java使用redis+sse实现带频道的网络聊天室
- # Volley之NetWorkImageView的源码解析与用法:
- 用户用户组配置文件相关文件格式说明
- bisonExe was not found
- 高次方尾数
- 通讯录——(C语言文件版本)
- (16)spring boot中集成Redis实例
- 第二十天 init初始化servlet,查询注入给Servlet的参数值
- 端午在即,难忘的经历——记一次php单次任务处理对内存超大需求的解决
- 字节序