Android2.x中使用Fragment的调查
Fragment是在android3.0中引入的,其功能和Activity基本相似,有自己的回调和生命周期,对于Fragment的理解我们可以解释为碎片或片段,这一点和DOM中的片段可以类比。
关于设计哲学、生命周期、事务管理、与Activity通信、ActionBar的使用,官方的文档给出了比较详细的说明,这里不做赘述了。
http://developer.android.com/guide/components/fragments.html
根据目前调查的情况这里列出几点
Google为Android2.x使用Fragment提供了支持,并提供了官方的类库,可以从SDK Manager中下载,SDK Manager中的位置为Extras > Android Support Library,下载后存放于android-sdks\extras\android\support\v4中。
一般情况下如果只使用Fragment的话,那么该库就够用了,但是如果我们想用ActionBar的话,这个支持类库的功能就不够了。
该方案是使用actionbarsherlock开源类库,该方案提供了Fragment和ActionBar的支持,其本身的Fragment支持采用的是Google解决方案的类库。具体的使用类似于GreenDroid,需要使用该方案的应用程序需要导入actionbarsherlock项目。
本次调查因为涉及到ActionBar,所以主要的输出内容以actionbarsherlock作为基础。
从actionbarsherlock官方网站下载actionbarsherlock项目及demo,
地址:https://github.com/JakeWharton/ActionBarSherlock/zipball/4.1.0
这里有几点需要注意:
1.因为ADT版本差异,官方网站提供的导入步骤在较高版本的ADT中导入失败,这里采用的方法新建Android项目,然后将actionbarsherlock的library目录作为项目源码拷贝到新建项目的根目录下面,
2.actionbarsherlock中有的内容不好打包,只能通过项目引用的方式来工作。
3.编译环境的AndroidSDK版本必须在3.2以后,即project.properties中的target必须大于等于13,但工作换进可以是2.x。
我们的项目如果需要引用该库,需要这样引入:
右键 > properties > Android > library > Add > actionbarsherlock项目
而不是这样:右键 > Build Path > Config Build Path > Project > Add > actionbarsherlock项目
ActionBar使用:
- public class MainActivity extends BaseActivity{
- private final static String TAB1 = "home";
- private final static String TAB2 = "live";
- private final static String TAB3 = "column";
- private final static String TAB4 = "news";
- private final static String TAB5 = "setting";
- int mStackLevel = 1;
- HomeFragment homeFragment = new HomeFragment();
- LiveFragment liveFragment = new LiveFragment();
- ColumnFragment columnFragment = new ColumnFragment();
- NewsFragment newsFragment = new NewsFragment();
- SettingFragment settingFragment = new SettingFragment();
- ……………………………
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.fragment_stack);
- final ActionBar bar = getSupportActionBar() ;
- bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
- bar.addTab(bar.newTab().setIcon(R.drawable.tab_icon_home_bg)
- .setText(R.string.tab_label_home)
- .setTabListener(new TabListener(homeFragment,TAB1)));
- bar.addTab(bar.newTab().setIcon(R.drawable.tab_icon_live_bg)
- .setText(R.string.tab_label_live)
- .setTabListener(new TabListener(liveFragment,TAB2)));
- bar.addTab(bar.newTab().setIcon(R.drawable.tab_icon_column_bg)
- .setText(R.string.tab_label_column)
- .setTabListener(new TabListener(columnFragment,TAB3)));
- bar.addTab(bar.newTab().setIcon(R.drawable.tab_icon_news_bg)
- .setText(R.string.tab_label_news)
- .setTabListener(new TabListener(newsFragment,TAB4)));
- bar.addTab(bar.newTab().setIcon(R.drawable.tab_icon_setting_bg)
- .setText(R.string.tab_label_setting)
- .setTabListener(new TabListener(settingFragment,TAB5)));
- if (savedInstanceState != null) {
- bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
- }
- }
- ……………………
- }
说明:
Fragment使用:
- public class SettingFragment extends BaseFragment {
- int mNum;
- private Button share;
- private Button clear;
- private Button contact;
- /**
- * 该方法用于Fragment默认构造
- * @return
- */
- public SettingFragment(){
- }
- public SettingFragment(int num){
- this.mNum = num;
- }
- /**
- * When creating, retrieve this instance's number from its arguments.
- */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Utils.log("onCreate");
- super.onCreate(savedInstanceState);
- mNum = getArguments() != null ? getArguments().getInt("num") : 5;
- }
- /**
- * The Fragment's UI is just a simple text view showing its instance number.
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- Utils.log("onCreateView");
- View v = inflater.inflate(R.layout.setting, container, false);
- getViews(v);
- setListener();
- return v;
- }
- private void getViews(View container){
- share = (Button)container.findViewById(R.id.setting_share_button);
- clear = (Button)container.findViewById(R.id.setting_clear_button);
- contact = (Button)container.findViewById(R.id.setting_contact_button);
- }
- private void setListener(){
- share.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(getActivity(),ShareActivity.class));
- }
- });
- clear.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(getActivity(),ClearActivity.class));
- }
- });
- contact.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(getActivity(),ContactActivity.class));
- }
- });
- }
- }
说明:
fragment第一次绘制它的用户界面的时候, 系统会调用此方法。为了绘制fragment的UI,此方法必须返回一个View, 这个view是你的fragment布局的根view。如果fragment不提供UI, 可以返回null。
根据目前调查的情况,这里给出几点建议
项目向Fragment框架靠拢整理方案在技术上是可行的,并能因此提高系统的性能,但是在部分UI和用户体验上可能与之前的预期存在一点小差异,可能需要小修改。