Android training(1)-Building a Dynamic UI with Fragments(用碎片创造一个动态的UI)(B)

B:建立一个灵活的用户界面

为了你的应用可以支持大屏幕尺寸的手机,你可以根据不同的可利用空间,配置拥有可重复利用的Fragment的不同布局配置来优化你的用户体验。

例如,在手机上,只显示一个单独的Fragment,提供一个单面板的用户界面是合适的。相反,在平板电脑上你就想把Fragment一个挨一个的平排放在宽的屏幕上,给用户提供更多的信息。如下图:

注意:FragmentManager类提供了在程序运行时向Activity中添加、删除、替换Fragment的方法,这样你就可以创建动态的体验了。

B.a 在程序运行时添加一个Fragment到Activity中

和上一篇讲的在布局文件中使用<fragment>元素讲Fragment添加到Activity中比,你可以在Activity运行期间给它添加Fragment,如果你想在Activity的生命周期期间改变Fragments,那么这么做是必须的。

为了完成一个添加或者删除Fragment的事务,你必须用Fragment来创建一个FragmentTransaction,它提供了添加、删除、替换以及其他一下处理Fragment的方法。如果你的Activity允许Fragments被删除或者替换,你必须在Activity的onCreate()方法里面添加它。

和Fragment打交道最重要的规则(特别是那些在程序运行的添加的)-就是Fragment必须在布局中拥有一个容器,Fragment的布局将属于它。

下面这个布局是上一篇中只显示一个Fragment的那个布局的替换着,为了用一个Fragment替换另一个,这个布局中包含了一个空的FrameLayout作为Fragment的容器。

可以看到文件名和上一篇中的是一样的,但是他所在的文件夹没有了large这个限定词,所以这个布局是用在相对于large的小尺寸屏幕设备上的,不适合在屏幕上同时显示两个Fragment。

res/layout/news_articles.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
在你的Activity中,调用getSupportFragmentManager()来获得一个使用支持库中方法的FragmentManager。然后调用beginTransaction()来创建一个FragmentTransaction然后调用add()方法来添加一个Fragment。

你可以在一个FragmentTransaction下执行多次对fragment的操作,当你做好准备变化fragment时,调用commit()方法。

下面就是一个怎么想上面布局添加Fragment的例子。


import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_articles);

        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }

            // Create an instance of ExampleFragment
            HeadlinesFragment firstFragment = new HeadlinesFragment();
            
            // In case this activity was started with special instructions from an Intent,
            // pass the Intent's extras to the fragment as arguments
            firstFragment.setArguments(getIntent().getExtras());
            
            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment).commit();
        }
    }
}

因为这个fragment实在程序运行是添加到FrameLayout中的,而不是在Activity的布局中用<fragment>元素添加的,所以Activity可以用删除它,或者另一个fragment替换它。

B.b 用一个fragment替换现有的fragment

替换一个fragment的过程和添加的过程是一样的,只不过使用replace()方法替换add()方法。

值得记住的是当你操作fragment时,允许用户返回或者取消操作是经常适用的。为了让用户可以通过之前的操作返回从前,你必须在调用addToBackStack()方法在你提交FragmentTransaction前。

注意:当你移除或者替换一个fragment并且把这次操作放到后退栈中时,这个被移除的fragment的生命周期变为stop(而不是被销毁了)。如果用户返回来恢复这个fragment,它将重新启动。如果你没有把操作放到后退栈中,那么当fragment被替换或者移除时它将被销毁。

下面是一个替换fragment的例子:

// Create fragment and give it an argument specifying the article it should show
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();
注意:addToBackStack()方法有可以可选的字符串类型的参数,用来表示这次操作的唯一性。这个用来命名的字符串不是必须的,除非你想使用FragmentManager.BackStackEntry提供的方法来对fragment进行一些高级的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值