Android(java)学习笔记147:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)
1. 有时候Android系统配置的UI控件,不能满足我们的需求,Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高。
2. 下面我们是自定义一个SmartImageView继承自ImageView,扩展了ImageView的功能:
步骤:
• 新建一个SmartImageView类,让继承自ImageView(放置特定的包下);
• 实现SmartImageView类下的构造方法,最好全部实现,这个不容易出现问题,同时子类不能剥夺父类的构造方法;
• 扩展功能方法setImageUrl,通过设置一个网络的路径给SmartImageView,SmartImageView会自动的把这个路径对应的图片下载下来;
3. 下面我结合一个具体的案例形象说明一下:
(1)新建一个Android工程,命名为" 网易新闻客户端_自定义控件(SmartImageView)",同时新建一个类为SmartImageView让它继承自ImageView,这里我们暂时不必理会布局文件activity_main.xml和MainActivity.java;
如下图:
(2)接下来我们编写SmartImageView,扩展ImageView的功能:
1 package com.himi.smart; 2 3 import java.io.InputStream; 4 import java.net.HttpURLConnection; 5 import java.net.URL; 6 7 import android.content.Context; 8 import android.graphics.Bitmap; 9 import android.graphics.BitmapFactory; 10 import android.os.Handler; 11 import android.os.Message; 12 import android.util.AttributeSet; 13 import android.widget.ImageView; 14 15 /** 16 * 实现一个子类,扩展系统的ImageView 17 * @author Administrator 18 * 19 */ 20 public class SmartImageView extends ImageView { 21 22 private static final int SUCCESS = 1; 23 private Handler handler = new Handler() { 24 public void handleMessage(android.os.Message msg) { 25 switch (msg.what) { 26 case SUCCESS: 27 Bitmap bitmap = (Bitmap) msg.obj; 28 setImageBitmap(bitmap); 29 break; 30 31 default: 32 //其他消息,都是获取图片失败 33 break; 34 } 35 36 }; 37 }; 38 39 public SmartImageView(Context context, AttributeSet attrs, int defStyle) { 40 super(context, attrs, defStyle); 41 // TODO 自动生成的构造函数存根 42 } 43 44 public SmartImageView(Context context, AttributeSet attrs) { 45 super(context, attrs); 46 // TODO 自动生成的构造函数存根 47 } 48 49 public SmartImageView(Context context) { 50 super(context); 51 // TODO 自动生成的构造函数存根 52 } 53 54 /** 55 * 设置一个网络的路径给imageview,imageview会自动的把这个路径对应的图片下载下来 56 * @param path 图片的路径 57 */ 58 59 public void setImageUrl(final String path) { 60 new Thread() { 61 public void run() { 62 try { 63 URL url = new URL(path); 64 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 65 conn.setConnectTimeout(5000); 66 conn.setReadTimeout(5000); 67 conn.setRequestMethod("GET"); 68 int code = conn.getResponseCode(); 69 if(code ==200) { 70 InputStream is = conn.getInputStream();//获得服务器端的图片文件的输入流 71 Bitmap bitmap = BitmapFactory.decodeStream(is);//将服务器端的图片文件的输入流 转化为 Bitmap图片文件 72 //setImageBitmap(bitmap);子线程不能更新UI,这里要使用消息机制 73 Message msg = Message.obtain(); 74 msg.obj = bitmap; 75 msg.what = SUCCESS; 76 handler.sendMessage(msg); 77 } 78 } catch (Exception e) { 79 e.printStackTrace(); 80 handler.sendEmptyMessage(0); 81 } 82 83 84 }; 85 }.start(); 86 } 87 88 }
这里我们上面说过了我们最好实现全部的构造方法,在扩展方法setImageUrl():它是利用网络路径(String),获取网络上的图片资源,这里用到了网络操作,必然是耗时的操作,我们定义的SmartImageView到时候必然运行在主线程,我们知道网络操作不能放在主线程(UI主线程),所以这里新建了一个子线程new Thread()再结合handler(消息机制)实现UI更新。
(3)接下来我们回到activity_main.xml布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.himi.smart.MainActivity" > <com.himi.smart.SmartImageView android:id="@+id/iv" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
添加一个我们定义的SmartImageView控件,设置其他参数和ImageView一样(SmartImageView继承自ImageView),这里特别注意:
开始标签是 " 包名+控件类名 ",比如这里的是:
<com.himi.smart.SmartImageView
android:id="@+id/iv"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
(4)接下来自然是使用,回到MainActivity.java:
package com.himi.smart; import com.himi.hebao.R; import android.app.Activity; import android.os.Bundle; import android.widget.ImageView; public class MainActivity extends Activity { private SmartImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (SmartImageView) findViewById(R.id.iv); iv.setImageUrl("http://a.hiphotos.baidu.com/image/pic/item/cf1b9d16fdfaaf51ebc1c2be8e5494eef01f7a94.jpg"); } }
这里的"http://a.hiphotos.baidu.com/image/pic/item/cf1b9d16fdfaaf51ebc1c2be8e5494eef01f7a94.jpg"是网络图片的路径,如下:
(5)不要忘记在AndroidManifest.xml添加网络权限: <uses-permission android:name="android.permission.INTERNET"/>
布署程序到模拟器上面:
备注:这里编写的SmartImageView是为了后面Android(java)学习笔记205网易新闻UI实现的扩展类,下篇就是详细说明如何编写一个网易新闻的客户端