经历了两三天的折磨,终于稍微弄懂了fragment的使用,来发表一下个人的愚见。
关于碎片的创建
右键新建fragment,弹出窗口勾选Create layout XML,则创建出以下java代码和xml
JAVA BlankFragment3
public class BlankFragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank_fragment3, container, false);
}
//其余生命周期已省去,此处只讨论onCreateView这个改写的方法
}
XML fragment_blank_fragment3.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".BlankFragment3">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
这样就预置好一个碎片了,当然也可以选择不勾选Create layout xml,在OnCreateView方法内
inflater.inflate(R.layout.XXXXXXXXXX, container, false);
XXX中选择你想要添加为碎片的layout也可以预置相应的碎片
关于碎片的使用
①碎片可以作为一个布局里的组件直接使用
<fragment
android:id="@+id/fragment"
android:name="com.example.administrator.myapplication.BlankFragment3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
②也可以在自己想要添加的Activity中这样使用
BlankFragment3 blankfragment3 = new BlankFragment3();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.XXX,blankfragment3);
transaction.commit();
其中R.id.XXX为注册在Activity中的一个组件(如Framelayout布局),可以不为fragment碎片
接下来为重点
困扰我这三天的问题是什么呢,因为我经过查阅书本及网上的资料,发现很多例程都是通过
BlankFragment3 blankfragment3 = new BlankFragment3();
这种方式创建的碎片
但是
但是
但是
这种方式创建的碎片,无法在相应Activity对其做出修改!
(可能是我个人能力不足,也欢迎大神来纠正我这个说法)
既是说以下情况
public class BlankFragment3 extends Fragment {
private View view;
private Button button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_blank_fragment3, container, false);
button = view.findViewById(R.id.button);
return view;
}
public void hhh(){
button.setText = "hhh";
}
}
类中定义了一个hhh()方法,想要修改R.layout.fragment_blank_fragment3这个layout中id为button的按钮
在Activity中
blankfragment3.hhh();
不是美滋滋?
这下就完蛋了
会出现一个空指针的报错!
是的,button没有被找到
为什么,我也不知道,等以后技能增长了再来填这个坑
现在猜测的原因是这个碎片的存在很奇怪,它既不是一个view,通过
fragmentManager.findFragmentById()也是找不到它的
但是创建碎片不就是为了操作里面的布局吗,如果在Activity中无法操作这个碎片,那它还有什么存在的意义呢?
原来,通过这种方式创建的碎片,它只能自己操作自己(或者说操作外面的Activity的方法或内容)
如下
public class BlankFragment3 extends Fragment {
private View view;
private Button button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_blank_fragment3, container, false);
button = view.findViewById(R.id.button);
button.setText = "hhh";
return view;
}
}
这种方法就可以正确修改fragment_blank_fragment3的id为button的按钮,或者添加监听其他内容,这样找到的button不为空指针,可以操作
只要在改写的onCreateView中把xml提前先设置好,就可以正确使用这种方式创建的碎片
/*题外话
onCreateView中可以通过(MainActivity) getActivity()的方式得到正在活动的Activity,从而达到碎片与Activity的联系*/
那么现在的情况是这样的
碎片能与Activity联系,Activity找不到碎片,那碎片和碎片怎么交互呢
(new的创建方式我不会,欢迎大神补充)
那这个时候我们可以采用第①种方法来实现碎片的交互
因为如果采用第①种方法,可以让Activity能找到对应的碎片实例,也可以随意修改碎片里的内容,也不会出现空指针的报错
在Activity中使用
BlankFragment3 blankfragment3 = (BlankFragment3) getSupportFragmentManager().findFragmentById(R.id.fragment)
这个R.id.fragment为xml中的中的Id
这样就可以blankfragment3.XXX随意调用碎片里的内容,注意不要使用FindViewById的方式(我没试过,但大家都说不行)
两种方式各有优劣,通过new创建的碎片,Activity无法找到它,而通过直接在xml中导入的碎片,是被写死的,无法在你想要的时刻动态地添加到你想要的地方,必须是xml能够找到这个碎片,才能对其发生的操作。
虽然说不能动态地添加到想要的地方,但是可以隐藏和显示嘛
transaction = fragmentManager.beginTransaction();
transaction.hide(fragment);
transaction.show(fragment);
transaction.commit();
transaction提供了这些方法可以隐藏和显示fragment,注意,必须transaction.commit()提交后上面的内容才会生效,而且transaction只能使用一次,想需要用多次必须通过fragmentManager.beginTransaction()再创建一个,可能是commit()完成后会被销毁吧
两三天就研究了这么些东西,希望对大家有帮助