Download模块 (三)

Download模块 (三)

DownloadConfirmDialog是UI流程中最先呈现给用户的V,让用户选择download存储的位置,名称以及在普通下载与转存网盘之间做选择.
这里采用了Fragment来作为实现手段<其实也可以进一步使用DialogFragment>,

<1>UI上的 存储方式的界面选择 采用了ViewPager实现。

<2>DownloadConfirmDialog类还implements了 OnClickListener 和 OnPageChangeListener, 成为一个C的聚合体,原因不再赘述.

<3>为了模仿Dialog的居中效果, 在真正的dialogView上和下各有一个layout_weight是1的dummyView<ugly....>

<4>一个trick:
该UI的layout文件中,ViewPager的height给的是wrap_content, 而对于ViewPager来说,其width和height是依靠外部的ViewParent为其制定的,本UI的layout为ViewPager的height指定wrap_content是无奈之举,因为和ViewPager同处一个LinearLayout的其他View都有着明确的
height,不可能通过layout_weight实现,而直接将viewPager指定为match_parent会占满整个屏幕,两个dummyView将被挤压出去。
将ViewPager的height指定为wrap_content也会导致最后ViewPager所在的ViewGroup占满整个屏幕<可以参考ViewPager的onMeasure>。因此需要对ViewPager进行扩展,使其
能够自己决定能够容纳其内部所有view的自己的合适height。
对该ViewPager要对其的onMeasure override,参考本身onMeasure实现,要先将其所有的子View生成,即:

// Make sure we have created all fragments that we need to have shown.
mInLayout = true;
populate();
mInLayout = false;

因为上面的变量和函数都不是public的,因此要反射实现调用。
然后在生成了所有的子View以后,对这些view进行遍历,每个child执行:
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
                        0, MeasureSpec.UNSPECIFIED)<MeasureSpec.UNSPECIFIED是为了让子child自己决定自己的合适height>);
然后得到child的MeasuredHeight, 取这些child中的最大height,这样,这个height就是能够让ViewPager完整显示所有child的最小heigt,
构造一个MeasureSpec.EXACTLY类型,值为此height的MeasureSpec作为height参数再调用super的onMeasure,就可以实现ViewPager自己为
自己实现了合理的height measure. <width不用考虑,因为满足普通viewPager的使用要求,都是match_parent>

<5>DownloadConfirmDialog本身这个类承担了很少的C功能,在其构造时,会传入一个定义在此类中的listener,该listener作为外部调用者的
回调,因此这一部分C功能移交给了外部调用者,ViewPager自定义的PagerAdapter也单独的作为一个类存在。
DownloadConfirmDialog类的C主要集中在除了ViewPager外的其他View的更新和交互,在此dialog的最上是一个水平的LinearLayout,
每个其中的子View代表这一种存储方式<当前只有两种 本地和网盘,但是考虑到扩展,因此此处的实现是不限数目的>
每个子View的作用是一个indicator,高亮标示当前的存储方式,而其他的子view则变灰。
在初始化时,会将所有 代表不同存储方式 的子view加入到此LinearLayout中,并且每个View之间也加入一个widt=1dp的view作为sep,
注意,子view的生成的逻辑也不在此类中,而是分拆到不同的IndicatorViewProvider类中,顺序遍历调用provider的createIndicatorView生
成并添加<注意在添加前,要为indicatorView生成一个合适的LinearLayout的LayoutParams,因为每个IndicatorView的width都一样,因此
设置其Layout_weight为1.0>,
同时,为了实现点击相应的indicatorView,ViewPager切换到相应的Page,为indicatorView设置clickListner<DownloadConfirmDialog实现
了这个C>,点击时,直接调用ViewPager的setCurrentItem.
<6>DownloadConfirmDialog还承担了PageListener这个C,主要是为了在ViewPager变化时,调整indicatorView和sliderView<自己实现的>
onPageSelected时,会将相应的indicatorView高亮.
对sliderView则直接调用其相应方法.
<7>trivial:
(1)如果用dialogFragment实现可能更方便,不过当时没想到.
(2)DownloadConfirmDialog的实现可以视为一个Facade模式<不完全>, 大量的C功能下放,以及比较单一的职责.
(3)目前ViewPager的变化<切换>只会影响到DownloadConfirmDialog这一层,不需要专门定义PageListener.
发布了426 篇原创文章 · 获赞 51 · 访问量 65万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览