首页 > 解决方案 > 如何在 dialogFragment 的 viewPager 内的片段中填充适配器?

问题描述

我正在尝试创建以下场景:

用户单击 a Button> 这显示 aDialogFragment 包含DialogFragmenta ViewPager,它有 2 个选项卡 - 一个显示颜色选择器片段,另一个显示符号选择器片段 每个选择器片段包含一个适配器,它将颜色/符号数组转换为漂亮的网格。

但是,它当前显示为空白 -DialogFragment出现,带有片段的其他部分,但没有适配器视图。

这是我所拥有的:

初始活动称为EditActivity。它有一个Button,当点击它时,会调用这个函数来显示DialogFragmentPickers

public void showPickers() {
        if(mDialogFragmentPickers == null) return;
        mDialogFragmentPickers.setColourSet(mColourSet);
        mDialogFragmentPickers.show(mFragmentManager, "Pickers");
    }

DialogFragmentPickersonCreate在这样的方法中初始化EditActivity

mDialogFragmentPickers = new DialogFragmentPickers();

传入的ColourSet基本上只是要在选择器中显示的颜色数组。DialogFragmentPickers然后应该将其传递到FragmentColourPicker初始化时。

这个DialogFragmentPickers类看起来像这样(我只展示了与 相关的部分ColourPicker,但SymbolPicker工作方式相同):

public class DialogFragmentPickers extends DialogFragment {

    private PickersPagerAdapter mPagerAdapter;
    private ViewPager           mViewPager;
    private ColourSet           mColourSet;
    private FragmentColourPicker    mColourPicker;

    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container,
            Bundle savedInstanceState) {

        // Inflate layout
        View view = inflater.inflate(R.layout.dialog_fragment_pickers, container, false);

        mPagerAdapter = new PickersPagerAdapter(getChildFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = view.findViewById(R.id.pager);
        mViewPager.setAdapter(mPagerAdapter);

        return view;

    }

    public void setColourSet(ColourSet colourSet) {
        mColourSet = colourSet;
        if(mColourPicker == null) getColourPickerFragment();
        else mColourPicker.setColourSet(mColourSet);
    }

    private void getColourPickerFragment() {
        if (mPagerAdapter == null) return;
        mColourPicker = (FragmentColourPicker) mPagerAdapter.getItem(0);
        if(mColourSet != null) mColourPicker.setColourSet(mColourSet);
    }

    public class PickersPagerAdapter extends FragmentPagerAdapter
    {

        PickersPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new FragmentColourPicker();
                case 1:
                    return new FragmentSymbolPicker();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return getResources().getString(R.string.colours);
                case 1:
                    return getResources().getString(R.string.symbols);
            }
            return null;
        }
    }

布局文件包含:

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- Current + adjacent page titles...-->
    <android.support.v4.view.PagerTitleStrip
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        android:textColor="#fff" />
</android.support.v4.view.ViewPager>

此寻呼机中使用的第一个 Fragment 是FragmentColourPicker. 它是这样定义的:

public class FragmentColourPicker extends Fragment {

    GridView mColourGrid;
    Context mContext;
    ColourSet mColourSet;
    ChartColourAdapter mColourAdapter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_colour_picker, container, false);

        mColourGrid = view.findViewById(R.id.gridview_colourPicker);

        initialiseWithColourSet(); // Returns without doing anything if colourSet is not set up yet

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mContext = getActivity();

    }

    @Override
    public void onDestroy(){ super.onDestroy();}

    public void setColourSet(ColourSet thisColourSet) {
        mColourSet = thisColourSet;
        initialiseWithColourSet(); // Returns without doing anything if the colourGrid is not set up yet
    }

    public void initialiseWithColourSet() {

// Make sure that the colourSet and the colourGrid have both been initialised
        if(mColourSet == null) return;
        if(mColourGrid == null) return;

        // Now set up ChartColourAdapter to display colours in grid
        // Initialise currently highlighted colour to default
        // Set on click listener for each colour
        mColourAdapter = new ChartColourAdapter(mContext,
                R.layout.adapter_pattern_colour_cell_layout,
                mColourSet.getColours());
        mColourGrid.setAdapter(mColourAdapter);

    }

}

FragmentColourPicker和(fragment_colour_picker.xml)的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/colour_picker_fragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/fui_transparent"
    android:orientation="vertical">

    <GridView 
        android:id="@+id/gridview_colourPicker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorBg"
        android:paddingBottom="@dimen/activity_standard_margin"
        android:columnWidth="@dimen/grid_cell_column_width"
        android:gravity="center"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:padding="@dimen/activity_small_margin"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="@string/prompt_swipe_for_symbols"
        android:padding="@dimen/activity_small_margin"
        android:background="@color/colorBg"
        />

</LinearLayout>

当我运行所有这些DialogFragment时,单击按钮时会出现 ,并显示FragmentColourPicker. 我可以FragmentSymbolPicker来回滑动。但是,在 ColourPicker 中显示的唯一内容是TextView提示用户滑动以查看符号。里面的GridView实际颜色根本不显示。

从调试器来看,我认为问题在于initialiseWithColourSet似乎只有一个colourSetORcolourGrid设置 - 从不同时设置。这使它无需尝试设置颜色适配器即可返回。

如果initialiseWithColourSet从 调用onCreateView,则 colourGrid 已设置,但 colourSet 未设置(因为尚未传入)。这足够合理。但是,当稍后(从 DialogFragment)传入 colourSet 时, colourGrid 又恢复为 null,因此该函数再次返回而没有执行任何操作。

我显然有一些错误的顺序,或者在没有意识到的情况下重新初始化 colourGrid / ColourPicker。

标签: androidandroid-fragmentsandroid-dialogfragment

解决方案


对我来说,这似乎是一个订单问题。为确保您Fragment在正确的时间获取数据,我会将片段所需的数据Adapter通过构造函数传递到。我会在那里保留它们的引用,然后使用静态newInstance(... requiredData)方法实例化片段。然后,您可以确定当它们由适配器“创建”时,它们将具有所需的信息。

像这样的东西:

你的片段类:

...

Object myRequiredData;

static FragmentColourPicker newInstance(... requiredData) {
   FragmentColourPicker f = new FragmentColourPicker();
    f.setRequiredData(requiredData);        

    return f;
}

public void setRequiredData(Object reqData){
    this.myRequiredData = reqData;
}

...

您的适配器类:

public class PickersPagerAdapter extends FragmentPagerAdapter {

        Object reqData0;
        Object reqData1;

        PickersPagerAdapter(FragmentManager fm, Object reqData0, Object reqData1) {
            super(fm);
            this.reqData0 = reqData0;
            this.reqData1 = reqData1;
        }

        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return FragmentColourPicker.newInstance(reqData0);
                case 1:
                    return FragmentSymbolPicker.newInstance(reqData1);
                default:
                    return null;
            }
        }

    ...

}

推荐阅读