如何以编程方式在 ViewPager 的实例化片段中实现自定义 ListView

How to programmatically implement a custom ListView in an instantiated fragment from ViewPager

在尝试创建带有选项卡视图的 activity 时,我使用了来自 Android Studio/IntelliJ IDEA 的 Tabbed Activity 模板.

我设法实例化了 3 个不同的选项卡,它们包含在 XML 资源中定义的自己的片段。 其中一个片段有一个 ListView 并填充它,我通过创建自定义 ArrayAdapter 找到了一个解决方案,发现 here.

我的问题是将 ListView 设置为该适配器,以便它显示我的数据。

嗯,比我想象的要容易..

要在其中一个选项卡中实例化片段,Tabbed 模板的流程如下:

public static class FragmentExample extends Fragment {
    public FragmentExample() {}

    public static FragmentExample newInstance() {
        FragmentExample fragment = new Fragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_example, container, false);
        return rootView;
    }
}

该片段由这一行膨胀,其中 fragment_example 是它的 XML 资源:

View rootView = inflater.inflate(R.layout.fragment_example, container, false);

我试图简单地使用相同的方法来膨胀包含我的 ListView 的 XML,然后以编程方式填充数据,最后将适配器设置到它。但它总是在我脸上抛出一个引用适配器对象的 NullPointerException。
我承认我不知道为什么,直到我读到这个答案:

MainActivity calls setContentView with R.layout.activity_main as parameter that contains a ViewPager and not a ListView. Since you don't have a ListView declare in to that layout, findViewById(android.R.id.list) returns null, and when you try access it (calling setAdapter) the NullPointerException is thrown.

我意识到我必须更改那个特定的片段 class,当然,但不仅仅是其中的代码..
通过做一些研究,我找到了 ListFragment class 并对其进行了分析。挺有意思的。

为了将我的 ListView 与我的实例化片段一起膨胀,我只需要将它扩展到 ListFragment class 而不是 Fragment 一个并像这样覆盖它的 onCreateView (我实际上是从 super class 本身改编的):

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final Context context = getActivity();

        FrameLayout root = new FrameLayout(context);

        FrameLayout lframe = new FrameLayout(context);

        ListView lv = new ListView(getActivity());
        lv.setId(android.R.id.list);
        lv.setDrawSelectorOnTop(false);
        lframe.addView(lv, new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

        root.addView(lframe, new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

        // ------------------------------------------------------------------

        // BEFORE SETTING YOUR CUSTOM ADAPTER TO THE LISTVIEW YOU MUST FIRST CREATE AN OBJECT
        // OF IT AND POPULATE YOUR DATA. THIS IS SHOWN IN THE CUSTOM ARRAYADAPTER LINK ABOVE //

        setListAdapter(customAdapter);

        // ------------------------------------------------------------------

        root.setLayoutParams(new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

        return root;
    }

这里发生的是它以编程方式设置片段和 ListView,因此我不需要 XML 资源文件。
然后它使用 setListAdapter 方法设置适配器,该方法在 ListFragment class 中定义。

我强烈建议你好好看看那个特定的 class 以便更好地理解它。

我是 Android 开发的新手。我希望我能用我所学的东西帮助别人。
请随时post评论中的任何改进。 :]