0. 前言

上周朋友拿美团外卖客户端的店铺页面,问我顶部文字详情展开的实现方式,这个效果本身就是一个已经有maxline设置的TextView展开的实现,但是没有对控件的跳变做更多的处理,感觉体验不是很好。于是我先仿写一个类似效果,又在原来的基础上把跳变改成了动画,效果如图所示。

阅读全文 »

0. 前言

本文是Philm源码分析系列的第三篇,重点分析Philm MVP结构中Presenter与Model的设计。本文选取了Philm中核心的部分Movie作为示例。

1.Philm中的Model

Philm中的Model通过State来管理,具体到Movie中,MovieController中包含一个对于MoviesState的引用。而State的实现在ApplicationState中,与第二篇提到的AndroidDisplay类似,ApplicationState是一个包含了所有Model总和的类。

1
2
3
public final class ApplicationState implements BaseState, MoviesState, UserState {
...
}

阅读全文 »

0.前言

本文是Philm源码分析系列的第二篇,重点分析Philm MVP结构中View与Presenter的设计。为了便于分析,本文选取了Philm中最简单的部分About,这部分用于展示Philm的关于信息,不包含任何Model代码。

1.绑定View和Presenter

在Philm中,View由Fragment和Activity实现,由于应用启动时首先启动Activity,因此,绑定Presenter的工作要在View中进行(也就是Activity/Fragment)。Philm在AboutFragment的onResume方法和onPause方法中进行View与Presenter的绑定与解绑。具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class AboutFragment extends ListFragment<ListView>
implements AboutController.AboutListUi {

...
@Override
public void onResume() {
super.onResume();
getController().attachUi(this);
}

@Override
public void onPause() {
getController().detachUi(this);
super.onPause();
}
...
}

对于Philm的About部分,它的Presenter就是MainController中的AboutController(是的,Chris Banes将Presenter命名为了Controller)。

阅读全文 »

0. 前言

Watch Philm这一系列文章主要是对近期阅读Chris Banes的开源项目Philm源码的整理。Android开发本身没有提供类似MVP之类的框架,只是提供了构建应用的基础组件。这一方面降低了上手难度,提供了极大的开发时的灵活度,但是对于新手极易写出高耦合的坏味道的代码。Philm本身构建了一套MVP架构的实现,本文也就基于Philm项目的源码来分析在Android开发中如何利用MVP模式构建程序。

本文为这个系列的第一篇,重点介绍MVC,MVP以及MVVM架构的基本概念以及他们的区别。

阅读全文 »

前言

Android中默认的TabBar位于ActionBar的下方,在ActionBar横屏有足够空间时,会将TabBar嵌入到ActionBar中,节省纵向空间。一些UI设计强制将TabBar嵌入到ActionBar,并去掉默认的HOME LOGO,起到节省屏幕空间的作用,如网易云音乐2.1.1中。


阅读全文 »

List Comprehension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> print [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> print [i for i in range(20) if i%2 == 0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

>>> nums = [1,2,3,4]
>>> fruit = ["Apples", "Peaches", "Pears", "Bananas"]
>>> print [(i,f) for i in nums for f in fruit]
[(1, 'Apples'), (1, 'Peaches'), (1, 'Pears'), (1, 'Bananas'),
(2, 'Apples'), (2, 'Peaches'), (2, 'Pears'), (2, 'Bananas'),
(3, 'Apples'), (3, 'Peaches'), (3, 'Pears'), (3, 'Bananas'),
(4, 'Apples'), (4, 'Peaches'), (4, 'Pears'), (4, 'Bananas')]

>>> print [(i,f) for i in nums for f in fruit if f[0] == "P"]
[(1, 'Peaches'), (1, 'Pears'),
(2, 'Peaches'), (2, 'Pears'),
(3, 'Peaches'), (3, 'Pears'),
(4, 'Peaches'), (4, 'Pears')]

>>> print [(i,f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1]
[(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')]

>>> print [i for i in zip(nums,fruit) if i[0]%2==0]
[(2, 'Peaches'), (4, 'Bananas')]

Use xrange instead of tranditional index manipulation

1
2
3
4
5
6
7
8
9
10
11
# NOT SO GOOD
for i in [0, 1, 2, 3, 4, 5]:
print i * 2

#BETTER
for i in range(6):
print i*2

#BEST
for i in xrange(6):
print i*2
阅读全文 »