Android:DialogFragment中的ViewPager:Fragment没有视图

时间:2014-11-20 14:17:03

标签: android android-fragments android-viewpager

我正在尝试使用alertDialog创建一个带有取消和确定按钮的pageView

问题是当我在方法onCreateDialog中设置适配器时,我得到了:

  

“java.lang.IllegalStateException:Fragment没有视图”。

如果我注释掉这一行,我没有例外。

我也试过覆盖班级onCreateView()中的方法MyDialog,但问题是一样的。

有人有想法吗?

MainActivity.java

public class MainActivity  extends FragmentActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);

        // Capture button clicks
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                MyDialog alertdFragment = new MyDialog();
                alertdFragment.show(getSupportFragmentManager(), "Alert Dialog Fragment");
            }
        });
    }
}

MyDialog.java

public class MyDialog extends DialogFragment implements OnTabChangeListener, OnPageChangeListener {

    private ViewPager viewPager;
    private View view;
    private TabHost tabHost;

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

    private List<Fragment> getFragments(){
        List<Fragment> fList = new ArrayList<Fragment>();

        // TODO Put here your Fragments
        fList.add(DetailsFragment.newInstance(1,"S1"));
        fList.add(DetailsFragment.newInstance(2,"S2"));
        fList.add(DetailsFragment.newInstance(3,"S3"));

        return fList;
    }

    // Method to add a TabHost
    private static void AddTab(FragmentActivity fragmentActivity, TabHost tabHost, TabHost.TabSpec tabSpec) {
        tabSpec.setContent(new MyTabFactory(fragmentActivity));
        tabHost.addTab(tabSpec);
    }

    // Manages the Tab changes, synchronizing it with Pages
    public void onTabChanged(String tag) {
        int pos = this.tabHost.getCurrentTab();
        this.viewPager.setCurrentItem(pos);
    }

    // Manages the Page changes, synchronizing it with Tabs
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        int pos = this.viewPager.getCurrentItem();
        this.tabHost.setCurrentTab(pos);
    }


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Builder builder = new Builder(getActivity());
        view = getActivity().getLayoutInflater().inflate(R.layout.dialog, null);
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);

        tabHost = (TabHost) view.findViewById(android.R.id.tabhost);
        tabHost.setup();

        // TODO Put here your Tabs
        AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab1").setIndicator("Tab1"));
        AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab2").setIndicator("Tab2"));
        AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab3").setIndicator("Tab3"));

        tabHost.setOnTabChangedListener(this);

        // Fragments and ViewPager Initialization
        List<Fragment> fragments = getFragments();
        viewPager.setAdapter(new FragmentAdapter(getChildFragmentManager(), fragments));
        viewPager.setOnPageChangeListener(this);

        // Positive button
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Do something else
            }
        });

        // Negative Button
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Do something else
            }
        });
        builder.setView(view);
        return builder.create();
    }

    @Override
    public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onPageSelected(int arg0) {
        // TODO Auto-generated method stub
    }

}

FragmentAdapter.java

public class FragmentAdapter  extends FragmentPagerAdapter {

    private List<Fragment> fragments;

    public FragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    public FragmentAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "Page " + position;
    }

    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

}

DetailsFragment.java

public class DetailsFragment extends Fragment {

    // Store instance variables
    private String title;
    private int page;

    // newInstance constructor for creating fragment with arguments
    public static DetailsFragment newInstance(int page, String title) {
        DetailsFragment fragmentFirst = new DetailsFragment();
        Bundle args = new Bundle();
        args.putInt("someInt", page);
        args.putString("someTitle", title);
        fragmentFirst.setArguments(args);
        return fragmentFirst;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        page = getArguments().getInt("someInt", 0);
        title = getArguments().getString("someTitle");
    }

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

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.details, container,false);
        TextView textView = (TextView) view.findViewById(R.id.detailsText);
        textView.setText(page + " -- " + title);
        return view;
    }
}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="dialog" />

</RelativeLayout>

dialog.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TabWidget
                android:id="@android:id/tabs"
                android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0" />

                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:layout_weight="0" />

                    <android.support.v4.view.ViewPager
                        android:id="@+id/viewpager"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_gravity="bottom" />

            </LinearLayout>
    </TabHost>
</RelativeLayout>

details.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/detailsText"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal|center_vertical"
        android:layout_marginTop="20dip"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="30dip" />

</LinearLayout>

修改:跟踪列表错误

11-21 20:12:56.224: E/AndroidRuntime(2864): FATAL EXCEPTION: main
11-21 20:12:56.224: E/AndroidRuntime(2864): java.lang.IllegalStateException: Fragment does not have a view
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.Fragment$1.findViewById(Fragment.java:1443)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:917)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.view.View.measure(View.java:15848)
11-21 20:12:56.224: E/AndroidRuntime(2864):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5012)

1 个答案:

答案 0 :(得分:0)

我还没试过这个,但根据错误,我的猜测是你试图过早配置你的寻呼机适配器。由于您的代码位于onCreateDialog中,因此您还没有告诉Android有关将进入对话框的视图,并且在您使用子片段管理器之前,它可能需要您的视图层次结构。

尝试将与视图寻呼机和标签主机有关的所有代码移动到onResume:

@Override
public void onResume() {
    super.onResume();
    if (viewPager != null) {
        return;
    }

    viewPager = (ViewPager) findViewById(R.id.viewpager);

    tabHost = (TabHost) findViewById(android.R.id.tabhost);
    tabHost.setup();

    // TODO Put here your Tabs
    AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab1").setIndicator("Tab1"));
    AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab2").setIndicator("Tab2"));
    AddTab(getActivity(), this.tabHost, this.tabHost.newTabSpec("Tab3").setIndicator("Tab3"));

    tabHost.setOnTabChangedListener(this);

    // Fragments and ViewPager Initialization
    List<Fragment> fragments = getFragments();
    viewPager.setAdapter(new FragmentAdapter(getChildFragmentManager(), fragments));
    viewPager.setOnPageChangeListener(this);
}

编辑: 嗯。也许问题是你需要让片段在生命周期的早期构建,然后再调用setAdapter。尝试将除实际调用之外的所有代码移回到onCreateDialog中的setAdapter,包括将FragmentAdapter保存在字段中,然后JUST在onResume中调用setAdapter:

@Override
public void onResume() {
    super.onResume();
    viewPager.setAdapter(fragmentAdapter);
}