• 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实现的扩展类,下篇就是详细说明如何编写一个网易新闻的客户端

     

  • 相关阅读:
    三大家族的作用和区别
    正则表达式
    Math的方法
    数组API方法
    面向对象方法
    数组的常用方法
    对象和数组的遍历方法
    js运算符(运算符的结合性)
    i++和++i的运算符
    flex
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4779043.html
Copyright © 2020-2023  润新知