Fragment使用具体解释

fragment是Google在3.0版本号中推出的新功能,如今已经增加到V4包中,假设要使用V4兼容包中的Fragment须要将Activity换成FragmentActivity,调用的getSupportFragmentManager获取FragmentManager而不是getFragmentManager。

Fragment是Google大力推荐使用的一个功能。它和Activity功能事实上差点儿相同,只是比Activity更加的灵活和轻巧,Fragment寄存在Activity上面,他的生命周期直接受宿主Activity的影响,我们使用Fragment能够把它当做一个自己定义视图一样来使用,使用好Fragment的前提是了解其生命周期,以下一张图来显示其与宿主Activity生命周期的关系:

当然上面的生命周期中我们不须要都重写。甚至你一个生命周期方法不敲代码也能够正常执行。一般假设Fragment有视图的话我们须要重写onCreateView。更加须要你也能够重写其他的生命周期的方法。

与本节知识点相关的类主要有:FragmentManager、FragmentTransaction、Fragment这三个。这里我给大家提出来几个有用的类,都是Google帮我们分装好而且经常会使用到的类:DialogFragment、ListFragment、PreferenceFragment,第一个是用来创建Dialog的,第二个是一个含有ListView的Fragment。最后一个一般用来作为偏好方面的功能的设计,类似于手机里面的设置界面。

以下就来给这三个类中的经常用法列出来。

FragmentManager:

beginTransaction():用来得到事务对象,兴许对Fragment的加入删除等都是靠事务对象。

addOnBackStackChangedListener():给回退栈加入一个监听,回退栈中的Fragment数量变化都会调用这个监听。

findFragmentbyid():依据Fragment的id找到相应的Fragment。

findFragmentByTag():依据TAG找到相应的Fragment

popBackStack():将回退栈中的Fragment弹出也就是销毁。这种方法有非常多个重载方法,能够指定一个Fragment弹出。

FragmentTransaction:

add():将一个Fragment加入到事务中,该方法有多个重载。

replace():将Fragment替换指定的容器控件。假设是动态创建一个Fragment常常使用这种方法。

addtoBackStack():将Fragment加入到回退栈中。

remove():移除一个Fragment对象。

hide():隐藏一个Fragment对象。

commit():提交本次事务,仅仅要涉及到事务都会有这么一个方法,比方数据库中用到了事务也有这种方法。

show():跟hide相应使用。

Fragment:

setArguement():常常使用这种方法传递数据,相应的方法为getArgument();

我们用一个实例来演示Fragment的使用,实例仅仅有一个Activity,而Activity布局文件里左右各一个Fragment,左边的Fragment中仅仅有一个ListView,右边Fragment中仅仅有一个ImageView,点击左边的ListView让右边的Fragment中的ImageView显示不同的图片。

这里关键是左右Fragment交互的问题,解决问题我们有两种方式。一种是基于接口回调的方式。还有一种我们能够是观察者模式,能够使用我们先前讲过的第三方EvnetBus,这里我们就使用接口回调的方式来解决。我们先来上效果图

(这里ListView的线条不正确的问题是模拟器的原因。真机执行不存在这个bug)

Fragment的使用有两种方式

静态:直接在布局文件里声明Fragment。

动态:在布局文件里使用容器控件占位。然后使用前面说的replace方法替换掉。

由于第一种方式比較简单,这里的样例我们使用另外一种方式。

首先来看Activity的布局文件

<?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="horizontal">

    <RelativeLayout
        android:id="@+id/containerB"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginRight="20dp"
        android:layout_weight="1"
        android:gravity="center"></RelativeLayout>

    <FrameLayout
        android:id="@+id/containerA"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"></FrameLayout>

</LinearLayout>

使用一个Relativelayout和一个framelayout作为占位控件。

当然我们先要有2个Fragment,以下贴出两个Fragment的代码:

左边的Fragment:

public class BFragment extends Fragment {
    private ListView listView;
    private OnClickItemListener onClickItemListener;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        onClickItemListener = (OnClickItemListener) getActivity();
        View view = inflater.inflate(R.layout.bfragment_layout, null);
        listView = ((ListView) view.findViewById(R.id.bfragment_listView));
        List<String> names = new ArrayList<>();
        {
            names.add("可爱");
            names.add("活泼");
            names.add("成熟");
            names.add("高贵");
            names.add("文静");
        }
        ArrayAdapter adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, names);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?

> parent, View view, int position, long id) {
                onClickItemListener.clickedItem(position);
                Toast.makeText(getActivity(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
            }
        });
        return view;
    }

    //回调接口用于传递数据
    public interface OnClickItemListener {
        void clickedItem(int position);
    }

}

这里我们定义了一个接口OnClickItemListener用于和Activity通信。

右边的Fragment:

public class AFragment extends Fragment {
    private View view;
    private ImageView imageView;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.afragment_layout, null);
        imageView = (ImageView) view.findViewById(R.id.afragment_imgv);
        imageView.setImageResource(R.drawable.girl);
        return view;
    }
    @Override
    public void onResume() {
        super.onResume();
        Bundle bundle = getArguments();
        if (bundle != null) {
            switch (bundle.getInt("position")) {
                case 0:
                    imageView.setImageResource(R.drawable.loveliness);
                    break;
                case 1:
                    imageView.setImageResource(R.drawable.lively);
                    break;
                case 2:
                    imageView.setImageResource(R.drawable.ripe);
                    break;
                case 3:
                    imageView.setImageResource(R.drawable.noble);
                    break;
                case 4:
                    imageView.setImageResource(R.drawable.gentle);
                    break;
                default:
                    imageView.setImageResource(R.drawable.girl);
            }
        }
    }
}

这里代码非常easy我就不多说了。以下重点是怎样把这两个Fragment加入到Activity中和他们之间怎样通信的。

既然Activity是这两个Fragment的宿主。那么Activity和Fragment的通信自然是非常easy的,既然Activity和Fragment通信非常easy并且两个Fragment又是在同一个Activity中。那么他们之间的通信自然就非常方便了,没错,我们就是使用Activity作为中转类似于手机通信中的基站的作用。前面一个Fragment已经提供了一个接口,我们仅仅须要让Activity实现这个接口就能够了。至于把Fragment加入到Activity中的问题,我们前面已经提供了2个容器控件,这里就非常easy了,代码例如以下:

   getFragmentManager().beginTransaction().replace(R.id.containerA, new AFragment()).commit();
        getFragmentManager().beginTransaction().replace(R.id.containerB, new BFragment()).commit();

没错。简单的我都不想再和你提什么了。来看Activity的完整代码

public class MainActivity extends Activity implements BFragment.OnClickItemListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getFragmentManager().beginTransaction().replace(R.id.containerA, new AFragment()).commit();
        getFragmentManager().beginTransaction().replace(R.id.containerB, new BFragment()).commit();
    }

    @Override
    public void clickedItem(int position) {
        AFragment aFragment = new AFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        aFragment.setArguments(bundle);
        getFragmentManager().beginTransaction().replace(R.id.containerA, aFragment).addToBackStack(null).commit();
    }
}

扫描关注我的微信公众号:

是不是特别简单呢??我们仅仅须要在重写的方法中动态的去创建右边的Fragment就能够把点击的位置传过去了。非常微妙的一种方式,假设你对这个不太熟能够慢慢的体会当中的关系,这里我给大家说说大致的思路:左边的Fragment我们提供了一个接口,而里面又有一个属性是这个接口。属性指向Activity,当使用接口中的方法的时候系统会去找实现了这个接口的类,自然就找到了Activity了,也就是会运行Activity中重写的clickItem方法,由于这种方法在Activity中,我们自己能够在这种方法中动态的去创建又变的Fragment而且把点击的位置传给它。

回调接口的时候刚開始我也不是非常会,慢慢的无论他然后自己就回了,真是奇怪。!

Fragment的知识大致就是这么多吧。最后送上demo给大家:点击打开链接

时间: 2024-10-09 07:24:55

Fragment使用具体解释的相关文章

android - Fragment getView() 总是返回null

如果你在使用Fragment的时候,有时会遇到调用Fragment.getView()的时候,总是返回一个null值. 可能出现此问题的原因是,你在Activity中,调用adapter.getItem()来获取当前Fragment. 大概如下 int index= _viewPaper.getCurrentItem(); Fragment fragment=_myFragmentAdapter.getItem(index); //这一步总是返回null值 View view= fragment

Fragment 与Fragment沟通

模式图: 不同activity 里面的fragment 同一个activity里面的两个fragment 详给解释一下activity 内部的fragment 怎么沟通, In FragmentA: firstly before we add the FragmentB to transaction,we can set target fragment as FragmentA for the FragmentB ,we are going to add together with reques

android Fragment与Activity交互,互相发数据(附图具体解释)

笔者最近看官方training.发现了非常多实用又好玩的知识. 当中.fragment与Activity通信就是一个. fragment与Activity通信主要是两点: 1.fragment传递信息给Activity 此点是通过在fragment中定义接口与Activity共享数据. 2.Activity传递信息给fragment 此点主要是通过fragment的getArgument()和setArgument()两个函数传递bundle来传递. 效果:(最后附上源代码) 主要流程: 1.在

Android fragment onHiddenChanged方法具体解释

项目中.为了实现不同fragment之间值得传递,首先想到的是利用bundle或者shareprefercnce之类的共享数据机制,当不符合项目需求,有点过于复杂和冗余,就利用网上一位前辈的建议.在主Activity中,创建一个共享的数据变量,在其它fragment中仅仅要获取到这个值就能够得到数据,实现共享.代码例如以下: 主activity定义一个共享数据变量: private String instrName; public String getInstrName() { return i

如何使用viewpager与fragment写一个app导航activity

今天我们来看一下如何使用viewpager和fragment组合来写一个app导航activity,这里使用到了android开源控件viewpagerindicator,有兴趣的同学可以去它网站上看看它的介绍. 附上效果截图一张: demo中只有一个activity,是用activity_main.xml来布局,其内容如下: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:and

读书笔记-fragment的使用

fragment的用法: FragmentManager fm = getSupportFragmentManager(); //fragment在队列存在,fragmentManager会返还这个fragment,不存在则返回null Fragment fragment = fm.findFragmentById(R.id.fragment_container); if (fragment == null){ fragment = new CrimeFragment(); fm.beginTr

【Android基础】Fragment 详解之Fragment生命周期

上一篇文章简单介绍了一下Fragment,这一篇文章会详细的说一下Fragment的生命周期和创建一个用户界面. Fragment的主要功能就是创建一个View,并且有一个生命周期来管理这个View的创建和销毁.Fragment的生命周期与Activity的生命周期类似,都会有一些回调方法,你所做的工作就是利用好这些生命周期方法,在恰当的方法中做恰当的工作. Fragment的生命周期与Activity的状态图如下: 左侧是Activity的生命周期状态,右侧对应的是这个状态下回执行Fragme

Android实习札记(5)---Fragment之底部导航栏的实现

Android实习札记(5)---Fragment之底部导航栏的实现 --转载请注明出处:coder-pig 在Part 4我们回顾了一下Fragment的基本概念,在本节中我们就来学习Fragment应用的简单例子吧! 就是使用Fragment来实现简单的底部导航栏,先贴下效果图: 看上去很简单,实现起来也是很简单的哈!那么接着下来就看下实现的流程图吧: 实现流程图: 看完流程图是不是有大概的思路了,那么接着就开始代码的编写吧: 代码实现: ①先写布局,布局的话很简单,一个FrameLayou

Android ViewPager和Fragment实现顶部导航界面滑动效果

在项目中,我们常常需要实现界面滑动切换的效果.例如,微信界面的左右滑动切换效果.那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果. 一. ViewPager 官方API 首先我们来看一下ViewPager官方给出的解释,如图: 具体意思如下: Layout 管理器允许用户可以在页面上,左右滑动来翻动页面.你可以考虑实现PagerAdapter接口来显示该效果. ViewPager很多时候会结合Fragment一块使用,这种方法使得管理每个页面的生命周期变得