设配器模式不止是补救,有时更像是一个创造者

设配器模式不止是补救,有时更像是一个创造者

适配器模式的官方应用场景是在软件开发后期,应对功能扩展后,新的类结构无法对应之前的接口,从而采用的一种补救措施。然而如果你只记住了这个,你可能会错过一个很重要的技巧。

================

定义

将一个类的接口变换成客户端所期待的另一个类的接口,从而使原本因接口不匹配而无法一起工作的两个类可以匹配。

咬文嚼字

必须要承认的是适配器模式是一个非常好的补救模式。但是除了补救呢?

适配器的核心是:对象的转变,将不适配的东西转成适配的东西。

关键词:“转换”。转换 — 加工 — 创造!

没错,我要说的就是创造。适配器模式在一些特定的场合,更像一个创造者模式。什么场合呢?

Data — View

灵感来源于Android控件 ListView。

其实最早在小小白时期并不能理解ListView适配器的工作原理,甚至因为模板模式的关系,没有显示调用关系,我甚至无法理解它是如何办到的!

将一个数据集塞进适配器,再将适配器塞给ListView,数据就展示出来了.Magic!

适配器模式—创造者模式

在一些复杂的ViewItem组合的View控件里(ListView, ViewPager,GirdView),因为Item的样式常常需要我们自行通过基础View控件组合子定义,而如何将数据转变为这些ViewItem就成为了问题。难道有5个Item我就定义5个View吗?NO!!当Item变成了100个怎么办?

这里,如果你想起来了适配器模式,那问题就迎刃而解。

通过适配器模式创造View,是非常符合数据控制View这条守则的。

在适配器模式中去写View的显示逻辑,也实现了View和业务解耦的需求。

而通过Data,去控制View的显示,也极大的提高了View效率,减少了不必要的View创建。

关于代码,因为较多,我们放在最后。

适配器模式优点

  • 适配器模式可以让没有任何关系的两个类在一起运行(最明显的:Data 和 View)

  • 提高了类的复用。接口不同你不需要去修改他们为相同,只需要添加一个适配器模式。

  • 适配器模式非常符合开闭原则

  • 解耦。在Data 转View的场景里,很好的实现了View和业务逻辑的解耦。

适配器模式的缺点

适配器模式是一个非常好用的模式,几乎很难找出缺点。

可能唯一的缺点就是对小小白来说阅读代码有困难,但这点困难时非常容易跨过去的。

另外值得一提的就是需要注意的场景:

  • 书中说:适配器模式是一个不需要再设计初期就要考虑的问题。但我说,在Data — View的场景,适配器模式一定是你需要提前审查的模式,不要写了很多View觉得麻烦了才想起来适配器模式。

  • 不要滥用。并不是任何时候都适合使用适配器模式。你不会想看到你的项目里到处都是适配器的。

适配器代码

Adapter.java

public class BannerAdapter extends ScrollBannerAdapter {

private List<BannerDto> mDatas;
private LayoutInflater mInflater;
private int mHeight;

public BannerAdapter(Context context) {
    this.mInflater = LayoutInflater.from(context);
    mHeight = (int) context.getResources().getDimension(R.dimen.banner_width);
}

public void setDatas(List datas) {
    mDatas = datas;
}

@Override
public int getCount() {
    return mDatas.size();
}

@Override
public Object getItem(int position) {
    return mDatas.get(position);
}

@Override
public int getItemId(int position) {
    return mDatas.get(position).getId();
}

@Override
public int getItemViewType(int position) {
    return mDatas.get(position).getType();
}

@Override
public int getBannerHeight() {
    return mHeight;
}

@Override
public View getView(int position, View convertView) {
    BannerDto bannerDto = mDatas.get(position);
    ViewHolder viewHolder = null;
    if (convertView == null) {
        viewHolder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.widget_banner, null);
        viewHolder.removeText = (ImageView) convertView.findViewById(R.id.removeText);
        viewHolder.titleText = (TextView) convertView.findViewById(R.id.titleText);
        viewHolder.enterText = (TextView) convertView.findViewById(R.id.enterText);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    convertView.setBackgroundColor(Color.parseColor(bannerDto.getBgColor()));

    viewHolder.titleText.setText(bannerDto.getTitle());
    return convertView;
}

@Override
public View getFixView(int position, View convertView) {
    BannerDto bannerDto = mDatas.get(position);
    ViewHolder viewHolder = null;
    if (convertView == null) {
        viewHolder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.widget_banner, null);
        viewHolder.removeText = (ImageView) convertView.findViewById(R.id.removeText);
        viewHolder.titleText = (TextView) convertView.findViewById(R.id.titleText);
        viewHolder.enterText = (TextView) convertView.findViewById(R.id.enterText);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.titleText.setText(bannerDto.getTitle());
    return convertView;
}

@Override
public int setFocusable(int position) {
    return 0;
}

@Override
public int getWheelTime(int position) {
    return mDatas.get(position).getWheelTime();
}

@Override
public boolean isEmpty() {
    return mDatas.isEmpty();
}

private static class ViewHolder {
    ImageView removeText;
    TextView titleText;
    TextView enterText;

}

}

View控件.java

public class ScrollBanner extends LinearLayout {

    //View控件其他方法
    //。。。


    //设置adapter
    public void setAdapter(ScrollBannerAdapter adapter) {
        this.mAdapter = adapter;
        mScrollBanners = new View[]{mAdapter.getView(0, null), mAdapter.getView(0, null)};


    }

    //取得下一个View
    private View getNextView(){
        if(mAdapter == null){
            return ;
        }
        return mAdapter.getView(mShowPosition,mScrollBannerItem);
    }



    //View控件其他方法
    //。。。


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值