应用场景:
众所了解Android上的界面展示都是通过Activity实现的,但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了。为了让界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像Activity一样包含布局。Fragment通常是嵌套在Activity中使用的。首先需要注意,Fragment是在3.0版本引入的,如果你使用的是3.0之前的系统,需要先导入android-support-v4的jar包才能使用Fragment功能。知识点介绍:
一、如何创建Fragment。首先需要创建继承Fragment的子类,Fragment类的代码看起来很像Activity。它与Activity一样都有回调函数,例如onCreate(),onStart(),onPause(),和onStop()。事实上,如果你正在将一个现成的Android应用转而使用Fragment来实现,可以简单的将代码从Activity的回调函数移植到各自的Fragment的回调函数中,简单而可行。
Fragment的生命周期方法主要包括如下:
1、onAttach
2、onCreate
3、onCreateView
4、onActivityCreated
5、onDestroyView
6、onDestroy
7、onPause
public class TestFragment extends Fragment { /**当Fragment已经跟Activity关联上的时候,这个回调被调用。Activity会作为onAttach()回调方法的参数来传递*/ @Override public void onAttach(Activity activity) { super.onAttach(activity); } /**当创建Fragment时,系统调用该方法 在实现代码中, 应当初始化想要在Fragment中保持的必要组件, 当Fragment被暂停或者停止后可以再次恢复。*/ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } /**Fragment第一次绘制它的用户界面的时候, 系统会调用此方法。 为了绘制Fragment的UI, 此方法必须返回一个View, 这个view是你的Fragment布局的根view。*/ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // R.layout.activity_main 自定义的布局文件 View view = inflater.inflate(R.layout.activity_main, null); return view; // return super.onCreateView(inflater, container, savedInstanceState); } /**当Activity的onCreate()方法执行完之后,调用这个回调方法。*/ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } /**当跟Fragment关联的视图层正在被删除时,调用这个回调方法。*/ @Override public void onDestroyView() { super.onDestroyView(); } /**当从Activity中解除Fragment的关联时,调用这个回调方法。*/ @Override public void onDestroy() { super.onDestroy(); } /*================================================================*/ /**用户将要离开Fragment时,系统调用这个方法作为第一个指示(然而它不总是意味着Fragment将被销毁。) 在当前用户会话结束之前,通常应当在这里提交任何应该持久化的变化(因为用户有可能不会返回)。*/ @Override public void onPause() { super.onPause(); } }
二、如何将Fragment添加到Activity。
此部分可以参看http://blog.csdn.net/t12x3456/article/details/8104574 这篇文章,博主写的很详尽。本文主要侧重于【在代码中添加Fragment到ViewGroup】的方式。
使用此方法需要了解一下以下三个类对象:
android.support.v4.app.FragmentActivity
android.support.v4.app.FragmentManager
android.support.v4.app.FragmentTransaction
首先我们使用的Activity需要继承(extends)FramentActivtiy。
public class MainActivity extends FragmentActivity然后通过获取FragmentTransaction 对象得到FragmentTransaction来完成Fragment的事务(比如添加,删除,替换等)操作,最后提交事务。
<span style="white-space:pre"> </span>FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); ExampleFragment fragment = new ExampleFragment(); transaction.add(R.id.main_frameLayout, fragment); transaction.commit();
使用方式:
第一步:新建项目FragmentStudy,AndroidManifest.xml如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.fragmentstudy" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar" > <activity android:name="com.example.fragmentstudy.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
第二步:创建ExampleFragment(Fragment的子类)与ExampleFragment相应的布局文件layout_fragment_example.xml。
【layout_fragment_example.xml】
<?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="vertical" > <TextView android:layout_height="wrap_content" android:layout_width="match_parent" android:text="ExampleFragment" android:gravity="center" android:id="@+id/fragment_textView" android:textColor="@android:color/black"/> </LinearLayout>
【ExampleFragment.java】
import java.util.Date; import android.annotation.SuppressLint; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @SuppressLint("ValidFragment") public class ExampleFragment extends Fragment{ private String title = ""; public ExampleFragment(String title) { super(); this.title = title; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.layout_fragment_example, null); TextView textView = (TextView) view.findViewById(R.id.fragment_textView); textView.setText(textView.getText().toString()+"\n"+title+"\n"+new Date().getTime()); // return super.onCreateView(inflater, container, savedInstanceState); return view; } }第三步:编写activity_main.xml主布局文件与MainActivity.java。
【activity_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:background="@android:color/white" android:layout_height="match_parent" tools:context=".MainActivity" > <FrameLayout android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/main_frameLayout"> </FrameLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_alignParentBottom="true" android:orientation="vertical"> <GridView android:layout_height="wrap_content" android:layout_width="match_parent" android:columnWidth="50dp" android:horizontalSpacing="10dp" android:id="@+id/main_gridView" android:numColumns="3"> </GridView> </LinearLayout> </RelativeLayout>【MainActivity.java】
import java.util.ArrayList; import java.util.List; import com.example.fragmentstudy.adapter.GridAdapter; import com.example.fragmentstudy.domain.GridInfo; import android.os.Bundle; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; public class MainActivity extends FragmentActivity { private GridView gridView; private List<GridInfo> gridInfos = new ArrayList<GridInfo>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews() { gridView = (GridView) findViewById(R.id.main_gridView); GridAdapter gridAdapter = new GridAdapter(MainActivity.this); getGridOnfoList(); gridAdapter.setList(gridInfos); gridView.setAdapter(gridAdapter); gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); ExampleFragment fragment = new ExampleFragment("主功能页面"); transaction.add(R.id.main_frameLayout, fragment); transaction.commit(); gridView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); //通过anim xml 配置Fragment切换效果 new / old //上出下进 transaction.setCustomAnimations(R.anim.push_up_in, R.anim.push_up_out); GridInfo info = gridInfos.get(arg2); ExampleFragment fragment = new ExampleFragment(info.getName()); transaction.replace(R.id.main_frameLayout,fragment); // transaction.addToBackStack(null); //提供返回上一页面的功能 transaction.commit(); } }); } private void getGridOnfoList() { for(int i=0;i<6;i++){ GridInfo gridInfo = new GridInfo("测试"+i, R.drawable.ic_launcher+""); gridInfos.add(gridInfo); } } }
第四步:本演示项目的主要代码如上,一下为辅助的GirdView菜单效果的相关.java文件与.xml文件。
【GridInfo.java】
public class GridInfo { private String name; private String appImage; public GridInfo(String name, String appImage) { super(); this.name = name; this.appImage = appImage; } public String getAppImage() { return appImage; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
【GirdAdapter.java】
import java.util.List; import com.example.fragmentstudy.R; import com.example.fragmentstudy.domain.GridInfo; import android.content.Context; import android.graphics.Color; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class GridAdapter extends BaseAdapter { private class GridHolder { ImageView appImage; TextView appName; } private Context context; private List<GridInfo> list; private LayoutInflater mInflater; public GridAdapter(Context c) { super(); this.context = c; } public void setList(List<GridInfo> list) { this.list = list; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { GridHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.grid_item, null); holder = new GridHolder(); holder.appImage = (ImageView)convertView.findViewById(R.id.itemImage); holder.appName = (TextView)convertView.findViewById(R.id.itemText); convertView.setTag(holder); }else{ holder = (GridHolder) convertView.getTag(); } GridInfo info = list.get(position); if (info != null) { holder.appName.setText(info.getName()); int colorInt = Color.parseColor("#CCFF66"); if(position%6==1){ colorInt = Color.parseColor("#336699"); } else if (position%6==2) { colorInt = Color.parseColor("#663366"); }else if (position%6==3) { colorInt = Color.parseColor("#ABCDEF"); }else if (position%6==4) { colorInt = Color.parseColor("#669933"); }else if (position%6==5) { colorInt = Color.parseColor("#CC3399"); } holder.appImage.setBackgroundColor(colorInt); holder.appName.setTextColor(Color.BLACK); holder.appName.setGravity(Gravity.CENTER); } return convertView; } }
【grid_item.xml】
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="4dip" > <ImageView android:id="@+id/itemImage" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerHorizontal="true" > </ImageView> <TextView android:id="@+id/itemText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/itemImage" android:layout_centerHorizontal="true" android:layout_marginTop="4dp" android:gravity="center" android:text="TextView01" android:textColor="@android:color/black" android:textSize="10dp" > </TextView> </RelativeLayout>
除此之外还需要两个动画效果文件res/anim下的push_up_in.xml、push_up_out.xml。
【push_up_in.xml】
<?xml version="1.0" encoding="utf-8"?> <!-- 上滑切入 --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <translate android:fromXDelta="0%p" android:toXDelta="0%p" android:fromYDelta="100%p" android:toYDelta="0%p" android:duration="1000" /> </set>【push_up_out.xml】
<?xml version="1.0" encoding="utf-8"?> <!-- 上滑切出 --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <translate android:fromXDelta="0%p" android:toXDelta="0%p" android:fromYDelta="0%p" android:toYDelta="-100%p" android:duration="1000" /> </set>