把郭大大的新聞客戶端例子從頭到尾寫一遍之後,理清了其中的思路。現在寫下一篇例子的拆解,以供進一步理解和記憶。
********************************************************
來看一下整個頁面架構的圖示:
總體而言,左側就是顯示標題的Fragment,右側就是顯示具體內容的Fragment。通過限定符判斷兩個activity分別決定了採用單頁模式還是雙頁模式。在單頁模式下,兩個碎片分別放入兩個不同的Activity中,通過Intent跳轉頁面並傳遞參數;雙頁模式下,兩個碎片被放入同一個Activity中,通過傳遞參數進行頁面更新。
下面就開始逐步拆分整個客戶端的例子吧。
***************************************************************
一、新建News類
在這個簡易的客戶端例子中,我們只需要新聞的標題和新聞的內容,因此新建News類,字段包括title和content。爲了方便使用循環自動更改title和content,此處就不使用構造函數傳參了,而是使用set方法設置。
public class News {
private String title;
private String content;
public void setTitle(String title){
this.title = title;}
public void setContent(String content){
this.content = content;}
public String getTitle(){
return title;}
public String getContent(){
return content;}
}
二、完成並加載兩個基礎Fragment的佈局
1.右側碎片詳情頁的佈局:right_detail_fragment
新建right_detail_fragment.xml,Root Element選擇使用ScrollView而非書中例子所使用的RelativeLayout,主要是考慮到萬一新聞內容超出頁面範圍,使用ScrollView則可以讓頁面進行滑動,不會造成被裁切的情況。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/layout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="10dp">
<TextView
android:id="@+id/text_detail_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/text_detail_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"/>
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#ccc"
android:layout_toLeftOf="@id/layout_1"/>
</RelativeLayout>
</ScrollView>
這段代碼中沒有對樣式給出太多要求,在做的時候可以手動添加各種不同的樣式隨你喜歡~
※ScrollView中只允許擁有一個子控件,因此SrollView中不可以包含兩個或兩個以上控件。但SrollView的子控件則無要求,因此一般使用會把LinearLayout嵌進SrollView中,此處我使用的是RelativeLayout。
這是我調整完樣式後得到的預覽圖:
2.左側碎片標題頁的佈局:left_title_fragment
左側使用RecyclerView去顯示所有的標題,因此別忘了先導入RecyclerView的依賴庫。
新建left_title_fragment.xml,RootElement選擇LinearLayout,然後嵌入RecyclerView。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview_title"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
佈置好了RecyclerView以後,當然也需要佈置它子項的佈局。新建left_title_item.xml,RootElement並沒有按照書上直接使用TextView,而是使用了一個LInearLayout,畢竟我想在RecyclerView的每個子項中添加一條分隔線。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_margin="10dp"
android:maxLines="1"
android:ellipsize="end"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc"/>
</LinearLayout>
這裏要注意的是,這個佈局只是用於RecyclerView中的一個子項的佈局,因此注意LinearLayout和TextView的高度都不能設定成match_parent,否則結果將會變成每顯示一個子項都需要翻一頁,也就是一屏只顯示一個子項。
TextView中的maxLines屬性表示最多隻允許文本出現一行。如果缺少了這個屬性,如果標題過長,就會導致這個子項所佔的高度隨着文本行數的增多而變大,就沒有那麼美觀了。而ellipsize屬性則表示如果一行過長,將會省略哪一部分內容,可選擇的屬性有end(省略號在末尾進行省略)、marquee(文本滾動顯示)、middle(省略號在中間進行省略)、start(省略號在開頭進行省略)。
3.加載兩個碎片的佈局:LeftTitleFragment和RightDetailFragment
新建LeftTitleFragment,繼承於Fragment。父類輸入Fragment的時候會提示兩個庫,一個是v4庫,一個是app庫。這裏我們要使用v4庫的Fragment,以保證在低版本系統中Fragment不會令程序崩潰。
重寫OnCreatView方法,將已經編寫好的左側碎片佈局加載進來,如下:
public class LeftTitleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_title_fragment, container, false);
return view;
}
}
※一定要注意,此處使用inflate加載佈局的時候必須使用3個參數,不可忽略第三個參數!詳情可回顧上一篇博文。RightDetailFragment加載右側碎片佈局方法和LeftTitleFragment相同。
到這裏爲止,第一部分工作已經完成了!休息一下,然後開始完成第二部分吧!