[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之间的分隔线不知道为什么没有显示出来,还有双页模式下右侧碎片的初始状态等等。但是现在已经解决了大部分问题啦。这些小问题就交给下一次优化的时候再解决吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值