使用Fragment兼容Tablet和Handset
为了适应Handset和Tablet等不同分辨率的android设备,google在android3.0之后提供了一个新的API,也就是Fragment,大家可以查阅官方SDK的详细说明。
?
以下是摘自官方SDK 的一张设计图,很好地展示了Fragment在兼容Tablet和Handset设备的设计理念。

?
首先解释一下,上述的设计原理。
1.针对Tablet,Activity A中包含了Fragment A和Fragment B,而Handset中的Activity A中只包含了Fragment A,至于Fragment B则通过对Fragment A的事件监听,来启动新的Activity B(包含Fragment B)将Fragment B显示给用户。
既然这样的话就必须用到两个布局,layout目录下默认存放的是Handset的布局,layout-large目录下存放的则是Tablet的布局。
更详细的请参考:http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html
?
2.接着看如何在布局中定义Fragment
参考一下配置文件:
?
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" ><fragment name="code">package com.test.fragment;import com.test.fragment.R;import android.app.ListFragment;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;public class ItemActivity extends ListFragment{private ItemAdapter adapter;private ImageView mLastIndicate = null;private Context mContext = null;private String [] mArr = null;private static OnItemChangeListener onItemChangeListener;public interface OnItemChangeListener{void onItemChange(int position);}@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);mContext = getActivity();mArr = new String[]{"item1","item2","item3"}; adapter = new ItemAdapter();}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onActivityCreated(savedInstanceState);setListAdapter(adapter);}@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {// TODO Auto-generated method stubsuper.onListItemClick(l, v, position, id);if(mLastIndicate != null){mLastIndicate.setVisibility(View.GONE);}ImageView imageView = (ImageView)v.findViewById(R.id.item_indicate);imageView.setVisibility(View.VISIBLE);mLastIndicate = imageView;onItemChangeListener.onItemChange(position);}public static void setItemChangeListener(OnItemChangeListener l){onItemChangeListener = l;}public class ItemAdapter extends BaseAdapter{private ViewHolder mHolder = null;public ItemAdapter(){}public int getCount() {// TODO Auto-generated method stubreturn mArr.length;}public Object getItem(int position) {// TODO Auto-generated method stubreturn position;}public long getItemId(int position) {// TODO Auto-generated method stubreturn position;}public View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubif(convertView == null){LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);convertView = inflater.inflate(R.layout.item_layout, parent, false);mHolder = new ViewHolder();mHolder.item_tv = (TextView)convertView.findViewById(R.id.item_tv);mHolder.item_indicate = (ImageView)convertView.findViewById(R.id.item_indicate);convertView.setTag(mHolder);}else{mHolder = (ViewHolder)convertView.getTag();}if(mLastIndicate == null){if(position == 0){mHolder.item_indicate.setVisibility(View.VISIBLE);mLastIndicate = mHolder.item_indicate;}}mHolder.item_tv.setText(mArr[position]);return convertView;}class ViewHolder{public TextView item_tv;public ImageView item_indicate;}}}在ItemActivity中设置onItemChangeListener监听器接口,在Item改变的时候,让MainActivity通过接口来刷新界面。
?
ContentActivity.java
package com.test.fragment;import com.test.fragment.R;import android.app.Fragment;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;public class ContentActivity extends Fragment {private String [] arr = null;private String [] arr0 = {"item1:","item1:","item1:","item1:","item1:"};private String [] arr1 = {"item2:","item2:","item2:","item2:","item2:"};private String [] arr2 = {"item3:","item3:","item3:","item3:","item3:"};private ContentAdapter adapter = null;private ListView lv = null;private Context mContext = null;@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);Bundle bundle = getActivity().getIntent().getExtras();int position = 0;if(bundle == null){position = 0;}else{position = bundle.getInt(MainActivity.KEY_POSITION);}switch(position){case 0:arr = arr0;break;case 1:arr = arr1;break;case 2:arr = arr2;break;}mContext = getActivity();}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubView view = inflater.inflate(R.layout.content_layout, container, false);lv = (ListView)view.findViewById(R.id.contentList);adapter = new ContentAdapter();lv.setAdapter(adapter);return view;}public void onUpdateContent(int position){switch(position){case 0:arr = arr0;break;case 1:arr = arr1;break;case 2:arr = arr2;break;}adapter.notifyDataSetChanged();}class ContentAdapter extends BaseAdapter{private ViewHolder mHolder;public ContentAdapter(){super();}public int getCount() {// TODO Auto-generated method stubreturn arr.length;}public Object getItem(int position) {// TODO Auto-generated method stubreturn position;}public long getItemId(int position) {// TODO Auto-generated method stubreturn position;}public View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubif(convertView == null){LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);convertView = inflater.inflate(R.layout.content_item_layout, parent, false);mHolder = new ViewHolder();mHolder.content_tv = (TextView)convertView.findViewById(R.id.content_tv);convertView.setTag(mHolder);}else{mHolder = (ViewHolder)convertView.getTag();}mHolder.content_tv.setText(arr[position]);return convertView;}class ViewHolder{public TextView content_tv;}}}?MainActivity.java
package com.test.fragment;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import com.test.fragment.ItemActivity.OnItemChangeListener;import com.test.fragment.R;public class MainActivity extends Activity implements OnItemChangeListener{private ContentActivity contentFragment = null;//private ItemActivity itemFragment = null;public static final String KEY_POSITION = "position"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); contentFragment = (ContentActivity)getFragmentManager().findFragmentById(R.id.content);ItemActivity.setItemChangeListener(this); }public void onItemChange(int position) {// TODO Auto-generated method stubif(contentFragment == null){Intent intent = new Intent(this,Content.class);Bundle bundle = new Bundle();bundle.putInt(KEY_POSITION, position);intent.putExtras(bundle);startActivity(intent);}else{contentFragment.onUpdateContent(position);}}}MainActivity的实现了OnItemChangeListener监听器接口,那么首先就要在onCreate的时候将监听器注册到ItemActivity中,在实现的方法中分别针对Tablet和Handset设备做了不同的处理。
?
欲知更多fragment的使用技巧,请参考官方SDK。
?
代码下载,请看附件。