安卓Fragment快速入门

来源:互联网 发布:淘宝怎么自己做模板 编辑:程序博客网 时间:2024/05/16 13:58

如有转载,请申明:

转载至 http://blog.csdn.net/qq_35064774/article/details/52622714


Fragment虽然不是四大组件之一,但在界面布局方面非常重要。

Fragment的作用

FragmentAPI11时新引入的轻量级”Activity”。目的是为了更方便的适配大小屏幕,在平板和手机上可以有完全不同的Fragment。可以很方便的动态添加删除Fragment

 

Fragment的编写

Fragment类似于Activity,只要继承Fragment类即可。

 

package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup; import com.ittianyu.basictest.R; public class StaticUseFragment extends Fragment {     @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {         return inflater.inflate(R.layout.fragment_display, container, false);    }}

上述代码为最简单的Fragment,只有onCreateView这一个生命周期方法。

这个方法会在创建Fragment视图时调用,需要返回要显示的View

这里返回的是fragment_display.xml的视图。下面附上代码

<FrameLayout 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:background="#440000ff"    tools:context="com.ittianyu.basictest.fragmentquickstart.DisplayFragment">     <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="display fragment" /> </FrameLayout>

Fragment的静态引用

自己编写的Fragment可以像其他控件一样,直接在xml中引用。

具体引用代码如下。


<?xml version="1.0" encoding="utf-8"?><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"    tools:context="com.ittianyu.basictest.fragmentquickstart.FragmentQuickStartActivity">     <fragment        android:id="@+id/f_static_use"        android:name="com.ittianyu.basictest.fragmentquickstart.StaticUseFragment"        android:layout_width="match_parent"        android:layout_height="match_parent" /> </LinearLayout>


只需要使用fragment标签,然后加上name属性,指定要引用的Fragment对象即可。

但值得注意的时,这样做的时候,我的Android Studio IDE报了一个警告,不推荐这么做。

 

Fragment的动态引用

先分别编写3Fragment

package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.Fragment;import android.text.TextUtils;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import android.widget.Toast; import com.ittianyu.basictest.R; public class SoundFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_sound, container, false);        return view;    }}   package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup; import com.ittianyu.basictest.R;  public class SaveFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_save, container, false);    }}  package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup; import com.ittianyu.basictest.R; public class DisplayFragment extends Fragment {     @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_display, container, false);    }}

这三个Fragment和最开始介绍的编写方式差不多,只是换了个xml界面。

接下来是三个xml的代码

<FrameLayout 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:background="#44ff0000"    tools:context="com.ittianyu.basictest.fragmentquickstart.SoundFragment">     <Button        android:id="@+id/btn_get_text"        android:text="获取activity中的文本内容"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /> </FrameLayout>  <FrameLayout 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:background="#4400ff00"    tools:context="com.ittianyu.basictest.fragmentquickstart.SaveFragment">     <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="save fragment" /> </FrameLayout>  <FrameLayout 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:background="#440000ff"    tools:context="com.ittianyu.basictest.fragmentquickstart.DisplayFragment">     <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="display fragment" /> </FrameLayout>

有了Fragment,我们接下来写动态引用Fragment的类。

package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;import android.view.View; import com.ittianyu.basictest.R; public class FragmentQuickStartActivity extends AppCompatActivity implements View.OnClickListener {     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_fragment_quick_start);         init();    }     /**     * 初始化按钮事件     */    private void init() {        findViewById(R.id.sound).setOnClickListener(this);        findViewById(R.id.display).setOnClickListener(this);        findViewById(R.id.save).setOnClickListener(this);         sound();    }     @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.sound:                sound();                break;            case R.id.display:                display();                break;            case R.id.save:                save();                break;        }    }     /**     * 显示sound fragment     */    private void sound() {        // 获得fragment管理对象(使用v4包向下兼容)        FragmentManager manager = getSupportFragmentManager();        FragmentTransaction transaction = manager.beginTransaction();        transaction.replace(R.id.frame, new SoundFragment());        transaction.commit();    }    /**     * 显示sound fragment     */    private void save() {        // 获得fragment管理对象(使用v4包向下兼容)        FragmentManager manager = getSupportFragmentManager();        FragmentTransaction transaction = manager.beginTransaction();        transaction.replace(R.id.frame, new SaveFragment());        transaction.commit();    }    /**     * 显示sound fragment     */    private void display() {        // 获得fragment管理对象(使用v4包向下兼容)        FragmentManager manager = getSupportFragmentManager();        FragmentTransaction transaction = manager.beginTransaction();        transaction.replace(R.id.frame, new DisplayFragment());        transaction.commit();    }}

结构很简单的代码,三个按钮点击之后,分别显示相应的Fragment

对了,还没贴出该Activity对应的xml

<?xml version="1.0" encoding="utf-8"?><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"    tools:context="com.ittianyu.basictest.fragmentquickstart.FragmentQuickStartActivity">     <EditText        android:id="@+id/et_content"        android:hint="请输入内容"        android:layout_width="match_parent"        android:layout_height="wrap_content" />     <FrameLayout        android:id="@+id/frame"        android:layout_weight="3"        android:layout_width="match_parent"        android:layout_height="match_parent">    </FrameLayout>     <LinearLayout        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:id="@+id/sound"            android:text="声音"            android:layout_weight="1"            android:layout_width="0dip"            android:layout_height="wrap_content" />        <Button            android:id="@+id/display"            android:text="显示"            android:layout_weight="1"            android:layout_width="0dip"            android:layout_height="wrap_content" />        <Button            android:id="@+id/save"            android:text="存储"            android:layout_weight="1"            android:layout_width="0dip"            android:layout_height="wrap_content" />    </LinearLayout> </LinearLayout>

下面解释一下如何动态引用fragment

首先我们要管理fragment就需要一个FragmentManager

FragmentManager manager = getSupportFragmentManager();

然后通过管理器,开启一个事务,这样是为了一次性提交,防止界面花屏。

FragmentTransaction transaction = manager.beginTransaction();

拿着事务去替换fragment,也就是把Fragment放入到了idframe的控件中。

transaction.replace(R.id.frame, new DisplayFragment());

最后提交修改

transaction.commit();


运行之后,我们应该会看到如下界面。

点击不同的按钮会切换到相应的Fragment

然后你会看到图中Fragment中有个按钮是用来获取Activity中的EditText的中内容的。但是上面代码并没有实现,那么如何实现呢?

请继续往下看。


 

FragmentActivity交互

Fragment必须依赖Activity才能存在,所以一般来说都会持有Activity的引用,事实上API也是这样设计的。

Fragment类中,可以通过getActivity拿到Fragment所在的Activity引用。

因此,要实现点击Fragment中的按钮获取Activity控件内容,也变得很容易。

package com.ittianyu.basictest.fragmentquickstart; import android.os.Bundle;import android.support.v4.app.Fragment;import android.text.TextUtils;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import android.widget.Toast; import com.ittianyu.basictest.R; public class SoundFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_sound, container, false);        // 设置fragment中的按钮的点击事件        view.findViewById(R.id.btn_get_text).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 拿到fragment所处的activity,然后获取其中的edittext的内容,显示出来                EditText etContent = (EditText) getActivity().findViewById(R.id.et_content);                String content = etContent.getText().toString().trim();                if(TextUtils.isEmpty(content)) {                    Toast.makeText(getActivity(), "文本内容为空", Toast.LENGTH_SHORT).show();                   return;                }                Toast.makeText(getActivity(), content, Toast.LENGTH_SHORT).show();            }        });         return view;    }}

Fragment向下兼容

在文章开头就介绍了FragmentAPI11时才加入安卓的,也就是安卓3.0以后才可以使用Fragment,然而谷歌早就看穿了一切,为我们提供了向下兼容包,也就是常说的support包。

为了在低版本中使用Fragment,我们需要使用的是support.v4中的Fragment,而我们上面的代码也是这样做的,细心的你应该会发现我导入的是

import android.support.v4.app.Fragment;

而不是

import android.app.Fragment;

 

同样的,在Activity中,导入的也是v4的包

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentTransaction;

 

使用v4包的Fragment与正常的Fragment几乎没有差别,但有一个地方需要注意。

V4包时,获取FragmentManager要用getSupportFragmentManager,也就是如下。

FragmentManager manager = getSupportFragmentManager();

而如果是非兼容的API,则用的是getFragmentManager()

 

最后还需要提醒一点的是,现在(2016)安卓4.0以下的设备非常少了,基本都是上5.0。所以,一般情况下也没有必要向下兼容了。

 

1 0