这节开始制作 Activity 视图。
视图的设计,在原理上可以借鉴 HTML 设计,目前大家的共识是内容与样式分离,也就是内容在 HTML 文件中定义,样式在 CSS 文件中对应。
同样,Android 的视图也可以分为 Activity XML 文件 与 style.xml 及其它资源文件(color, dimens, string, share ...),尽可能将布局样式的定义属性转移到 style.xml 文件中。
由于刚开始在 Android 平台上开发,对视图及样式的了解不是很深入,下面的内容有可能不是最佳实现,如有不同意见,希望能在回复中告知。
activity_main.xml
打开在创建 Project 时,ADT 帮我们建立的 activity_main.xml 文件。
在开始编辑之前,作以下设置:
- 将目标设备设为 Nexus 7
- 屏幕方向设置为横屏
- 设置 Theme 为 Holo.Light.NoActionBar
我们要更改根节点的 Layout 类型,切换到 xml 编辑器,直接将 RelativeLayout 改成 LinearLayout。
按下图右边的树结构,依次添加各个组件。其中,最后一个 pager 我在左边的 Palette 面板上未找到,所以直接在 xml 文件中手工输入。
设计样式,加入到 style.xml 中,再在画面上为各组件指定样式。
最后,检查 activity_main.xml 文件,清理不必要的定义,或考虑转移到 style.xml 中。
最终完成的画面:
最终的 activity_main.xml 文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img_main_background"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout style="@style/style_calendar_titlebar" >
<LinearLayout style="@style/style_calendar_title_gregorian_container" >
<ImageView
android:id="@+id/imgPreviousMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:contentDescription="@string/desc_previous_month"
android:onClick="onMenuImageClick"
android:src="@drawable/img_arrow_left" />
<TextView
android:id="@+id/txtTitleGregorian"
style="@style/style_calendar_title_gregorian_text"
android:text="@string/demo" />
<ImageView
android:id="@+id/imgNextMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_next_month"
android:onClick="onMenuImageClick"
android:src="@drawable/img_arrow_right" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_title_detail_container" >
<TextView
android:id="@+id/txtTitleLunar"
style="@style/style_calendar_title_lunar_text"
android:text="@string/demo" />
<TextView
android:id="@+id/txtTitleAddition"
style="@style/style_calendar_title_addition_text"
android:text="@string/demo" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_title_command_container" >
<ImageView
android:id="@+id/imgToday"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="30dp"
android:contentDescription="@string/desc_today"
android:onClick="onMenuImageClick"
android:src="@drawable/img_today" />
<ImageView
android:id="@+id/imgPopupMenu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/desc_popup_menu"
android:onClick="onMenuImageClick"
android:src="@drawable/img_option_menu" />
</LinearLayout>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
style.xml 文件,在完成其它 view 之后再列出。
view_calendar_table.xml
点击 下图 菜单 Search 下面的图标(New Android XML File)
选择 Resource Type -> Layout,输入文件名 -> view_calendar_table,选择 Root Element -> TableLayout,点击 Finish。
这次,我们设置编辑器的 Theme 为 Holo.NoActionBar,因为我们的样式,定义的边框线和文字颜色是白色,在白色背景下观察不到,这个主题的背景色是黑色。
完成后的画面:
xml 文件内容:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tableViewCalendar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1,2,3,4,5,6,7" >
<!--
这里会有一个警告,提示 TableRow 不必要,因为只有一行内容。但是,日历的其它行是动态添加的,
所以这里必须保留,这样 TableHeader 和 TableBody 的列才能对齐。
-->
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
style="@style/style_calendar_header_container"
android:background="@drawable/shape_calendar_cell_weekindex" >
<TextView
style="@style/style_calendar_header_text"
android:layout_width="38dp" />
</LinearLayout>
<LinearLayout
style="@style/style_calendar_header_container"
android:background="@drawable/shape_calendar_cell_weekend" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_sunday" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_header_container" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_monday" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_header_container" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_tuesday" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_header_container" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_wednsday" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_header_container" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_thursday" />
</LinearLayout>
<LinearLayout style="@style/style_calendar_header_container" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_firday" />
</LinearLayout>
<LinearLayout
style="@style/style_calendar_header_container"
android:background="@drawable/shape_calendar_cell_weekend" >
<TextView
style="@style/style_calendar_header_text"
android:text="@string/calendar_saturday" />
</LinearLayout>
</TableRow>
</TableLayout>
view_calendar_day_cell.xml
按上一段的步骤,创建 view_calendar_day_cell.xml,但选择 LinearLayout 作为根节点。
完成的画面:
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/style_calendar_cell.normal" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/txtCellGregorian"
style="@style/style_calendar_gregorian.normal"
android:text="@string/demo" />
<ImageView
android:id="@+id/imgCellHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:contentDescription="@string/desc_cell_hint" />
</FrameLayout>
<TextView
android:id="@+id/txtCellLunar"
style="@style/style_calendar_lunar.normal"
android:text="@string/demo" />
</LinearLayout>
view_calendar_week_index.xml
画面:
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/style_calendar_cell.weekindex"
android:orientation="vertical" >
<TextView
android:id="@+id/txtWeekIndex"
style="@style/style_calendar_weekindex_text"
android:text="@string/demo" />
<TextView
style="@style/style_calendar_weekindex_text"
android:text="@string/chinese_week" />
</LinearLayout>
当前状态下的 style.xml 文件(编写代码时,可能会对其进行更新):
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<style name="style_calendar_titlebar">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@drawable/shape_calendar_titlebar</item>
<item name="android:layout_gravity">bottom</item>
<item name="android:orientation">horizontal</item>
</style>
<style name="style_calendar_title_gregorian_container">
<item name="android:layout_width">250dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">10dp</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<style name="style_calendar_title_gregorian_text">
<item name="android:layout_width">164dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">36sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/color_calendar_title_gregorian</item>
<item name="android:layout_marginLeft">25dp</item>
</style>
<style name="style_calendar_title_detail_container">
<item name="android:layout_width">560dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:gravity">bottom</item>
<item name="android:paddingBottom">10dp</item>
<item name="android:paddingLeft">20dp</item>
</style>
<style name="style_calendar_title_lunar_text">
<item name="android:layout_width">350dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">bottom|left</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/color_calendar_title_lunar</item>
</style>
<style name="style_calendar_title_addition_text">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/color_calendar_title_addition</item>
</style>
<style name="style_calendar_title_command_container">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
<item name="android:gravity">bottom|right</item>
</style>
<style name="style_calendar_header_container">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
<item name="android:background">@drawable/shape_calendar_header</item>
</style>
<style name="style_calendar_header_text">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">#9fff</item>
<item name="android:padding">5dp</item>
</style>
<style name="style_calendar_weekindex_text">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">18sp</item>
<item name="android:textColor">#9fff</item>
<item name="android:paddingBottom">2dp</item>
</style>
<style name="style_calendar_cell">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:clickable">true</item>
<item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:onClick">onCellClick</item>
<item name="android:orientation">vertical</item>
</style>
<style name="style_calendar_cell.normal">
<item name="android:background">@drawable/shape_calendar_cell_normal</item>
</style>
<style name="style_calendar_cell.outrange">
<item name="android:background">@drawable/shape_calendar_cell_outrange</item>
</style>
<style name="style_calendar_cell.today">
<item name="android:background">@drawable/shape_calendar_cell_today</item>
</style>
<style name="style_calendar_cell.weekindex">
<item name="android:gravity">center_horizontal</item>
<item name="android:background">@drawable/shape_calendar_cell_weekindex</item>
</style>
<style name="style_calendar_cell.weekend">
<item name="android:background">@drawable/shape_calendar_cell_weekend</item>
</style>
<style name="style_calendar_gregorian">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:textSize">36sp</item>
<item name="android:textStyle">bold</item>
</style>
<style name="style_calendar_gregorian.normal">
<item name="android:textColor">@color/color_calendar_normal_gregorian</item>
</style>
<style name="style_calendar_gregorian.outrange">
<item name="android:textColor">@color/color_calendar_outrange</item>
</style>
<style name="style_calendar_gregorian.today">
<item name="android:textColor">@color/color_calendar_today_gregorian</item>
</style>
<style name="style_calendar_gregorian.weekend">
<item name="android:textColor">@color/color_calendar_weekend</item>
</style>
<style name="style_calendar_lunar">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:textSize">16sp</item>
<item name="android:paddingBottom">2dp</item>
</style>
<style name="style_calendar_lunar.normal">
<item name="android:textColor">@color/color_calendar_normal_lunar</item>
</style>
<style name="style_calendar_lunar.outrange">
<item name="android:textColor">@color/color_calendar_outrange</item>
</style>
<style name="style_calendar_lunar.today">
<item name="android:textColor">@color/color_calendar_today_lunar</item>
</style>
<style name="style_calendar_lunar.weekend">
<item name="android:textColor">@color/color_calendar_weekend</item>
</style>
</resources>
对于 style 的 name 属性,可以用点分隔来实现继承,如上面的 style_calendar_lunar.today,就是从 style_calendar_lunar 继承而来,然后新增或修改特点属性。
当前状态下的 string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Pure Lunar Calendar</string>
<string name="menu_settings">Settings</string>
<string name="desc_previous_month">previous month</string>
<string name="desc_next_month">next month</string>
<string name="desc_today">return to today</string>
<string name="desc_popup_menu">Popup menu</string>
<string name="desc_cell_hint">cell hint</string>
<string name="chinese_week">周</string>
<string name="demo">demo</string>
<string name="calendar_sunday">星期日</string>
<string name="calendar_monday">星期一</string>
<string name="calendar_tuesday">星期二</string>
<string name="calendar_wednsday">星期三</string>
<string name="calendar_thursday">星期四</string>
<string name="calendar_firday">星期五</string>
<string name="calendar_saturday">星期六</string>
<string-array name="gregorianFestivals">
<item>元旦</item>
<item>情人节</item>
<item>妇女节</item>
<item>植树节</item>
<item>消费者权益日</item>
<item>愚人节</item>
<item>国际劳动节</item>
<item>国际儿童节</item>
<item>教师节</item>
<item>国庆节</item>
<item>万圣节</item>
<item>平安夜</item>
<item>圣诞节</item>
</string-array>
</resources>
[待续] 下节开始编写代码