改动说明

  • 删除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.

  1. public class DemoPopup extends BasePopupWindow {
  2. @BindView(R.id.tv_desc)
  3. public TextView mTvDesc;
  4. int a;
  5. public DemoPopup(Context context,int a) {
  6. super(context);
  7. // 此时赋值构造器传入的值
  8. this.a = a;
  9. setContentView(R.layout.popup_demo);
  10. }
  11. @Override
  12. public void onViewCreated(View contentView) {
  13. ButterKnifeUtil.bind(this, contentView);
  14. // 此时能正确访问到a
  15. mTvDesc.setText(String.valueOf(a));
  16. }
  17. // 如果使用 new DemoPopup().setText(),不需要担心mTvDesc为空
  18. public DemoPopup setText(CharSequence text) {
  19. mTvDesc.setText(text);
  20. return this;
  21. }
  22. }