-
碎片介绍
-
碎片使用方式
-
碎片生命周期
-
碎片界面滑动
- 碎片介绍
碎片是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间。 - 碎片使用方式
1)布局文件添加碎片
在xml文件直接使用fragment标签
2)动态添加碎片
可以在程序运行时动态地添加到活动当中,根据具体情况来动态地添加碎片
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) {
View view = inflater.inflate(R.layout.my_fragment, container, false);
return view;
}
}
可以将碎片放在一个FrameLayout中,之后我们将在代码中替换FrameLayout里的内容,从而实现动态添加碎片的功能。
MyFragment fragment = new MyFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.right_layout, fragment);
ft.commit();
具体步骤:
1.创建待添加的碎片实例
2.获取到FragmentManager,在活动中可以直接调用getFragmentManager()方法得到
3.开启一个事务,通过调用beginTransaction()方法开启
4.向容器内添加碎片,一般使用repalce()方法实现,需要传入容器id和待添加的碎片
5.提交事务,调用commit()方法来完成
3)碎片中模拟返回栈
模仿类似于返回栈的效果,点击back可以回到上一个碎片,addToBackStack()方法可以用于将一个事务添加到返回栈中。
MyFragment fragment = new MyFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.right_layout, fragment);
ft.addToBackStack(null);
ft.commit();
一般传null值,效果是点击back,会发现程序并没有退出,而是回到了MyFragment界面,再次按下back才会退出。
- 碎片生命周期
每个碎片在其生命周期内也可能会经历这几种状态:运行状态、暂停状态、停止状态、销毁状态
- onAttach()
当碎片和活动建立关联的时候调用。 - onCreateView()
为碎片创建视图(加载布局)时调用。 - onActivityCreated()
确保与碎片相关联的活动一定已经创建完毕的时候调用。 - onDestroyView()
当与碎片关联的视图被移除的时候调用。 - onDetach()
当碎片和活动解除关联的时候调用
生命周期图如下:
- 碎片界面滑动
1)FragmentTranscation事务add()和replace()方法区别
使用 FragmentTransaction 的时候,它提供了这样两个方法,一个 add , 一个 replace ,对这两个方法的区别一直有点疑惑。我觉得使用 add 的话,在按返回键应该是回退到上一个 Fragment,而使用 replace 的话,那个别 replace 的就已经不存在了,所以就不会回退了。但事实不是这样子的。add 和 replace 影响的只是界面,而控制回退的,是事务。
add是把一个fragment添加到一个容器 container 里
replace是先remove掉相同id的所有fragment,然后在add当前的这个fragment
在大部分情况下,这两个的表现基本相同。一般会使用一个FrameLayout来当容器,而每个Fragment被add 或者 replace 到这个FrameLayout的时候,都是显示在最上层的。所以你看到的界面都是一样的。但是,使用add的情况下,这个FrameLayout其实有2层,多层肯定要比一层的来得浪费,所以还是推荐使用replace。当然有时候还是需要使用add的。比如要实现轮播图的效果,每个轮播图都是一个独立的Fragment,而他的容器FrameLayout需要add多个Fragment,这样他就可以根据提供的逻辑进行轮播了。
而至于返回键的时候,这个跟事务有关,跟使用add还是replace没有任何关系。(需要添加到返回栈中)
2)FragmentTabHost使用
注意:Fragment之前切换时每次都会调用onCreateView方法,导致每次Fragment布局都重绘,无法保持Fragment原有状态。解决方法:
private View rootView;// 缓存Fragment view
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG, "onCreateView");
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_1, null);
}
// 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除,
//要不然会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
}
return rootView;
}
Paste_Image.png
import com.example.android.supportv4.R;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;i
mport android.support.v4.app.FragmentTabHost;
/** * This demonstrates how you can implement switching between the tabs of a * TabHost through fragments, using FragmentTabHost. */
public class FragmentTabs extends FragmentActivity {
private FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
FragmentStackSupport.CountingFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
LoaderCursorSupport.CursorLoaderListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
LoaderCustomSupport.AppListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
}
}
网友评论