为何未在XML中添加ListView标签,ListFragment仍可正常工作?
嘿,我来帮你把这个问题理清楚~
为什么你的ListFragment无需自定义XML里的<ListView>也能正常运行?
其实ListFragment本身自带了一个默认布局!当你没有重写onCreateView()方法来加载自定义布局时,它会自动使用内部预设的布局——这个布局里已经包含了一个id为android.R.id.list的ListView组件。
你看你的FragmentA代码,只在onCreate()里设置了列表适配器,没有重写onCreateView()去加载自己的XML布局,所以ListFragment自动启用了默认布局,自然能正常显示列表内容。官方文档提到的“需要带有ListView标签的XML文件”,是针对自定义ListFragment布局的场景:比如你要在列表上方加一个标题栏,这时候你需要自己写XML,并且必须在布局里保留一个id为android.R.id.list的ListView,否则ListFragment找不到对应的列表控件才会报错。
关于android.app.Fragment与android.support.v4.app.Fragment的区别,能不能解释这个现象?
能,但只覆盖了一部分逻辑:
- 版本兼容性:
android.app.Fragment是Android 3.0(API 11)原生引入的,只能在3.0及以上系统使用;而android.support.v4.app.Fragment是支持库提供的,用来让低版本系统(比如Android 2.x)也能使用Fragment功能。 - 类体系独立:两个包下的Fragment(包括ListFragment)是完全独立的实现,但它们的核心逻辑是一致的——都自带默认的ListView布局。
你提到的那篇帖子会帮你理解两个包的兼容性差异和类实现区别,但你这个场景的核心原因是ListFragment的默认布局机制,不过理解两者的区别能帮你避开混用带来的坑。
重要提醒:不要同时混用两个包的Fragment!
你当前同时使用android-support-v4-app-fragment和android-app-fragment是非常危险的:这两个包的Fragment是不同的类,搭配对应的FragmentManager使用时必须严格匹配——比如AppCompatActivity的getSupportFragmentManager()只能管理support/v4或AndroidX包下的Fragment,而原生的getFragmentManager()只能管理android.app包下的Fragment。混用会导致崩溃或异常行为,建议你统一使用一套包体系(比如全部用AndroidX替代旧的support库)。
附上你提供的代码参考:
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"> <FrameLayout android:id="@+id/newFrame" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary"> </FrameLayout> </LinearLayout>
MainActivity代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); Fragment fragmentA = new FragmentA(); fragmentTransaction.add(R.id.newFrame, fragmentA, "fragmentA"); fragmentTransaction.commit(); } }
ListFragment代码
public class FragmentA extends ListFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String dataArray[] = new String[]{"One", "Two", "Three",}; ListAdapter listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, dataArray); setListAdapter(listAdapter); } }
内容的提问来源于stack exchange,提问作者Mauricio Etchevest

