上一篇把左側碎片的RecyclerView的部分完成啦,這一部分就是使用限定符兼容手機平板的重頭戲啦。
*********************************************************
繼續來看圖示:
一、單頁模式:
上一篇中,我們爲了查看RecyclerView的效果,已經將左側碎片LeftTitleFragment添加到MainActivity中啦。那麼現在,我們也可以同樣地將右側碎片RightDetailFragment添加到一個Activity中。新建DetailContentActivity和activity_detail,加入以下代碼:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_page_detail"
android:name="com.example.tahlia.newsclient_2.RightDetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
public class DetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
}
這裏我們新建了一個Activity,當然不能忘記去AndroidMainfest文件中註冊這個活動了!在AndoridManifest文件中已有的<activity>標籤下方再添加一行代碼:
<activity android:name=".DetailActivity"/>
註冊完成。
在單頁模式下,我們要完成從標題頁Activity到詳情頁Activity的跳轉。爲了能統一啓動跳轉的代碼和傳遞的數據格式,添加一個actionStart()方法。這個方法添加在MainActivity或者DetailActivity都可以,但是在使用的時候,單頁模式下兩個Activity都用到,而雙頁模式下DetailActiviy完全不出現,也就意味着不需要用到actionStart()這個方法。爲了代碼的清爽,我們將這個方法添加到DetailActivity中。
public static void actionStart(Context context, String title, String content){
Intent intent = new Intent(context, DetailActivity.class);
intent.putExtra("news_title", title);
intent.putExtra("news_content", content);
context.startActivity(intent);
}
修改跳轉事件(LeftTitleFragment-NewsAdapter-OnCreatViewHolder中):
@Override
public void onClick(View v) {
News news = newsList.get(holder.getAdapterPosition());
DetailActivity.actionStart(getActivity(), news.getTitle(), news.getContent());
}
跳轉頁面的同時,我們使用了intent進行傳遞數據,把title和content也一起傳遞過去了。在DetailActivity中我們應該把它取出來,然後更新顯示。對於單頁模式和雙頁模式來說,更新都是右側詳情碎片所需要的功能,因此在RightDetailFragment中添加一個refresh()方法用來更新頁面數據:
public class RightDetailFragment extends Fragment {
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.right_detail_fragment, container, false);
return view;
}
public void refresh(String title, String content){
TextView newsTitle = (TextView) view.findViewById(R.id.text_detail_title);
TextView newsContent = (TextView) view.findViewById(R.id.text_detail_content);
newsTitle.setText(title);
newsContent.setText(content);
}
}
這裏要注意的是,Fragment中要通過findViewById去獲取控件實例,是需要通過activity中加載的佈局去拿到的,也就是需要一個view,而在OnCreatView中我們已經有一個view了。我們可以將view的定義放在類之中,令整個類的方法都可以使用到view這個變量,以便於我們refresh方法的使用。下一步就是單頁跳轉之後數據的傳遞和更新了。
在獲得Intent包含的數據後,調用refresh對DetailActivity中的數據進行更新顯示。修改DetailActivity中的代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
String title = getIntent().getStringExtra("news_title");
String content = getIntent().getStringExtra("news_content");
RightDetailFragment detailFragment = (RightDetailFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_page_detail);
detailFragment.refresh(title, content);
}
完成。運行看看單頁跳轉效果如何?
嗯單頁已經成功啦!
二、雙頁模式
雙頁模式是我們留給平板之類的屏幕比較大的設備使用的。在這個模式裏,使用最小寬度限定符指定最小值作爲兩個屏幕尺寸加載頁面的區分。
在res目錄下新建layout-sw600dp文件夾,然後新建activity_main.xml,將做好的兩個碎片都加載進來。這裏要注意,左側碎片的id與右側碎片id要和之前單頁模式的id一致。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_page_title"
android:name="com.example.tahlia.newsclient_2.LeftTitleFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2">
<fragment
android:id="@+id/fragment_page_detail"
android:name="com.example.tahlia.newsclient_2.RightDetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</LinearLayout>
新建完成後,考慮到點擊頁面的RecyclerView觸發的效果是不一樣的(單頁模式是啓動一個新的Activity,雙頁模式是直接刷新右側碎片內容),因此要新建一個布爾變量去判斷到底是單頁模式還是雙頁模式,以進行不同的觸發操作。
在LeftTitleFragment中,我們新建一個布爾變量isTwoPage,然後重寫OnActivityCreate如下:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getFragmentManager().findFragmentById(R.id.fragment_page_detail) != null){
isTwoPage = true;
}else{
isTwoPage = false;
}
}
※OnCreatActivity方法是當和碎片相關聯的活動一定創建好的時候調用的一個函數。在確保活動創建完成的時候,我們能夠保證當前活動已經確定好了使用哪個佈局。此時在佈局中尋找id爲fragment_page_detail(右側碎片),如果當前活動中包含了右側碎片,則說明加載的是雙頁模式,isTwoPage爲true;當前佈局不包含右側碎片,則說明加載的是單頁模式,isTwoPage爲false。
判斷完成後,也要修改RecyclerView子項的點擊觸發事件。修改如下:
holder.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
News news = newsList.get(holder.getAdapterPosition());
if (isTwoPage){
RightDetailFragment rightDetailFragment = (RightDetailFragment) getFragmentManager().findFragmentById(R.id.fragment_page_detail);
rightDetailFragment.refresh(news.getTitle(), news.getContent());
}else{
DetailActivity.actionStart(getActivity(), news.getTitle(), news.getContent());
}
}
});
修改完成。大體上所有功能都完成啦!運行一下看看結果:
嗯,基本樣式已經完成啦!
當然還有一些小問題沒有處理好,比如說兩個Fragment之間的分隔線不知道爲什麼沒有顯示出來,還有雙頁模式下右側碎片的初始狀態等等。但是現在已經解決了大部分問題啦。這些小問題就交給下一次優化的時候再解決吧!