android Fragment 入门

翻译 2015年07月25日 20:18:07

  首先,先放出这次blog的演示demo,你需要使用android studio才能够打开它了,http://download.csdn.net/detail/tgbus18990140382/8933151

先来说说fragment是个什么东西。fragment是android3.0引入的设计理念,可以在用户不切换activity的情况下即时更新界面,fragment设计实际上和activity十分相似,fragment拥有activity的大部分重要的生命周期函数,你也可以近似的将fragment看作是activity

以下是fragment生命周期:


  图中我们可以看出fragment通过onAttach方法将生命周期和activity相关联,所以每个fragment可以看作是一个独立的activity。其中不同的是onCreateView方法中你需要返回fragment的view内容,onActivityCreated方法会通知fragment activity创建成功,在activity结束onDestory之前会调用onDestoryView方法销毁fragment中的view以释放内存。

  其他详细内容可参考android官方api refrence,这里我们就不再赘述了,下面我们就来详细说说如何使用fragment。

  我们可以近似的将fragment看作为activity,其不同之处以上已经做了大概的描述,因此我们使用fragment是也可以像使用activity一样简单。fragment可以作为独立的组建在各个activity中使用,提高了ui组建的重用率。下面我们看下如何静态的定义一个fragment:

  首先,我们新建一个类TitleFragment并继承自ListFragment(它是Fragment的子类,这里为了方便使用我们使用ListFragment,其与ListActivity类似),一般的我们创建一个fragment需要复写onCreateView方法并且返回创建完的view,但是这里我们使用的是ListFragment系统已经帮我们创建了相应的view,因此这里我们不需要复写onCreateView方法。我们需要为list设置adapter,这里我们复写onActivityCreated方法为ListFragment设置adapter,完整的Fragment的代码如下(其中需要的一些资源未包含其中):

/**
 * Created by OnlynightZhang on 2015/7/9.
 *
 */
public class TitlesFragment extends ListFragment{


    public List<String> TITLES;


    private TitlesItemClickListener listener;


    /**
     * fragment添加到activity上的时候首先会调用onAttach方法,
     * 如果container activity实现了{@TitlesItemClickListener}监听器的话,
     * 我们就可以在该方法中将acitivity强转为{@TitlesItemClickListener},
     * 方便fragment与activity通信
     * @param activity
     */
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);


        /**
         * 初始化监听器通信接口
         */
        try{
            listener = (TitlesItemClickListener)activity;
        }catch( ClassCastException e ){
            e.printStackTrace();
        }


        /**
         * 初始化界面显示用的list data
         */
        TITLES = new ArrayList<>();
        for (Article article: Articles.ShakespeareArticles ){
            TITLES.add( article.getTitle() );
        }
    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);


        /**
         * 创建adapter,并将其设置到fragment上
         */
        ArrayAdapter<String> adapter = new ArrayAdapter<>( getActivity(), android.R.layout.simple_expandable_list_item_1, TITLES );
        setListAdapter(adapter);


        /**
         * 当切换到横屏后,自动选中第一个fragment
         */
        if ( getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ){
            listener.onItemClick( 0, TITLES.get( 0 ) );
        }
    }




    /**
     * 复写该方法,用于接收点击事件
     * @param l
     * @param v
     * @param position
     * @param id
     */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {


        /**
         * 如果fragment的container activity实现了{@TitlesItemClickListener}的话,
         * 那么activtiy就能够接收到相应的事件
         */
        if ( listener != null ){
            listener.onItemClick( position, TITLES.get( position ) );
        }
    }


    /**
     * fragment与container activity通信用的监听器接口
     */
    public interface TitlesItemClickListener{
        void onItemClick( int position, String title );
    }
}

接下来我们需要在activity中使用Fragment,我们在要是使用的activtiy中引用fragment,代码如下:

<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"
    tools:context=".MainActivity">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment_titles"
        android:name="com.android.developer.officalfragmentdemo.fragment.TitlesFragment"/>

</LinearLayout>
使用<fragment>标签引入到activity中,并且使用android:name将<fragment>标签与TitleFragment class相关联。

接下来我们需要显示article的内容,这次我们同样也是创建一个DetailsFragment继承自Fragment,与刚才不同的是我们这回需要复写onCreateView方法,并且在fragment中使用我们自定义的布局。

首先,创建一个布局文件fragment_details.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:gravity="center_horizontal"
            android:id="@+id/article_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </ScrollView>

</LinearLayout>
由于显示的文字较多,为了能够完整的阅读这里使用了scrollview使TextView能够滑动(其布局与activity并没有什么不同)。

然后,我们需要创建一个DetailsFragment继承自Fragment,并且复写onCreateView方法,然后使用layoutinflator将布局中的view加载并返回,最后提供一个外部能够设置内容的接口用于设置文章的内容,代码如下:

/**
 * Created by OnlynightZhang on 2015/7/9.
 *
 */
public class DetailsFragment extends Fragment{

    private TextView contentTextView;

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

    private void initView( View contentView ){
        contentTextView = (TextView)contentView.findViewById( R.id.article_content );
    }

    public void setArticleContent( String content ){
        if ( content != null && contentTextView != null ){
            contentTextView.setText( content );
        }
    }

    public void setContentByTitle( String title ){
        if ( title != null && contentTextView != null ){
            Article article = getArticle( title );
            if ( article != null ){
                contentTextView.setText( article.getContent() );
            }
        }
    }

    private Article getArticle( String title ){
        for ( Article article : Articles.ShakespeareArticles ){
            if ( article.getTitle().equals( title ) ){
                return article;
            }
        }
        return null;
    }
}

再次,DetailsFragment需要显示用的容器,我们这里使用一个独立的activity用于DetailsFragment的显示,其布局如下:

<RelativeLayout 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"
    tools:context="com.android.developer.officalfragmentdemo.DetailsActivity">

    <fragment
        android:id="@+id/fragment_details"
        android:name="com.android.developer.officalfragmentdemo.fragment.DetailsFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

activity的代码如下:

public class DetailsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_details);

        String title = getIntent().getStringExtra( "title" );
        if ( title != null ){
            DetailsFragment detailsFragment = (DetailsFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_details);
            detailsFragment.setContentByTitle( title );
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_details, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


为了简化demo,activity间我们只传递title,我们假设title是唯一的,通过title就可以找到唯一的acticle。

最后我们来看看MainActivity中代码:

public class MainActivity extends AppCompatActivity implements TitlesFragment.TitlesItemClickListener{


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();


        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent();
            intent.setClass( this, FragmentOperationActivity.class );
            startActivity( intent );
            return true;
        }


        return super.onOptionsItemSelected(item);
    }


    @Override
    public void onItemClick(int position, String title) {
        showToast(title);
        showArticle(title);
    }


    private void showArticle( String title ){
        Intent intent = new Intent();
        intent.setClass( this, DetailsActivity.class );
        intent.putExtra( "title", title );
        startActivity( intent );
    }


    private void showToast( String text ){
        Toast.makeText( this, text, Toast.LENGTH_SHORT ).show();
    }
}

这样一个完整的Fragment使用的demo就完成了,现在你可以运行下你的demo看看了。

Fragment从入门到精通之创建一个fragment②

步骤: 1.创建一个layout来作为fragment视图层次。 2.创建一个class继承自Fragment。 3.在class中使用onCreateView方法来联系视图层次。 4.在Acrivi...
  • u013003052
  • u013003052
  • 2015年11月15日 21:20
  • 1396

Android基础入门教程——5.1 Fragment基本概述

Android基础入门教程——5.1 Fragment基本概述 本节引言 1.基本概念 1)它是什么鬼,有什么用? 2)Fragment的生命周期图 3)核心要点: 4)Fragment的几个子类: ...
  • zpj779878443
  • zpj779878443
  • 2015年08月26日 14:03
  • 8991

Android基础入门教程——5.2.4 Fragment实例精讲——底部导航栏+ViewPager滑动切换页面

前三节我们分别用不同的方式实现了普通底部导航栏的效果,而本节我们将会在第二个实例的基础上 加上ViewPager来实现滑动切换页面的效果!大部分朋友都知道这个ViewPager是什么东西吧,如果 不知...
  • zpj779878443
  • zpj779878443
  • 2015年08月31日 15:44
  • 8406

Android在Fragment中嵌套(添加)Fragment

注意导包: import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; impo...
  • zhaihaohao1
  • zhaihaohao1
  • 2016年07月08日 18:34
  • 3841

Android之Fragment(一):静态使用碎片

创建Fragmentpublic class MyFragment extends Fragment { @Override public View onCreateView(Layo...
  • lj2012sy
  • lj2012sy
  • 2016年06月14日 15:02
  • 537

【android实战经验】关闭Fragment的方法

getActivity().onBackPressed()。 该方法用于监听用户点击返回键的事件,也可以调用它来关闭view。 在FragmentTransaction对象中添加fragmen...
  • Miehalu
  • Miehalu
  • 2015年11月17日 17:30
  • 4729

安卓强大的Fragment管理器

XFrag简介版本号:1.0.1 测试版XFrag https://github.com/zkbuttXFrag 采用函数式链式调用,即可轻松管理应用中的所有FragmentXFrag 帮忙我们轻松应...
  • zkbutt
  • zkbutt
  • 2016年09月09日 00:24
  • 952

Android fragment监听返回键

fragment需要监听返回键时分两种情况,一种是有其他控件获取了焦点,另一种是没有其他控件获得焦点。 先看第二种情况,代码如下: MyFragment.Java [...
  • love_xiaozhao
  • love_xiaozhao
  • 2017年04月10日 12:38
  • 636

Android中Fragment的详解和使用。

一、Fragment的基础知识介绍 1.1概述 1.1.1 特性         Fragment是activity的界面中的一部分或一种行为。可...
  • u012386435
  • u012386435
  • 2016年08月22日 15:52
  • 918

Android Fragment中监听事件

问题: Fragment中没有提供监听touch事件的方法。 解决方案: Activity中能够监听touch事件。 于是在Activity中写一个接口,MyOnTouchLi...
  • jdsjlzx
  • jdsjlzx
  • 2014年03月07日 10:39
  • 24929
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android Fragment 入门
举报原因:
原因补充:

(最多只允许输入30个字)