关闭

android Fragment 入门

标签: fragment
679人阅读 评论(1) 收藏 举报
分类:

  首先,先放出这次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看看了。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:41501次
    • 积分:838
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:1篇
    • 译文:1篇
    • 评论:41条
    文章分类
    最新评论