[Android Exercise]Fragment新聞客戶端例子拆解PART.3—帶你記憶Fragment的使用

上一篇把左側碎片的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之間的分隔線不知道爲什麼沒有顯示出來,還有雙頁模式下右側碎片的初始狀態等等。但是現在已經解決了大部分問題啦。這些小問題就交給下一次優化的時候再解決吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章