23
23
24
24
25
25
26
-
26
+
27
27
在上图中可以看出,Adaptee类并没有sampleOperation2\(\) 方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的:
28
28
29
29
模式所涉及的角色有:
@@ -82,7 +82,7 @@ public class Adapter extends Adaptee implements Target {
82
82
83
83
84
84
85
-
85
+
86
86
从上图可以看出,Adaptee类并没有sampleOperation2\(\) 方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装\( Wrapper\) 类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
87
87
88
88
``` java
@@ -168,53 +168,47 @@ JDK1.1 之前提供的容器有 Arrays,Vector,Stack,Hashtable,Properties,BitSet
168
168
``` java
169
169
Vector v= new Vector ();
170
170
for (Enumeration enum = v. elements(); enum. hasMoreElements();) {
171
- Object o = enum. nextElement();
172
- processObject(o);
171
+ Object o = enum. nextElement();
172
+ processObject(o);
173
173
}
174
174
```
175
175
176
176
JDK1.2 版本中引入了 Iterator 接口,新版本的集合对(HashSet,HashMap,WeakHeahMap,ArrayList,TreeSet,TreeMap, LinkedList)是通过 Iterator 接口访问集合元素。
177
177
178
178
``` java
179
179
List list= new ArrayList ();
180
- for (Iterator it= list. iterator();it. hasNext();)
181
- {
182
- System . out. println(it. next());
180
+ for (Iterator it= list. iterator();it. hasNext();){
181
+ System . out. println(it. next());
183
182
}
184
183
```
185
184
186
185
这样,如果将老版本的程序运行在新的 Java 编译器上就会出错。因为 List 接口中已经没有 elements\(\) ,而只有 iterator\(\) 了。那么如何将老版本的程序运行在新的 Java 编译器上呢? 如果不加修改,是肯定不行的,但是修改要遵循“开-闭”原则。我们可以用 Java 设计模式中的适配器模式解决这个问题。
187
186
188
187
``` java
189
- public class NewEnumeration implements Enumeration
190
- {
191
-
192
- Iterator it;
193
- public NewEnumeration (Iterator it )
194
- {
195
- this . it= it;
196
- }
197
-
198
- public boolean hasMoreElements ()
199
- {
200
- return it. hasNext();
201
- }
202
-
203
- public Object nextElement ()
204
- {
205
- return it. next();
206
- }
207
- public static void main (String [] args )
208
- {
209
- List list= new ArrayList ();
210
- list. add(" a" );
211
- list. add(" b" );
212
- list. add(" C" );
213
- for (Enumeration e= new NewEnumeration (list. iterator());e. hasMoreElements();)
214
- {
215
- System . out. println(e. nextElement());
216
- }
217
- }
188
+ public class NewEnumeration implements Enumeration {
189
+ Iterator it;
190
+
191
+ public NewEnumeration (Iterator it ) {
192
+ this . it = it;
193
+ }
194
+
195
+ public boolean hasMoreElements () {
196
+ return it. hasNext();
197
+ }
198
+
199
+ public Object nextElement () {
200
+ return it. next();
201
+ }
202
+
203
+ public static void main (String [] args ) {
204
+ List list = new ArrayList ();
205
+ list. add(" a" );
206
+ list. add(" b" );
207
+ list. add(" C" );
208
+ for (Enumeration e = new NewEnumeration (list. iterator()); e. hasMoreElements(); ) {
209
+ System . out. println(e. nextElement());
210
+ }
211
+ }
218
212
}
219
213
```
220
214
@@ -225,63 +219,56 @@ NewEnumeration 是一个适配器类,通过它实现了从 Iterator 接口到
225
219
在开发过程中,ListView的Adapter是我们最为常见的类型之一。一般的用法大致如下:
226
220
227
221
``` java
228
- // 代码省略
229
- ListView myListView = (ListView )findViewById(listview_id);
230
- // 设置适配器
231
- myListView. setAdapter(new MyAdapter (context, myDatas));
222
+ // 代码省略
223
+ ListView myListView = (ListView ) findViewById(listview_id);
224
+ // 设置适配器
225
+ myListView. setAdapter(new MyAdapter (context,myDatas));
232
226
233
227
// 适配器
234
- public class MyAdapter extends BaseAdapter {
235
-
236
- private LayoutInflater mInflater;
237
- List
238
- <
239
- String
240
- >
241
- mDatas ;
242
-
243
- public MyAdapter (Context context , List
244
- <
245
- String
246
- >
247
- datas ){
248
- this . mInflater = LayoutInflater . from(context);
249
- mDatas = datas ;
250
- }
251
- @Override
252
- public int getCount () {
253
- return mDatas. size();
254
- }
228
+ public class MyAdapter extends BaseAdapter {
255
229
256
- @Override
257
- public String getItem (int pos ) {
258
- return mDatas. get(pos);
259
- }
230
+ private LayoutInflater mInflater;
231
+ List<String > mDatas;
260
232
261
- @Override
262
- public long getItemId ( int pos ) {
263
- return pos ;
264
- }
233
+ public MyAdapter ( Context context , List< String > datas ) {
234
+ this . mInflater = LayoutInflater . from(context);
235
+ mDatas = datas ;
236
+ }
265
237
266
- // 解析、设置、缓存convertView以及相关内容
267
- @Override
268
- public View getView (int position , View convertView , ViewGroup parent ) {
269
- ViewHolder holder = null ;
270
- // Item View的复用
271
- if (convertView == null ) {
272
- holder = new ViewHolder ();
273
- convertView = mInflater. inflate(R . layout. my_listview_item, null );
274
- // 获取title
275
- holder. title = (TextView )convertView. findViewById(R . id. title);
276
- convertView. setTag(holder);
277
- } else {
278
- holder = (ViewHolder )convertView. getTag();
279
- }
280
- holder. title. setText(mDatas. get(position));
281
- return convertView;
282
- }
238
+ @Override
239
+ public int getCount () {
240
+ return mDatas. size();
241
+ }
242
+
243
+ @Override
244
+ public String getItem (int pos ) {
245
+ return mDatas. get(pos);
246
+ }
247
+
248
+ @Override
249
+ public long getItemId (int pos ) {
250
+ return pos;
251
+ }
283
252
253
+ // 解析、设置、缓存convertView以及相关内容
254
+ @Override
255
+ public View getView (int position , View convertView , ViewGroup parent ) {
256
+ ViewHolder holder = null ;
257
+ // Item View的复用
258
+ if (convertView == null ) {
259
+ holder = new ViewHolder ();
260
+ convertView = mInflater. inflate(R . layout. my_listview_item, null );
261
+ // 获取title
262
+ holder. title = (TextView ) convertView. findViewById(R . id. title);
263
+ convertView. setTag(holder);
264
+ } else {
265
+ holder = (ViewHolder ) convertView. getTag();
266
+ }
267
+ holder. title. setText(mDatas. get(position));
268
+ return convertView;
284
269
}
270
+
271
+ }
285
272
```
286
273
287
274
我们知道,作为最重要的View,ListView需要能够显示各式各样的视图,每个人需要的显示效果各不相同,显示的数据类型、数量等也千变万化。那么如何隔离这种变化尤为重要。
@@ -294,27 +281,22 @@ Android的做法是增加一个Adapter层来应对变化,**将ListView需要
294
281
ListView继承自AbsListView,Adapter定义在AbsListView中,我们看一看这个类。
295
282
296
283
``` java
297
- public abstract class AbsListView extends AdapterView
298
- <
299
- ListAdapter
300
- >
301
- implements TextWatcher ,
284
+ public abstract class AbsListView extends AdapterView<ListAdapter >
285
+ implements TextWatcher ,
302
286
ViewTreeObserver .OnGlobalLayoutListener , Filter .FilterListener ,
303
287
ViewTreeObserver .OnTouchModeChangeListener ,
304
288
RemoteViewsAdapter .RemoteAdapterConnectionCallback {
305
289
306
- ListAdapter mAdapter ;
290
+ ListAdapter mAdapter;
307
291
308
292
// 关联到Window时调用的函数
309
293
@Override
310
294
protected void onAttachedToWindow () {
311
295
super . onAttachedToWindow();
312
296
// 代码省略
313
297
// 给适配器注册一个观察者。
314
- if (mAdapter != null
315
- &
316
- &
317
- mDataSetObserver == null ) {
298
+ if (mAdapter != null &&
299
+ mDataSetObserver == null ){
318
300
mDataSetObserver = new AdapterDataSetObserver ();
319
301
mAdapter. registerDataSetObserver(mDataSetObserver);
320
302
@@ -327,7 +309,7 @@ ListAdapter
327
309
mIsAttached = true ;
328
310
}
329
311
330
- /**
312
+ /**
331
313
* 子类需要覆写layoutChildren()函数来布局child view,也就是Item View
332
314
*/
333
315
@Override
@@ -336,18 +318,14 @@ ListAdapter
336
318
mInLayout = true ;
337
319
if (changed) {
338
320
int childCount = getChildCount();
339
- for (int i = 0 ; i
340
- <
341
- childCount; i++ ) {
321
+ for (int i = 0 ; i< childCount; i++ ) {
342
322
getChildAt(i). forceLayout();
343
323
}
344
324
mRecycler. markChildrenDirty();
345
325
}
346
326
347
- if (mFastScroller != null
348
- &
349
- &
350
- mItemCount != mOldItemCount) {
327
+ if (mFastScroller != null &&
328
+ mItemCount != mOldItemCount){
351
329
mFastScroller. onItemCountChanged(mOldItemCount, mItemCount);
352
330
}
353
331
// 布局Child View
@@ -376,7 +354,7 @@ ListAdapter
376
354
377
355
return child;
378
356
}
379
- }
357
+ }
380
358
```
381
359
382
360
通过增加Adapter一层来将Item View的操作抽象起来,ListView等集合视图通过Adapter对象获得Item的个数、数据元素、Item View等,从而达到适配各种数据、各种Item视图的效果。
0 commit comments