当前位置: 首页 > wzjs >正文

b站倒过来的网站谁做的青岛seo排名收费

b站倒过来的网站谁做的,青岛seo排名收费,域名服务器的简称,夏天做那些网站能致富一、前言 适配器模式就是将两个不兼容的类融合在一起。通过转换使他们可以兼容的工作。Android代码中最常见的适配器就是Adapter了。ListView、GridView、RecyclerView都使用Adapter,Adapter的作用都一样,把高度定制化的item view和ListView分开。item view通过一个…

一、前言

适配器模式就是将两个不兼容的类融合在一起。通过转换使他们可以兼容的工作。Android代码中最常见的适配器就是Adapter了。ListView、GridView、RecyclerView都使用Adapter,Adapter的作用都一样,把高度定制化的item view和ListView分开。item view通过一个Adapter和ListView联系到一起。解耦而不失高度可定制。

二、适配器模式定义

将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作

三、例子

我们先来看下适配器模式的例子。学习到底什么是适配器模式。

3.1、我们举一个出水口出水量的例子。出水量有大有小,于是先定义两个接口

public interface BigOutlet {public void bigOutlet();
}public interface SmallOutlet {public void smallOutlet();
}
3.2、然后有一个出水口water tap。出水量大。

public class BigWaterTap implements BigOutlet {private static final String TAG = WaterTap.class.getSimpleName();@Overridepublic void bigOutlet() {Log.d(TAG,"bigOutlet");}
}
3.3、定义适配器

现在需求来了,我要出水口既能大量出水,也可以小量出水。而我们不能去更改BigWaterTap,因为通常很多时候一个类拟定好了过后,我们无法再去修改了。也没有源码。给它再继承SmallOutlet这个接口。我们需要的是另外的办法来添加出水量小的方法。这个时候适配器模式就派上用场了。
适配器模式写法有两种,这里先看第一种写法叫类适配器模式
类适配器模式

public class ClassWaterTapAdapter extends BigWaterTap implements SmallOutlet {private static final String TAG = ClassWaterTapAdapter.class.getSimpleName();@Overridepublic void smallOutlet() {Log.d(TAG,"smallOutlet");}
}

调用

ClassWaterTapAdapter classWaterTapAdapter = new ClassWaterTapAdapter();
classWaterTapAdapter.bigOutlet();
classWaterTapAdapter.smallOutlet();

输出这里就省略了。我们可以看到适配器模式就是把两个不兼容的类结合到了一起,即可以出水量大,也可以出水量小了。达到了融合的作用。而不用去改变原来的类。然后看下另一种写法。对象适配器模式,其实就是代理模式的写法。
对象适配器模式

public class ProxyWaterTapAdapter implements SmallOutlet {private static final String TAG = ProxyWaterTapAdapter.class.getSimpleName();private BigWaterTap bigWaterTap;public ProxyWaterTapAdapter(BigWaterTap bigWaterTap) {this.bigWaterTap = bigWaterTap;}public void adapterBigOutlet() {bigWaterTap.bigOutlet();}@Overridepublic void smallOutlet() {Log.d(TAG,"smallOutlet");}
}

调用

        ProxyWaterTapAdapter proxyWaterTapAdapter = new ProxyWaterTapAdapter(new BigWaterTap());proxyWaterTapAdapter.adapterBigOutlet();proxyWaterTapAdapter.smallOutlet();

一目了然,就是用代理的方式,拥有BigWaterTap来调用了bigOutlet。ProxyWaterTapAdapter就达到了兼容的目的。

4、小结

1、现在我们队适配器模式有个清晰的认识了。适配器就是不改变原有类的基础上,让它兼容别的接口方法,以实现新的功能,达到兼容的目的。
2、在我们开发过程中,笔者强烈建议最好还是使用对象适配器模式这种写法。对象适配器模式比类对象适配模式好处就是更加灵活,且不会暴露被适配者。因为继承了过后Adapter类中也有了一样的方法。

四、ListView与适配器模式

4.1、为了避免读者混淆,我先简单用上面的例子模拟一下Listview和适配器ListAdapter是如何工作的。

先写适配器ListWaterTapAdapter,等价于ListAdapter

public abstract class ListWaterTapAdapter implements SmallOutlet{public abstract void middleOutlet();
}

ListWaterTapAdapter抽象类,需要我们客户使用的时候具体去实现。然后重新写一下BigWaterTap,因为它本身有的功能就是bigOutlet()。等价于listview

public class ListViewWaterTap implements BigOutlet{private static final String TAG = ListViewWaterTap.class.getSimpleName();private ListWaterTapAdapter listWaterTapAdapter;@Overridepublic void bigOutlet() {Log.d(TAG,"bigOutlet");}public void setAdapter(ListWaterTapAdapter listWaterTapAdapter) {this.listWaterTapAdapter = listWaterTapAdapter;}public void smallToBigOutlet() {listWaterTapAdapter.smallOutlet();int i = 100;while (i-- > 0);listWaterTapAdapter.middleOutlet();}
}

这里的ListViewWaterTap并非适配器。我们的适配器就是ListWaterTapAdapter。setAdapter来拥有适配器抽象类,调用抽象方法,让客户自己去实现smallOutlet和middleOutlet这两个方法。接着我们看下调用

        ListViewWaterTap listViewWaterTap = new ListViewWaterTap();ListWaterTapAdapter listWaterTapAdapter = new ListWaterTapAdapter() {@Overridepublic void middleOutlet() {Log.d(TAG,"middleOutlet");}@Overridepublic void smallOutlet() {Log.d(TAG,"smallOutlet");}};listViewWaterTap.setAdapter(listWaterTapAdapter);listViewWaterTap.bigOutlet();listViewWaterTap.smallToBigOutlet();

这里就是和listview与adapter一样的用法了。并不是标准的适配器模式写法。但确实最经典的适配器模式应用。下面我们来分析一下listview和adapter的关系。

4.2、ListView和ListAdapter

首先说下ListView用适配器模式的目的就是让listview的每个item可以客户自己高度定制化。你自己去实现就行了。无论你如何定制item使用就是一个view。listview用适配器模式就完美的达到了这个效果。
以下有射猎源码的地方,来自Android P。"..."代表省略代码

4.2.1、首先来一个普通示例

    listView = (ListView) findViewById(R.id.listView);MyAdapter myAdapter = new MyAdapter(this,mListTile);public class MyAdapter extends BaseAdapter {private LayoutInflater layoutInflater;List<String> litTile;public MyAdapter(Context context, List<String> listTile) {layoutInflater = LayoutInflater.from(context);this.litTile = listTile;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {holder = new ViewHolder();convertView = layoutInflater.inflate(R.layout.layout_item,null);holder.title = (TextView) convertView.findViewById(R.id.title);convertView.setTag(holder);} else {holder = (ViewHolder)convertView.getTag();}holder.title.setText(litTile.get(position));return convertView;}class ViewHolder{public TextView title;}
// 篇幅原因,省略getCount、getItem和getItemId

这是我们最普通的运用listview的写法了。然后我们从适配器讲起,先看adapter是个啥
listview.java的setAdapter方法

@Overridepublic void setAdapter(ListAdapter adapter) {...
}

看看BaseAdapter的集成关系,然后开始讲适配器BaseAdapter

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { ... }public interface ListAdapter extends Adapter { ... }public interface Adapter { ... }

4.2.2、适配器

为了节约篇幅我把注释删了。看Adapater代码如下:

public interface Adapter {void registerDataSetObserver(DataSetObserver observer);void unregisterDataSetObserver(DataSetObserver observer);int getCount();   Object getItem(int position);long getItemId(int position);boolean hasStableIds();View getView(int position, View convertView, ViewGroup parent);static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE;int getItemViewType(int position);int getViewTypeCount();static final int NO_SELECTION = Integer.MIN_VALUE;boolean isEmpty();default @Nullable CharSequence[] getAutofillOptions() {return null;}
}

1>根据上面的继承关系,BaseAdapter跟开始举例一样,抽象类来定义适配器,要实现的接口是Adapter
2> 可以看到Adapter就是接口,接口的这些方法是要提供给ListView内部使用的。我们自己实现Adapter,完成这些接口,或者抽象方法。

4.2.3、listview如何使用adapter

首先看下listView的继承关系

public class ListView extends AbsListView { ... }public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,ViewTreeObserver.OnTouchModeChangeListener,RemoteViewsAdapter.RemoteAdapterConnectionCallback { ... }public abstract class AdapterView<T extends Adapter> extends ViewGroup { ... }

ListView就是一个ViewGroup,然后通过主要的逻辑实现代码就在ListView.java和AbsListView.java了

先讲一个getCount
在AbsListView.java的onAttachedToWindow方法

    protected void onAttachedToWindow() {super.onAttachedToWindow();...if (mAdapter != null && mDataSetObserver == null) {mDataSetObserver = new AdapterDataSetObserver();mAdapter.registerDataSetObserver(mDataSetObserver);// Data may have changed while we were detached. Refresh.mDataChanged = true;mOldItemCount = mItemCount;mItemCount = mAdapter.getCount();}}

把view关联到window的时候,mAdapter.getCount(),这个getConut是我们继承时写的,就确定了我们这个listView有多少个item了。

再梳理一下getView是如何把item view加载出来的
大致流程如下,这里就只列出简化的代码了,本文主要理解适配器模式的思想
1>AbsListView:onlayout

 protected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);...layoutChildren();....}

ViewGroup是组合模式,它在调用onlayout的时候调用layoutChildren来布局子控件,layoutChildren在AbsListView是一个空实现,实现代码在ListView
2>ListView:layoutChildren

protected void layoutChildren() {...switch (mLayoutMode) {...case LAYOUT_FORCE_BOTTOM:sel = fillUp(mItemCount - 1, childrenBottom);adjustViewsUpOrDown();break;case LAYOUT_FORCE_TOP:mFirstPosition = 0;sel = fillFromTop(childrenTop);adjustViewsUpOrDown();break;

调用到layoutChildren后来布局item view.
3>ListView:fillDown

private View fillDown(int pos, int nextTop) {...while (nextTop < end && pos < mItemCount) {// is this the selected item?boolean selected = pos == mSelectedPosition;View child = makeAndAddView(pos, nextTop, true, mListPadding.left, selected);nextTop = child.getBottom() + mDividerHeight;if (selected) {selectedView = child;}pos++;}

每个子view都是调用makeAndAddView然后调用AbsListView的obtainView方法

private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,boolean selected) {...final View child = obtainView(position, mIsScrap);

4>AbsListView:obtainView

 View obtainView(int position, boolean[] outMetadata) {...final View scrapView = mRecycler.getScrapView(position);final View child = mAdapter.getView(position, scrapView, this);if (scrapView != null) {if (child != scrapView) {// Failed to re-bind the data, return scrap to the heap.mRecycler.addScrapView(scrapView, position);} else if (child.isTemporarilyDetached()) {outMetadata[0] = true;// Finish the temporary detach started in addScrapView().child.dispatchFinishTemporaryDetach();}}...
}

这里用到了mAdapter.getView。从ListView布局每个item view的过程来看,最后布局使用view的时候就用到了我们去实现的getView方法返回的view。

我们对listview优化的时候,为啥写法是判断if (convertView == null)
接着分析上面第四步的代码
mRecycler.getScrapView是获得可复用的view,然后带入mAdapter.getView(position, scrapView, this);
如果还没有被加入到缓存list则

if (child != scrapView) {// Failed to re-bind the data, return scrap to the heap.mRecycler.addScrapView(scrapView, position);
} 

所以我们写代码的时候则这样来优化判断,当然获得缓存后数据也是原来的。所以我们要重新设置title

     if (convertView == null) {holder = new ViewHolder();convertView = layoutInflater.inflate(R.layout.layout_item,null);holder.title = (TextView) convertView.findViewById(R.id.title);convertView.setTag(holder);} else {holder = (ViewHolder)convertView.getTag();}holder.title.setText(litTile.get(position));

这里ListView和ListAdapter的关系就梳理到这里了。有兴趣的同学还可以去看看GridView,RecyleView喔。比如RecycleView就是ListView的一个升级版,RecycleView定义了ViewHolder的机制。更加巧妙。

五、总结

适配器模式就是将原本不兼容的接口融合在一起,以便更好的协同合作。当然设计模式不是一成不变的,litview的adapter就是很好的一个变化,让UI更加高度可定制化而不失自身实现。
优点:
1、把接口和类结合,通过适配器可以让接口定义的功能更好的复用。
2、扩展性好,不光可调用自己开发的功能,还自然的扩展了接口定义的其它功能。
缺点:
不易滥用,如果你的代码有n多个适配器,你想想那场面,调用十分凌乱,还不如直接修改源码设计更好的public api。
还是那句话,设计模式主要理解它的精髓。并不是一成不变。多思考是否应该使用这个设计模式才能事半功倍。

http://www.dtcms.com/wzjs/5208.html

相关文章:

  • 长沙网站设计工作室百度在全国有哪些代理商
  • 深圳挖矿app开发百度推广优化师是什么
  • 我的个人网页设计效果图seo技巧是什么意思
  • 做网站服务器还是虚拟空间好seo咨询河北
  • python入门教程完整版网络seo招聘
  • 邢台做网站可信赖广告推广语
  • 套模板做网站流程网站怎么注册
  • 网站主题网西安网约车平台
  • 机关事业单位网站建设北京网站外包
  • 有哪些做高考模拟卷的网站北京seo公司工作
  • 做淘宝客网站需要多大带宽cpv广告联盟
  • 杭州萧山区专门做网站的公司武汉百度推广开户
  • 做网站排名多少钱深圳优化公司排名
  • 免费做名片的网站可以营销的十大产品
  • 高端设计网站制作百度软件中心下载安装
  • 如何在电商上购物网站重庆seo职位
  • 黑山网站建设网络推广文案
  • 网站建设redu网站seo诊断分析
  • 创网络用语是什么意思鞍山seo公司
  • 公司注册后怎么做网站深圳疫情防控最新消息
  • 网站设计的五大要素seo牛人
  • c 怎么和网站做交互个人免费推广网站
  • 中国建设银行车主卡网站网站快速排名上
  • 网站seo优化外包网站生成app工具
  • 佛山做网站-准度科技公司win7系统优化大师
  • 网站建设 上市公司semifinal
  • 苏州网站优化维护推广赚钱的微信小程序
  • 关于做真实的自己视频网站seo优化网站排名
  • 禅城网站建设公司关键词挖掘站网
  • php网站开发考试广告网站推荐