Android Fragment出错:that is not a Fragment

        最近做项目要用到公告系统,不用想,肯定要用到Fragment碎片。但Fragment是Android3.0(API Level 11)才开始引入的,而我们写的项目最低版本是Android2.3(API Level 9),最蛋疼的就是你要为这大约7%(截止到2015年2月)的用户考虑,不能直接用android.app.Fragment。谷歌也没办法,总不能让android3.0以下的用户用不了fragment吧,如果强迫用户去更新系统或硬件那肯定会被骂死的,所以google那些大神们就写了兼容低版本的Fragment并放在android.support.v4.jar兼容包中。

        我没注意到xml文件中不能使用<fragment>节点,因为前面提到了:Fragment是Android3.0(API Level 11)才开始引入的,我的项目最小版本是Android2.3(API Level 9),编译版本是Android4.0(API Level 14)。所以就出现了下面这样的错误:

...

android.view.InflateException: Binary XML file line #9: Error inflating class fragment

...

Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class cn.smc.notice.NoticeListFragment that is not a Fragment

...

        第一个错误信息还阔以理解:xml文件中的<fragment>节点默认是使用android.app.Fragment中的Fragment,而Fragment类是继承自android.support.v4.app.Fragment中的Fragment,所以会实例化失败。但第二个我第一次见到就懵了:它竟敢说我的NoticeListFragment不是一个Fragment,我都继承了Fragment你还说我不是一个Fragment?不过现在看来就不难理解了,原来这是两个不同包中的Fragment类,不可以互用。

        可是,就在刚刚我再次运行时竟然发现竟然奇迹般的可以运行了,也不报错。我啥也没干啊,他不崩溃我可就崩溃了。哪位大神知道可以跟我解释一下。

        所以要保证所有的关于Fragment的相关引入和类引用都是来自Android支持包,就只能在Java代码中动态加载Fragment了。

        关于Fragment新闻的例子网上和很多Android书上都有,这里就不细讲了,他们一般都是在xml文件中设置<fragment>节点实现的,我这里是动态加载fragment。

原理:

Android Fragment出错:that is not a Fragment_第1张图片

NoticeActivity:公告Activity

NoticeContentActivity:公告内容Activity

NoticeListFragment:公告列表Fragment

NoticeContentFragment:公告内容Fragment

所以,为了同时适应手机和平板,需要两个activity(包含三个布局文件)、两个Fragment(包含两个布局文件)来实现。

目录结构:

Android Fragment出错:that is not a Fragment_第2张图片

关键代码:

NoticeActivity.java:

public class NoticeActivity extends FragmentActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_notice);
		if (this.findViewById(R.id.fl_notice_list_container) != null) {
			if (savedInstanceState != null) {
				return;
			}
			NoticeListFragment noticeListFragment = new NoticeListFragment();
			FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
			transaction.add(R.id.fl_notice_list_container, noticeListFragment);
			transaction.commit();
			if (this.findViewById(R.id.fl_notice_content_container) != null) {
				Log.e("shang", "big!big!");
				NoticeContentFragment noticeContentFragment = new NoticeContentFragment();
				FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
				transaction2.add(R.id.fl_notice_content_container, noticeContentFragment);
				transaction2.commit();
			}
		}
	}
}

NoticeContentActivity.java:

public class NoticeContentActivity extends FragmentActivity {

	public static NoticeContentFragment noticeContentFragment;
	public static void actionStart(Context context, String title,
			String author, String publishTime, String content) {
		Intent intent = new Intent(context, NoticeContentActivity.class);
		intent.putExtra("title", title);
		intent.putExtra("author", author);
		intent.putExtra("publishTime", publishTime);
		intent.putExtra("content", content);
		context.startActivity(intent);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_notice_content);
		if (this.findViewById(R.id.fl_notice_content_container) != null) {
			if (savedInstanceState != null) {
				return;
			}
			noticeContentFragment = new NoticeContentFragment();
			FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
			transaction.add(R.id.fl_notice_content_container, noticeContentFragment);
			transaction.commit();
		}
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		String title = getIntent().getStringExtra("title");
		String author = getIntent().getStringExtra("author");
		String publishTime = getIntent().getStringExtra("publishTime");
		String content = getIntent().getStringExtra("content");
		noticeContentFragment.refresh(title, author, publishTime, content);
	}
	
}

NoticeListFragment.java:

@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater
				.inflate(R.layout.fragment_notice_list, container, false);
		lv_notice_list = (ListView) view
				.findViewById(R.id.lv_notice_list);
		lv_notice_list.setAdapter(mAdapter);
		lv_notice_list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub
				NoticeBean noticeBean = list_notice.get(position);
				if (isTwoPane) {
					NoticeContentFragment noticeContentFragment = (NoticeContentFragment) NoticeListFragment.this.myActivity.getSupportFragmentManager()
							.findFragmentById(R.id.fl_notice_content_container);
					noticeContentFragment.refresh(noticeBean.getTitle(),noticeBean.getAuthor(),noticeBean.getPublish_time(),noticeBean.getContent());
				} else {
					NoticeContentActivity.actionStart(getActivity(),noticeBean.getTitle(),noticeBean.getAuthor(),noticeBean.getPublish_time(),noticeBean.getContent());
				}
			}
			
		});
		return view;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		if (getActivity().findViewById(R.id.fl_notice_content_container) != null) {
			isTwoPane = true;
		} else {
			isTwoPane = false;
		}
	}

源码免费下载:

源码下载

        

你可能感兴趣的:(api,Google,Android4.0,平板)