fragment的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fragment的使用相关的知识,希望对你有一定的参考价值。

  从google在android3.0推出fragment之后,fragment的使用场景越来越多。fragment可以将UI界面一块儿一块儿的封装,有更加强大、灵活的生命周期,更快的启动速度。现在越来越多的app,会较少的使用activity,而是用fragment完成大部分页面的展示。

  在这里,我将记录关于fragment的使用方法。

  首先,我们要建立一个大致的结构模型。我们使用Activity作为App的底层界面容器。在Activity中用一个控件,来显示fragment。然后界面的切换就是用这个控件来切换它显示的fragment。

  所以Activity的xml比较简单:

  activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/main_framelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>

</LinearLayout>

 

  将要用来显示fragment的容易就是这个framelayout。

  在开始MainAcitivy.java的代码编写之前,先要在此说明两个类。  

  1.FragmentManager

    它像一个管理fragment的类,它类似一个fragment的容器,能够使用add,remove,findFragmentByTag方法,操作fragment。但是除了findFragmentByTag,我们不能直接操作add和remove,也不能直接操作fragment。我们需要另一个类来进行操作——FragmentTransaction。

  2.FragmentTransaction

    它是一个一次性的事务,我们通过fragmentManager.beginTransaction();获取它,用fragmentTransaction.commit();完成操作。fragmentTransaction提交过一次之后,就不能再提交了。下一次操作时,就要创建新的实例。

  

public class MainActivity extends Activity implements mBaseUiFragment.OnUiFragmentJumpToListener {


    FrameLayout mainFrameLayout;
    FragmentManager fragmentManager;
    Fragment mainFragment;

    Stack<Fragment> mFragmentStack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainFrameLayout = (FrameLayout) findViewById(R.id.main_framelayout);
        initFragment();


    }

    private void initFragment(){
        fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mFragmentStack = new Stack<>();

        mainFragment = new MainFragment();
        fragmentTransaction.add(R.id.main_framelayout, mainFragment, MainFragment.FRAGMENT_TAG);
        mFragmentStack.push(mainFragment);
        
        fragmentTransaction.show(mainFragment);
        fragmentTransaction.commit();
    }
}

 

  mFragmentStack是一个存放fragment的栈。用于模仿activity的堆栈返回机制。

  我们在给fragmentManager中添加fragment时,我们需要设置一个tag.这样,我们想再操作这个fragment时,我们就可以通过findFragmentByTag这个方法,获得这个fragment的引用。

 

  mBaseUiFragment.OnUiFragmentJumpToListener 是一个接口,用于fragment对activity的回调。这个接口定义在uiFragment的基类中。

 

  mBaseUiFragment.java:  

public class mBaseUiFragment<T extends mBaseUiFragment> extends mBaseFragment {


    Context mContext;
    View rootView;
    OnUiFragmentJumpToListener onUiFragmentJumpToListener;

    public interface OnUiFragmentJumpToListener{
        void jumpToFragment(Class<? extends Fragment> fragmentClass , String toFragmentTag);
        void fragmentBack();
    }



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getActivity();
        onUiFragmentJumpToListener = (OnUiFragmentJumpToListener) getActivity();
    }
}

 

   在这个基类中,定义了OnUiFragmentJumpToListener接口,并赋予它实例。OnUiFragmentJumpToListener接口中暂时只声明了跳转和返回的方法。

  因为,我们在MainActivity中可以加上这一段的实现

  MainActivity.java:  

public class MainActivity extends Activity implements mBaseUiFragment.OnUiFragmentJumpToListener {


    FrameLayout mainFrameLayout;
    FragmentManager fragmentManager;
    Fragment mainFragment;

    Stack<Fragment> mFragmentStack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainFrameLayout = (FrameLayout) findViewById(R.id.main_framelayout);
        initFragment();


    }

    private void initFragment(){
        fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mFragmentStack = new Stack<>();

        mainFragment = new MainFragment();
        fragmentTransaction.add(R.id.main_framelayout, mainFragment, MainFragment.FRAGMENT_TAG);
        mFragmentStack.push(mainFragment);

        fragmentTransaction.show(mainFragment);
        fragmentTransaction.commit();
    }


    @Override
    public void jumpToFragment(Class<? extends Fragment> fragmentClass , String toFragmentTag) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment targetFragment = fragmentManager.findFragmentByTag(toFragmentTag);

        if (targetFragment == null){
            try {
                targetFragment = fragmentClass.newInstance();
                fragmentTransaction.add(R.id.main_framelayout , targetFragment , toFragmentTag);
                fragmentTransaction.show(fragmentClass.newInstance());
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }else {
            fragmentTransaction.show(targetFragment);
        }

        fragmentTransaction.hide(mFragmentStack.get(0));

        mFragmentStack.push(targetFragment);
        fragmentTransaction.commit();
    }

    @Override
    public void fragmentBack() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment fromFragment = mFragmentStack.pop();
        fragmentTransaction.hide(fromFragment);
        fragmentTransaction.show(mFragmentStack.get(0));
        fragmentTransaction.commit();
    }
}

   

  最后,贴上MainFragment和TestFragment的代码。MainFragment中可以”跳转“至TestFragment,TestFragment可以”返回“。

  MainFragment:

public class MainFragment extends mBaseUiFragment implements View.OnClickListener {

    static public String FRAGMENT_TAG = "MainFragment";



    // View
    TextView downLoadProgress;
    Button startOrPauseBtn;
    Button stopBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.main_layout , null);
        initView();
        return rootView;
    }

    private void initView(){
        downLoadProgress = (TextView) rootView.findViewById(R.id.download_progress_id);
        startOrPauseBtn = (Button) rootView.findViewById(R.id.start_or_pause_btn);
        startOrPauseBtn.setOnClickListener(this);
        stopBtn = (Button) rootView.findViewById(R.id.stop_btn);
        stopBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_or_pause_btn:
                onUiFragmentJumpToListener.jumpToFragment(TestFragment.class , TestFragment.FRAGMENT_TAG);
                break;
            case R.id.stop_btn:
                break;
        }
    }
}

  

   TestFragment:

  

public class TestFragment extends mBaseUiFragment {

    static public String FRAGMENT_TAG = "TestFragment";

    Button backBtn;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.test_fragment_layout , null);
        backBtn = (Button) rootView.findViewById(R.id.back_btn);
        backBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onUiFragmentJumpToListener.fragmentBack();
            }
        });
        return rootView;
    }


}

 

  

  这样就构建起一个基本的以Fragment代替Activity的界面切换的结构。

 

Done!

 

以上是关于fragment的使用的主要内容,如果未能解决你的问题,请参考以下文章

在 Fragment 中使用 WebView

RadioGroup结合RadioButton使用切换Fragment片段

Asynctask结果显示重新创建片段后

Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)

片段上的 Mapbox 膨胀视图

Reload Activity 以在 Fragment 之间重新切换