加载ImageView
# 加载网络图片
获取网络图片
/**
* 获取网落图片资源
* @param url
* @return
*/
public static Bitmap getHttpBitmap(String url){
URL myFileURL;
Bitmap bitmap=null;
try {
myFileURL = new URL(url);
// 获得连接
HttpURLConnection conn=(HttpURLConnection)myFileURL.openConnection();
// 设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制
conn.setConnectTimeout(6000);
// 连接设置获得数据流
conn.setDoInput(true);
// 不使用缓存
conn.setUseCaches(false);
conn.connect();
// 得到数据流
InputStream is = conn.getInputStream();
// 解析得到图片
bitmap = BitmapFactory.decodeStream(is);
// 关闭数据流
is.close();
} catch(Exception e){
e.printStackTrace();
}
return bitmap;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Activity中使用
public class MainActivity extends Activity {
// 定义一个图片显示控件
private ImageView imageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 图片资源
String url = "http://s16.sinaimg.cn/orignal/89429f6dhb99b4903ebcf&690";
// 得到可用的图片
Bitmap bitmap = getHttpBitmap(url);
imageView = (ImageView)this.findViewById(R.id.imageViewId);
// 显示
imageView.setImageBitmap(bitmap);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 自定义ImageView
传入URL,直接下载ImageView
public class BaseImageView extends androidx.appcompat.widget.AppCompatImageView {
private String imagePath;
// 是否启用缓存
public boolean isUseCache = false;
public static final int GET_DATA_SUCCESS = 1;
public static final int NETWORK_ERROR = 2;
public static final int SERVER_ERROR = 3;
// 子线程不能操作UI,通过Handler设置图片
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_DATA_SUCCESS:
Bitmap bitmap = (Bitmap) msg.obj;
setImageBitmap(bitmap);
break;
case NETWORK_ERROR:
Toast.makeText(getContext(), "网络连接失败", Toast.LENGTH_SHORT).show();
break;
case SERVER_ERROR:
Toast.makeText(getContext(), "服务器发生错误", Toast.LENGTH_SHORT).show();
break;
}
}
};
public BaseImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public BaseImageView(Context context) {
super(context);
}
public BaseImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//设置网络图片
public void setImageURL(String path) {
imagePath = path;
if (isUseCache) {
useCacheImage();
} else {
useNetWorkImage();
}
}
//使用网络图片显示
public void useNetWorkImage() {
//开启一个线程用于联网
new Thread() {
@Override
public void run() {
try {
//把传过来的路径转成URL
URL url = new URL(imagePath);
//获取连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//使用GET方法访问网络
connection.setRequestMethod("GET");
//超时时间为10秒
connection.setConnectTimeout(10000);
//获取返回码
int code = connection.getResponseCode();
if (code == 200) {
Bitmap bitmap;
//获取网络输入流
InputStream inputStream = connection.getInputStream();
//判断是否使用缓存图片
if (isUseCache) {
//因为InputStream要使用两次,但是使用一次就无效了,所以需要复制两个
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
} catch (IOException e) {
e.printStackTrace();
}
//复制新的输入流
InputStream is = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());
//调用压缩方法显示图片
bitmap = getCompressBitmap(is);
//调用缓存图片方法
cacheImage(is2);
} else {
//调用压缩方法
bitmap = getCompressBitmap(inputStream);
}
//利用Message把图片发给Handler
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what = GET_DATA_SUCCESS;
handler.sendMessage(msg);
inputStream.close();
} else {
//服务启发生错误
handler.sendEmptyMessage(SERVER_ERROR);
}
} catch (IOException e) {
e.printStackTrace();
//网络连接错误
handler.sendEmptyMessage(NETWORK_ERROR);
}
}
}.start();
}
//使用缓存图片
public void useCacheImage() {
//创建路径一样的文件
File file = new File(getContext().getCacheDir(), getURLPath());
//判断文件是否存在
if (file != null && file.length() > 0) {
//使用本地图片
try {
InputStream inputStream = new FileInputStream(file);
//调用压缩方法显示图片
Bitmap bitmap = getCompressBitmap(inputStream);
// 利用Message把图片发给Handler
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what = GET_DATA_SUCCESS;
handler.sendMessage(msg);
Log.e("BaseImageView", "使用缓存图片");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
//使用网络图片
useNetWorkImage();
Log.e("MyImageView", "使用网络图片");
}
}
/**
* 缓存网络的图片
*
* @param inputStream 网络的输入流
*/
public void cacheImage(InputStream inputStream) {
try {
File file = new File(getContext().getCacheDir(), getURLPath());
FileOutputStream fos = new FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
Log.e("MyImageView", "缓存成功");
} catch (IOException e) {
e.printStackTrace();
Log.e("MyImageView", "缓存失败");
}
}
/**
* 根据网址生成一个文件名
*
* @return 文件名
*/
public String getURLPath() {
StringBuilder urlStr2 = new StringBuilder();
String[] strings = imagePath.split("\\/");
for (String string : strings) {
urlStr2.append(string);
}
Log.e("MyImageView", "文件名:" + urlStr2.toString());
return urlStr2.toString();
}
/**
* 根据输入流返回一个压缩的图片
*
* @param input 图片的输入流
* @return 压缩的图片
*/
public Bitmap getCompressBitmap(InputStream input) {
//因为InputStream要使用两次,但是使用一次就无效了,所以需要复制两个
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
} catch (IOException e) {
e.printStackTrace();
}
//复制新的输入流
InputStream is = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());
//只是获取网络图片的大小,并没有真正获取图片
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
//获取图片并进行压缩
options.inSampleSize = getInSampleSize(options);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(is2, null, options);
}
/**
* 获得需要压缩的比率
* @param options 需要传入已经BitmapFactory.decodeStream(is, null, options);
* @return 返回压缩的比率,最小为1
*/
public int getInSampleSize(BitmapFactory.Options options) {
int inSampleSize = 1;
int realWith = realImageViewWith();
int realHeight = realImageViewHeight();
int outWidth = options.outWidth;
Log.e("网络图片实际的宽度", String.valueOf(outWidth));
int outHeight = options.outHeight;
Log.e("网络图片实际的高度", String.valueOf(outHeight));
//获取比率最大的那个
if (outWidth > realWith || outHeight > realHeight) {
int withRadio = Math.round(outWidth / realWith);
int heightRadio = Math.round(outHeight / realHeight);
inSampleSize = withRadio > heightRadio ? withRadio : heightRadio;
}
Log.e("压缩比率", String.valueOf(inSampleSize));
return inSampleSize;
}
/**
* 获取ImageView实际的宽度
*
* @return 返回ImageView实际的宽度
*/
public int realImageViewWith() {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
ViewGroup.LayoutParams layoutParams = getLayoutParams();
//如果ImageView设置了宽度就可以获取实在宽带
int width = getWidth();
if (width <= 0) {
//如果ImageView没有设置宽度,就获取父级容器的宽度
width = layoutParams.width;
}
if (width <= 0) {
//获取ImageView宽度的最大值
width = getMaxWidth();
}
if (width <= 0) {
//获取屏幕的宽度
width = displayMetrics.widthPixels;
}
Log.e("ImageView实际的宽度", String.valueOf(width));
return width;
}
/**
* 获取ImageView实际的高度
*
* @return 返回ImageView实际的高度
*/
public int realImageViewHeight() {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
ViewGroup.LayoutParams layoutParams = getLayoutParams();
//如果ImageView设置了高度就可以获取实在宽度
int height = getHeight();
if (height <= 0) {
//如果ImageView没有设置高度,就获取父级容器的高度
height = layoutParams.height;
}
if (height <= 0) {
//获取ImageView高度的最大值
height = getMaxHeight();
}
if (height <= 0) {
//获取ImageView高度的最大值
height = displayMetrics.heightPixels;
}
Log.e("ImageView实际的高度", String.valueOf(height));
return height;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
控件布局使用
<top.iqqcode.demo.load.TaskImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
1
2
3
4
2
3
4
自定义ImageView使用
// 直接把网络的图片路径写上就可以显示网络的图片了
String url = "";
// 设置成true才会启动缓存,默认是false
myImageView.isUseCache = true;
myImageView.setImageURL(url);
1
2
3
4
5
2
3
4
5
编辑 (opens new window)
上次更新: 2021/09/05, 15:01:20