Skip to content

Latest commit

 

History

History
88 lines (55 loc) · 3.88 KB

Update_3.0.md

File metadata and controls

88 lines (55 loc) · 3.88 KB

中文 | English


关于BasePopup 3.0的破坏性更新说明

改动说明

  • 删除BaseLazyPopupWindow:往后不需要区分懒加载和正常的BasePopupWindow,统一依赖BasePopupWindow
  • 删除方法onCreateConstructor:该方法实际上是给BaseLazyPopupWindow使用的,现在没有了BaseLazyPopupWindow,自然不需要该方法
  • 【重要】删除方法onCreateContentView:该方法的删除将会影响所有的BasePopupWindow子类,您需要手动去改动
    • 该方法将会被setContentView(@LayoutRes int layoutResID)setContentView(final View view)所代替,您需要修改其使用。
    • 当然,如果使用setContentView(final View view),我们依然建议您用setContentView(createPopupById(layoutResID)),以便我们解析到正确的xml配置。

为什么要这么改

事实上想改这个很久了,而且也不止一位开发者向我提过这个issue,如#368

初始化ContentView其实就应该跟Dialog或者Activity一样,把权限交给使用者而非框架强行设定。

之所以会出现onCreateContentView这样的强制实现的方法,是因为第一版的BasePopup就是这么设计的,而第一版的设计时间是16年,那时候我大四,设计这个框架的目的就是为了求职。

那时候我也想不到BasePopup会被我一直维护且迭代更新,也没想到会有那么多开发者使用。

但也正因为是那么多人使用,因此我一直不太敢去动他,毕竟这是一个破坏性更新,要改的很多很多(虽然改动很小,但可能依赖BasePopup的类很多)。

但是,随着越来越多人的提出这个问题,我认为这种修改是躲不过的。

因此这次改动我将直接发布3.0版本,与2.x版本区分开来。

修改的好处

优点有很多,先来说说以前的缺点:

BaseLazyPopupWindow

在以前的版本中,我提供了一个BaseLazyPopupWindow来解决构造器传参,onViewCreated中无法获取的问题。

咋一眼似乎还行,实际上仍有弊端,最主要体现在两个:

1. inflate的时机在showPopupWindow(),这会导致复杂的布局在第一次show的时候会卡顿(卡顿原因:inflate)
2. 由于懒加载,其加载时机在show的时候,因此我们无法在构造器中findViewById,其次对于 new popup().setText().showPopupWindow()这样的在setText中直接访问控件的方法是不可行的,只会得到NPE报错(在show之前都没有inflate呢,访问控件只能是空的)。

这两个问题也许很多人没遇到过,但一旦遇到了就会觉得巨麻烦,框架为啥这么设计。

构造器传参及onViewCreated取参的问题

在以前的版本中,onViewCreated是在父类的构造器中调用的,此时子类的参数都还没赋值进行初始化,因此执行onViewCreated时我们无法得到参数。

哪怕后来提供了BaseLazyPopupWindow,也会有上述几个问题。

修改后的使用

修改后的使用上跟以前其实没啥区别,优点是setContentView的时机完全由您控制,不必担心上面所说的问题。

e.g.

public class DemoPopup extends BasePopupWindow {
    @BindView(R.id.tv_desc)
    public TextView mTvDesc;

    int a;

    public DemoPopup(Context context,int a) {
        super(context);
        // 此时赋值构造器传入的值
        this.a = a;
        setContentView(R.layout.popup_demo);
    }


    @Override
    public void onViewCreated(View contentView) {
        ButterKnifeUtil.bind(this, contentView);
        // 此时能正确访问到a
        mTvDesc.setText(String.valueOf(a));
    }

    // 如果使用 new DemoPopup().setText(),不需要担心mTvDesc为空
    public DemoPopup setText(CharSequence text) {
        mTvDesc.setText(text);
        return this;
    }
}