我们在认识安卓里面的事物的时候,很多时候都是先从它的生命周期开始认识。我们今天先来介绍下Fragment,先来看一下fragment的生命周期吧,首先偷一张官网的图:
一:Fragment生命周期:
(其中)
1.类似于activity,fragment的实例也是通过继承fragment来拿到,fragment中文意思,碎片,它不是一个完整界面,它是跟activity类似具有生命周期和回调的控件,但是又不能独立的存在,fragment的存在都需要通过绑定一个activity,称为它的宿主activity,也就是说,要显示出一个fragment,我们首先要在activity绑定上这个fragment,也就是在activity加载的时候,fragment调用onAttach绑定上去然后调用onCreate方法进行创建,对于两者一样名字的生命周期方法,你可以把他们相似的来理解。
2.onCreateView:绘制fragment的界面view,一定要把绘制好的view返回给activity,然后在activity里面加载出来。
3.onActivityCreated:当activity创建完成->也就是在宿主activity创建完成,就是activity的onCreate方法返回的是,fragment调用这个方法。
4.onStart和onResume跟activity的同名函数是一样的,使界面可见和获取焦点。一般在创建完成之后调用。
5.onPause和onStop:界面失去焦点和界面不可见。一般是在activity转到后台,其他的控件被唤到前台的时候调用。
6.onDestroyView:界面销毁,fragment被移除或者销毁的时候调用。
7.onDetach:与宿主activity解除关联。
个人觉得fragment比较需要注意的是fragmentManager的replace,add方法的时候,我觉得使用replace方法会比较好,使用add的话,如果add多次,所有的fragment都会被添加进来,replace会替换,也就是只会保留当前的fragment。比较值得注意的是fragment的addToBackStack方法,加到后台栈中,activity管理的后台栈,在使用fragmentTransaction调用这个方法之后并提交事务,这个fragment的管理就会添加到activity管理的后台栈中,当你按返回键的时候,会返回到上一个界面—-添加fragment事务之前的界面状态。
二:ActionBar在之前的菜单节中基本已经都讲了,都差不多。默认情况下ActionBar的图标按钮不能点击,setHomeButtonEnable(true)之后就可以点击了,在onOptionSelected里面通过id:android.R.id.home来捕捉事件。还有跟这节会有关的是ActionBar的navigationItem,actionbar的下方带有的选项卡,使用系统自带的actionbar的好处是,在很多情况下,它会帮我们自动找比较适合的方式来排列view。
下面就来介绍刚做的fragment,viewpager,actionbar配合实现的布局吧。
图中圆圈画出的overflow button要显示数来还是有点费劲。。
private void getOverflowMenu() {
ViewConfiguration viewConfig = ViewConfiguration.get(this);
try {
Field overflowMenuField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
if (null != overflowMenuField) {
overflowMenuField.setAccessible(true);
overflowMenuField.setBoolean(viewConfig, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
在代码要加入这一段代码才能用三个点来显示出不显示的菜单们。。
方框中的选项卡则是:
actionBar = getActionBar();
actionBar.setTitle("Fragment Demo");
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);//这种模式可以显示和添加选项卡
actionBar.setHomeButtonEnabled(true);//使actionbar图标按钮可以点击
actionBar.addTab(actionBar.newTab().setText("第一个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第二个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第三个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第四个fragment").setTabListener(this));
最主要的还是viewpager和actionbar item中监听:
vp.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int arg0) {
actionBar.setSelectedNavigationItem(arg0);
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int arg0) {
}
});
class FragmentPager extends FragmentStatePagerAdapter {
public FragmentPager(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public Fragment getItem(int position) {
return list.get(position);
}
@Override
public int getCount() {
return list.size();
}
}
这几个选项卡可以根据屏幕的大小改变现实方式,足够大的时候(平板或者横屏的时候)可以跟actionbar在同一区域显示,而且选中的tab可以居中显示,这点细节做的不错。
actionbar home键点击动作捕捉:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "this is home key", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
其实也没什么代码,就是api的调用,最重要的,要选择suppot.v13的jar包,不然会出现很多问题。以下贴出全部代码:
//MainActivity --- 主界面
package com.example.frangmentdemo;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewConfiguration;
import android.widget.Toast;
public class MainActivity extends Activity implements TabListener {
MyFragment fragment0;
MyFragment fragment1;
MyFragment fragment2;
MyFragment fragment3;
ActionBar actionBar;
private ActionBar.Tab tab1;
private ActionBar.Tab tab2;
private ActionBar.Tab tab3;
private ActionBar.Tab tab4;
private List<Fragment> list = new ArrayList<Fragment>();
Random random;
private ViewPager vp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getOverflowMenu();
initView();
initData();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "this is home key", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void initView() {
random = new Random();
vp = (ViewPager) findViewById(R.id.pager);
}
private void initData() {
actionBar = getActionBar();
actionBar.setTitle("Fragment Demo");
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setHomeButtonEnabled(true);
actionBar.addTab(actionBar.newTab().setText("第一个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第二个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第三个fragment").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第四个fragment").setTabListener(this));
vp.setAdapter(new FragmentPager(getFragmentManager()));
vp.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int arg0) {
actionBar.setSelectedNavigationItem(arg0);
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int arg0) {
}
});
}
class FragmentPager extends FragmentStatePagerAdapter {
public FragmentPager(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public Fragment getItem(int position) {
return list.get(position);
}
@Override
public int getCount() {
return list.size();
}
}
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
vp.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
}
private void getOverflowMenu() {
ViewConfiguration viewConfig = ViewConfiguration.get(this);
try {
Field overflowMenuField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
if (null != overflowMenuField) {
overflowMenuField.setAccessible(true);
overflowMenuField.setBoolean(viewConfig, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//main.xml---主界面布局
<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"
android:id="@+id/container"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.frangmentdemo.MainActivity" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</FrameLayout>
// MyFragment ----
package com.example.frangmentdemo;
import com.example.frangmentdemo.R;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyFragment extends Fragment {
String title ;
View view ;
public MyFragment(String title){
this.title = title ;
}
public void setTitle(String title){
((TextView)view.findViewById(R.id.text)).setText(title);
}
public MyFragment(){
this(null);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_test_stack, container, false);
if(title != null && !title.trim().equals("")){
((TextView)view.findViewById(R.id.text)).setText(title);
}
return view;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:id="@+id/root"
android:background="@android:color/black"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text"
android:textSize="20sp"
android:textColor="@android:color/white"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/back"
/>
</LinearLayout>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.frangmentdemo.MainActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>