您的位置:首页 > 移动开发 > Android开发

Android - 卡片式布局 Fragment 详细回顾(二)

2015-09-01 20:15 801 查看
上篇( Android - 卡片式布局 Fragment 详细回顾(一))回顾了Fragment的使用原因,生命周期,在不同的生命期函数内做的事情,以及如何静态的(从xml文件中)创建Fragment。这篇回顾如何动态创建Fragment,FragmentManager与FragmentTransaction的API。

四、Fragment的创建方式2——动态创建

在窗口中动态添加Fragment的代码如下:

1.获取FragmentManager对象

FragmentManager fragmentManager = getFragmentManager();


2.开始Fragment事务

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();


3.创建Fragment对象

MyFragment1 fragment1 = new MyFragment1();


4.向窗口中添加Fragment

fragmentTransaction.replace(R.id.id_container, fragment1);


5.提交Fragment事务

fragmentTransaction.commit();


至于FragmentManager与FragmentTransaction一会再讨论,这里先将整个app跑起来。

首先是Activity的布局文件,这里提供了一个fragment的容器,用了一个FrameLayout,具体布局如下:

Actvity_main.xml

<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"
>
<FrameLayout
android:id="@+id/id_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"></FrameLayout>

<LinearLayout
android:id="@+id/id_bottom_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
>

<Button
android:id="@+id/id_fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:text="Fragment1"
android:layout_weight="1"/>
<View android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#808080"
/>
<Button
android:id="@+id/id_fragment2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment2"
android:background="@null"
android:layout_weight="1"/>

</LinearLayout>
<View android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#808080"
android:layout_above="@id/id_bottom_btn"
/>
</RelativeLayout>


两个Fragment的布局文件出文字外都一样:

Fragment1.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#808080">

<TextView
android:id="@+id/id_fragment1_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#ffffff"
android:textSize="30sp"
android:text="This is Fragment1"/>

</RelativeLayout>


Activity的Java文件:

public class MainActivity extends Activity {
private Button btn_fragment1;
private Button btn_fragment2;
private MyFragment1 fragment1 = null;
private MyFragment2 fragment2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_fragment1 = (Button) findViewById(R.id.id_fragment1);
btn_fragment2 = (Button) findViewById(R.id.id_fragment2);
btn_fragment1.setOnClickListener(new ButtonListener());
btn_fragment2.setOnClickListener(new ButtonListener());
setDefaultFragment();
}
private void setDefaultFragment() {
btn_fragment1.setBackgroundColor(Color.GRAY);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment1 fragment1 = new MyFragment1();
fragmentTransaction.replace(R.id.id_container, fragment1);
fragmentTransaction.commit();
}
class ButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (v.getId()) {
case R.id.id_fragment1:
btn_fragment1.setBackgroundColor(Color.GRAY);
btn_fragment2.setBackgroundColor(Color.WHITE);
if(fragment1 == null){
fragment1 = new MyFragment1();
}
fragmentTransaction.replace(R.id.id_container, fragment1);
break;
case R.id.id_fragment2:
btn_fragment1.setBackgroundColor(Color.WHITE);
btn_fragment2.setBackgroundColor(Color.GRAY);
if(fragment2 == null){
fragment2 = new MyFragment2();
}
fragmentTransaction.replace(R.id.id_container, fragment2);

break;
default:
break;
}
fragmentTransaction.commit();

}
}
public void DebugLog(String string){
Log.e("_MyFragment1", "MainActivity----"+string);
}
}


两个fragment的Java文件只是加载的布局不一样。

MyFragment1.Java:

public class MyFragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
DebugLog("onCreateView()");
View view = inflater.inflate(R.layout.fragment1, container,false);
return view;
}
}


此时运行app即可,效果图如下:



在动态创建fragment时,有两个类特别重要,一个是FragmentManager,一个是FragmentTransaction。

FragmentManager,可以先通过字面意思理解一下,Fragment管理者。这个类提供了很多API对Fragment进行管理:

1、管理Fragment事务

如上面代码,通过beginTransaction()开始一个Fragment事务。

2、查找Fragment。

通过id或者tag可以在窗口(Activity)中查找Fragment。对应的方法分别是findFragmentById(int id)和findFragmentByTag(String tag)。

3、跟踪回退栈状态。

通过FragmentManager的addOnBackStackChangedListener方法可以添加监听回退栈的监听对象。通过removeOnBackStackChangedListener方法可以移除。监听对象实现了OnBackStackChangedListener接口,接口中需要重写的方法是onBackStackChanged()。当Fragment出栈或者入栈时该方法会被调用。

4、恢复历史状态。

要恢复某一个fragment的状态只需要把它前面的所有状态全部出栈即可。(书上有这么一句话,回退栈中存储的实际上是Fragment的状态而不是对象本身。这里怎么理解,突然发现这个还需要写点代码测试一下,以前理解错了?)。

5、管理Fragment的状态。

FragmentManager提供了putFragment()和getFragment()方法来保存和获得状态。这一般在onSaveInstanceState方法(可以类比Activity中的onSaveInstance方法使用)中使用。

尽管FragmentManager可以做这么多,但是真正负责Fragment显示或者移除操作的还需要FragmentTransaction来完成。

1、添加Fragment

Transaction提供了三种添加Fragment的重载形式。

public FragmentTransaction add(Fragment fragment, String tag)
public FragmentTransaction add(int containerViewId, Fragment fragment)
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag)


其中第一个是添加一个没有UI的fragment。第二三个可以通过参数很好理解

2、删除fragment

public FragmentTransaction remove(Fragment fragment)


删除当前窗口中有fragment参数指向的Fragment对象,因此删除之前应该通过tag或者id获取该Fragment。

3、替换fragment

public FragmentTransaction replace(int containerViewId, Fragment fragment)
public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag)


替换相当于先执行了remove方法,然后执行了add方法。

4、显示和隐藏Fragment

public FragmentTransaction show(Fragment fragment, String tag)
public FragmentTransaction hide(Fragment fragment, String tag)


这两个方法相当于对fragment的跟视图调用了serVisibility(View.VISIBLE)和setVisibility(View.GONE)。

注意:事务只能提交一次。

下一篇Fragment与Activity的交互。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: