viewpager 中的片段,未发现视图错误

fragments in viewpager, no view found error

我有一个activity持有一个片段,在这个片段中有一个按钮,当它被点击时,弹出一个对话框。

在这个对话框中,有一个Viewpager,里面有一些要显示的片段。

这是代码和错误,请您抽出宝贵的时间告诉我哪里错了。非常感谢您的帮助。

MainActivity.class

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

public class MainActivity extends FragmentActivity {

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

    setContentView(R.layout.activity_main);

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fm.beginTransaction();

    MyFragment fragment = new MyFragment();

    fragmentTransaction.add(R.id.container, fragment);

    fragmentTransaction.commit();

}
}

MyFragment.class

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_sandbox, container, false);
    Button button = (Button) v.findViewById(R.id.button);

    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            PagerDialog dialog = new PagerDialog(getActivity(),
                    getChildFragmentManager());
            dialog.show();
        }
    });
    return v;
}
}

PagerDialog.class

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class PagerDialog extends Dialog {

ViewPager mViewPager;
FragmentStatePagerAdapter mAdapter;
FragmentManager mFragmentManager;

public PagerDialog(Context context, FragmentManager fm) {
    super(context);
    mFragmentManager = fm;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.dialog);
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mAdapter = new MyAdapter(mFragmentManager);
    mViewPager.setAdapter(mAdapter);

}

private class MyAdapter extends FragmentStatePagerAdapter {

    public MyAdapter(FragmentManager fm) {
        super(fm);

    }

    @Override
    public Fragment getItem(int index) {
        return new DummyFragment();
    }

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

}

private class DummyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_dummy_layout,
                container, false);
        return v;
    }
}
}

这里是 dialog.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" >

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</LinearLayout>

这里是错误

03-06 19:43:38.487: E/AndroidRuntime(1167): FATAL EXCEPTION: main
03-06 19:43:38.487: E/AndroidRuntime(1167): Process: com.me.sandbox, PID: 1167
03-06 19:43:38.487: E/AndroidRuntime(1167): java.lang.IllegalArgumentException: No view found for id 0x7f05003d (com.mochimira.sandbox:id/pager) for fragment DummyFragment{b2d9f8c8 #0 id=0x7f05003d}
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:939)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:486)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.View.measure(View.java:16497)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.Choreographer.doCallbacks(Choreographer.java:574)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.Choreographer.doFrame(Choreographer.java:544)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.os.Handler.handleCallback(Handler.java:733)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.os.Handler.dispatchMessage(Handler.java:95)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.os.Looper.loop(Looper.java:136)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at android.app.ActivityThread.main(ActivityThread.java:5017)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at java.lang.reflect.Method.invokeNative(Native Method)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at java.lang.reflect.Method.invoke(Method.java:515)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-06 19:43:38.487: E/AndroidRuntime(1167):  at dalvik.system.NativeStart.main(Native Method

我在 Google 中发现了一个博客 post,它说 viewpager 在 Dialog 上不起作用。 它还说我们应该改用 DialogFragment。

这是该博客的link:http://www.intellicode.in/viewpager-inside-dialog/

当您使用 v4 支持库时,

getChildFragmentManager() 自 API 17 起可用。尝试改用支持片段管理器:

PagerDialog dialog = new PagerDialog(getActivity(),
        getActivity().getSupportFragmentManager());

到目前为止,我们无法弄清楚为什么会出现错误,但我有办法解决这个问题,使用这个技巧:

提示:如果您想要自定义对话框,您可以将 Activity 显示为对话框而不是使用对话框 API。只需创建一个 activity 并在清单元素中将其主题设置为 Theme.Holo.Dialog:

<activity android:theme="@android:style/Theme.Holo.Dialog"

基于这个提示,我没有让 PagerDialog 扩展 Dialog,而是从 Fragment 扩展。然后把这个Fragment放到一个Activity里面,把这个activity的主题设置成上面的AndroidManifest.xml。

PagerDialog更新后的代码如下

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PagerDialog extends Fragment {

ViewPager mViewPager;
FragmentStatePagerAdapter mAdapter;

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.id.dialog, container, false);
    mViewPager = (ViewPager) v.findViewById(R.id.pager);
    mAdapter = new MyAdapter(getFragmentManager());
    mViewPager.setAdapter(mAdapter);
    return v;
}

private class MyAdapter extends FragmentStatePagerAdapter {

    public MyAdapter(FragmentManager fm) {
        super(fm);

    }

    @Override
    public Fragment getItem(int index) {
        return new DummyFragment();
    }

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

}

private class DummyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_dummy_layout,
                container, false);
        return v;
    }
}
}

如果你有更好的解决方案或者你能找出我问题中的原代码为什么不起作用,请教我。我是 Android 编程的新手,很高兴向大家学习。

干杯。

The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses:

AlertDialogA dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout. And also DatePickerDialog or TimePickerDialog.

These classes define the style and structure for your dialog, but you should use a DialogFragment as a container for your dialog. The DialogFragment class provides all the controls you need to create your dialog and manage its appearance, instead of calling methods on the Dialog object.

更多详情请查看Dialog Design

错误听起来像是在 xml 文件中寻找 DummyFragment (fragment_dummy_layout.xml) 的 id 寻呼机。我想知道这是否是因为在与 setContentView(R.layout.dialog); 相同的文件中调用 View v = inflater.inflate(R.layout.fragment_dummy_layout, container, false);。您是否尝试过将 DummyFragment 分离到它自己的文件中?

你也可以试试

View v = getActivity().getLayoutInflater().inflate(R.layout.fragment_dummy_layout, 
        container, false);

尝试使用 DialogFragment 并将 getChildFragmentManager() 传递给您的 FragmentPagerAdapter 的 构造函数。

对话框片段:

public static class MyDialogFragment extends DialogFragment {

    private ViewPager viewPager;
    MySectionPagerAdapter mAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.m_layout, container);

        viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        mAdapter = new MySectionPagerAdapter(getChildFragmentManager());
        viewPager.setAdapter(mAdapter);

        return view;
    }


}

我找到了问题的解决方案并修改了您的 classes 以便不再出现此错误。

唯一的主要区别是您应该使用 DialogFragment 而不是 Dialog,这样您就可以调用 getChildFragmentManager() 并接收正确的 FragmentManager来自 DialogFragment

即使您之前使用了 getChildFragmentManager(),它也来自 MyFragment,并且 PagerDialog class 不是 MyFragment 中的子片段。

我已经测试了下面的代码,现在应该可以正常工作了。

MyFragment

public class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_sandbox, container, false);
        Button button = (Button) v.findViewById(R.id.button);

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                DialogFragment newFragment = PagerDialog.newInstance();
                newFragment.show(getChildFragmentManager(), "dialog");
            }

        });

        return v;
    }
}

PagerDialog

public class PagerDialog extends DialogFragment {

    public static PagerDialog newInstance() {
        return new PagerDialog();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.dialog_fragment, container, false);

        ViewPager mViewPager = (ViewPager) v.findViewById(R.id.view_pager);

        /* Use childFragmentManager here provided from the PagerDialog */
        MyAdapter mAdapter = new MyAdapter(getChildFragmentManager());
        mViewPager.setAdapter(mAdapter);

        return v;
    }

    private class MyAdapter extends FragmentStatePagerAdapter {

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

        @Override
        public Fragment getItem(int index) {
            return new DummyFragment();
        }

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

    }
}

DummyFragment

public class DummyFragment extends Fragment {

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

        View v = inflater.inflate(R.layout.fragment_dummy_layout, container, false);
        return v;
    }

}

fragment_sandbox.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test Fragment Dialog Pager"
        android:textSize="24sp"
        android:padding="20dp" />

</LinearLayout>

dialog_fragment.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:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment Dialog Title Text "
        android:padding="10dp"
        android:textColor="#333"
        android:textSize="24sp"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

</LinearLayout>

fragment_dummy_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment Dummy Text"
        android:textSize="24sp"
        android:textColor="#ff0000"/>

</LinearLayout>

我想你用过

Dialog dialog = new Dialog(context);

表示这个。

第一步:使用DialogFragment

public class MyCustomDialog extends DialogFragment {
    Button mButton;
    EditText mEditText;


    List<MasterPageModel> listdata;
    int position;
    ViewPager viewpager;

    public MyCustomDialog(List<MasterPageModel> listdata, int position) {
        this.listdata = listdata;
        this.position = position;
    }




    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View dialog = inflater.inflate(R.layout.dailoglayout, container);

        final Dialog dailog = getDialog();
        dailog.getWindow().setLayout(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        dailog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        dailog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        ImageView closebtn = (ImageView) dialog.findViewById(R.id.closeimgeview);
        closebtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dailog.dismiss();
            }
        });

        viewpager = (ViewPager) dialog.findViewById(R.id.dailog_viewpager);

        **viewpager.setAdapter(new PagerAdapter(getChildFragmentManager(), listdata));** //This Line is Very important
        viewpager.setCurrentItem(position);

        return dialog;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen); //For Full Screen of DailogBox
    }

}

第二步:设置 FragmentViewPager

public class PagerAdapter extends FragmentPagerAdapter   {

    private final List<MasterPageModel> pages;

    public PagerAdapter(FragmentManager fm, List<MasterPageModel> pages) {
        super(fm);
        this.pages = pages;
    }



    @Override
    public Fragment getItem(int position) {
        return new ViewPagerFragment(pages.get(position));
    }

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

第 3 步:ViewPager 的片段视图

public class ViewPagerFragment extends Fragment {

    MasterPageModel masteDetailModel;


    public ViewPagerFragment(MasterPageModel questionItem) {
        this.masteDetailModel = questionItem;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.pagerlayout, container, false);

        ImageView image = (ImageView) v.findViewById(R.id.pager_imageview);
        Log.i("Image", "=>" + masteDetailModel.imagelarge);
        Picasso.with(getActivity()).load(masteDetailModel.imagethumb).error(R.drawable.img).into(image);

        return v;
    }

第 4 如何使用此 dialogfragment

 MyCustomDialog fragment1 = new MyCustomDialog(listdata, position);
                EditionDetailActivity act = (EditionDetailActivity) context;
                FragmentManager fm = act.getSupportFragmentManager();
                fragment1.show(fm, "");