<Fragment>的学习

本文介绍了一个基于Fragment的界面布局示例,展示了如何通过传递参数来更新Fragment的显示内容,并总结了Fragment的主要特性。

人生,只有你自己想努力,才能真正的努力。这是任何人都无法用逼迫让你达到的目的,它只能是出由你自己内心的意愿,你才会真正的着手去调整,去完善,去提升,去塑造一个更好的自己。


下面Fragment将会显示一个简单的界面布局文件,并根据传入的参数来更新界面.

package com.test.demo.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.test.demo.R;

public class BookDetailFragment extends Fragment {
    public static final String ITEM_ID = "item_id";
    //保存该fragment 显示的book对象
    BookContent.Book book;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //如果启动该 Fragment时包含了 ITEM_ID
        if (getArguments().containsKey(ITEM_ID)) {
            book = BookContent.itemMap.get(getArguments().getInt(ITEM_ID)); //①
        }
    }

    /**
     * 重写该方法,该方法返回的 view 将作为 Fragment 的显示的组件
     *
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View rootView = inflater.inflate(R.layout.fragment_book_detail, container, false);

        if (book != null) {
            //让book_title文本框显示 属性内容
            ((TextView) rootView.findViewById(R.id.book_title)).setText(book.title);
            ((TextView) rootView.findViewById(R.id.book_desc)).setText(book.desc);
        }

        return rootView;
    }

}

上面的①号代码获取该Fragment 时传入 ITEM_ID 参数,并根据该ID 获取 BookContent的 itemMap的数据信息.


BookContent 用于模拟系统的数据模型.

package com.test.demo.fragment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * book 对象
 */
public class BookContent {

    //定义一个内部类,作为 业务对象
    public static class Book {
        public Integer id;
        public String title;
        public String desc;

        public Book(Integer id, String title, String desc) {
            this.id = id;
            this.title = title;
            this.desc = desc;
        }

        @Override
        public String toString() {
//            return "Book{" +
//                    "id=" + id +
//                    ", title='" + title + '\'' +
//                    ", desc='" + desc + '\'' +
//                    '}';
            return title;
        }
    }

    //定义一个 list集合 记录所包含的Book对象
    public static List<Book> items = new ArrayList<>();
    // 使用Map集合记录系统所包含的Book对象
    public static Map<Integer, Book> itemMap = new HashMap<Integer, Book>();
    // 初始化一个static 的常量Map

    static {
//使用静态初始化代码
        addItem(new Book(4, "天龙4部", "神说,所谓幸福,是有一颗感恩的心,一个健康的身体,一份称心的工作,一位深爱你的爱人,一帮值得信赖的朋友。"));
        addItem(new Book(5, "天龙5部", "人生不是得到,而是学到:你不是得到一份圆满的姻缘,就是学到怎样更靠近幸福。你不是得到胜利,就是学到如何避免失败。你不是得到最终自己想要的结果,就是学到世事总不会尽如人意。"));
        addItem(new Book(6, "天龙6部", "人生,似一杯茶,似一杯苦涩的茶,品尝苦涩的味道,而回感却是甘甜的微笑。就似在努力中默默所承受的煎熬,历经磨难之后却是无比灿烂的微笑。人生,不要给自己留下什么遗憾,用最真的微笑去面对世界上所有的一切。其实,我们会发现,世界并非那么残酷,只要有微笑的心,世界的一切依然美好。"));
        addItem(new Book(7, "天龙7部", "牵挂是一种忧伤的幸福,当你牵挂一个人时,你就会想他是不是也在牵挂你。因为喜欢才牵挂,因为牵挂而忧伤,用心去感受对方的牵挂。牵挂是一份烂漫,一份深沉,一份纯美,一份质朴。"));
        addItem(new Book(1, "天龙八部", "其实很多事物,没有得到时总觉得美好,得到之后才开始明白,我们得到的同时也在失去。"));
        addItem(new Book(2, "神雕侠侣", "留住的叫幸福,流逝的叫遗憾:幸福的滋味是甜甜的,偶尔酸酸的;遗憾的感觉是苦苦的,偶尔辣辣的。好好对待你身边的人,能在一起就是幸福。如果爱上,就不要轻易放弃。怯懦,可能使你一辈子后悔。没有经历过爱情的人生是不完整的,没有经历过痛苦的爱情是不深刻的。爱情使人生丰富,痛苦使爱情升华……"));
        addItem(new Book(3, "倚天屠龙记", "你改变不了环境,但你可以改变自己;你改变不了事实,但你可以改变态度;你改变不了过去,但你可以改变现在;你不能控制他人,但你可以掌握自己;你不能预知明天,但你可以把握今天;你不可以样样顺利,但你可以事事尽心;你不能延伸生命的长度,但你可以决定生命的宽度。"));

    }

    private static void addItem(Book book) {
        itemMap.put(book.id, book);
        items.add(book);
    }

}

开发ListFragment的子类,则无须重写 onCreateView () 方法,只要调用 ListFragment的setAdapter(); 为Fragment设置Adapter 即可.

package com.test.demo.fragment;

import android.app.Activity;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class BookListFragment extends ListFragment {

    private Callbacks mCallbacks;


    //定义一个回调接口,该fragment 与它所在的Activity 需要实现该接口
    //该Fragment 将通过与它所在的Activity 进行交互
    public interface Callbacks {
        public void onItemSelected(Integer id);
    }

    public BookListFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //为 ListFragment 设置adapter
        setListAdapter(new ArrayAdapter<BookContent.Book>(getActivity(),
                android.R.layout.simple_list_item_activated_1,
                android.R.id.text1, BookContent.items
        ));
    }

    //当 Fragment被添加显示到 activity 时 回调该方法
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        //如果 Activity 没有实现 Callbacks 就抛出异常
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException(
                    "BookListFragment 所在的Activity必须实现 Callbacks接口"
            );
        }
        mCallbacks = (Callbacks) activity;

    }

    //当该 Fragment 从它所属的Activity被删除时回调该方法
    @Override
    public void onDetach() {
        super.onDetach();
        if (mCallbacks != null) {
            mCallbacks = null;
        }
    }

    //当用户点击某列表项时回调该方法
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        //触发mCallbacks 的 onItemSelected() 方法
        mCallbacks.onItemSelected(BookContent.items.get(position).id);
    }

    public void setActivateOnItemClick(boolean activateOnItemClick) {
        getListView().setChoiceMode(
                activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
                        : ListView.CHOICE_MODE_NONE);
    }

}

下面的布局文件 使用’<.fragment… > 元素添加一个 BookListFragment,该ACtivity,左边显示一个ListFragment, 右边显示一个FrameLayout容器,该FrameLayout容器将会动态更新其中显示的Fragment.

<?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:divider="?android:attr/dividerVertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:showDividers="middle"
    tools:context="com.test.demo.MainActivity">

    <!--添加一个 Fragment-->
    <fragment
        android:name="com.test.demo.fragment.BookListFragment"
        android:layout_width="0dp"
        android:id="@+id/book_list"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <!--添加一个FrameLayout容器-->
    <FrameLayout
        android:id="@+id/book_detail_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"></FrameLayout>


</LinearLayout>

下面是 Activity代码


package com.test.demo;


import android.app.Activity;
import android.os.Bundle;

import com.test.demo.fragment.BookDetailFragment;
import com.test.demo.fragment.BookListFragment;

public class MainActivity extends Activity implements  BookListFragment.Callbacks {

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

    }

    @Override
    public void onItemSelected(Integer id) {

        //创建 Bundle 准备向Fragment传入数据
        Bundle bundle = new Bundle();
        bundle.putInt(BookDetailFragment.ITEM_ID,id);

        //创建 BookDetailFragment 对象
        BookDetailFragment fragment = new BookDetailFragment();
        //向 Fragment 传入参数
        fragment.setArguments(bundle);

        //使用 Fragment 替换 book_detail_container容器显示当前的 Fragment

        //获取 Fragment管理器 然后开启事务
       // getFragmentManager().beginTransaction().replace(R.id.book_detail_container,fragment).commit();
        getFragmentManager().beginTransaction().replace(R.id.book_detail_container,fragment).commit(); //②

    }
}

上面的②号代码 就是调用了 FragmentTransaction 的 replace();动态的更新了book_detail_container容器,(也就是前面布局文件中的FrameLayout容器)中显示的Fragment.


关于Fragment可以总结一些几个特征:

  1. Fragment 总是作为Activity界面的组成部分.可调用getActivity(),方法获取它所在的activity;而Activity可以调用 FragmentManager的 findFragmentById()或者 findFragmentByTag();方法来获取fragment.
  2. 在 Activity运行过程中,可以调用 FragmentManager的 add(), remove(), replace();方法动态的对Fragment进行添加,删除和替换.
  3. 一个Activity可以同时组合多个Fragment,; 反过来一个Fragment可以也可被多个Activity复用.
  4. Fragment可以响应自己的输入事件,并拥有自己的生命周期,但他的生命周期,直接被所属的Activity的生命周期所控.

通常来说,创建Fragment通常会实现如下三个方法

  1. onCreate(); 系统创建Fragment时,系统调用该方法,实现代码中只初始化想要在fragment 中保持的必要组件,当Fragment被暂停或者停止可以恢复.
  2. onCreateView(); 当Fragment绘制界面组件的时候回调该方法.该方法必须返回一个view,该View也就是Fragment所显示的View.
  3. onPause(); 当用户离开该Fragment时将会回调该方法.
    在实际开发中,开发者可以根据需要重写Fragment的任意回调方法.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值