问题
I would like to use a ViewPager in a dialog but fail epicly! Here is all the code. There is two fragments to be shown in the dialog:
Layouts
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>
details.xml (Fragment layout)
<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>
image.xml (Fragment layout)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher" />
</LinearLayout>
dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip" />
</LinearLayout>
Main.java
public class Main extends FragmentActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupUIComponents();
setupListeners();
}
private void setupUIComponents() {
button = (Button) findViewById(R.id.button);
}
private void setupListeners() {
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MyDialog dialog = new MyDialog(Main.this);
dialog.startDialog();
}
});
}
}
MyDialog.java
public class MyDialog extends FragmentActivity {
private Dialog dialog;
private Context context;
private CirclePageIndicator mIndicator;
private Main mMain;
private ViewPager mPager;
private FragmentAdapter mAdapter;
public MyDialog(Context context) {
super();
this.context = context;
this.mMain = (Main) context;
}
public void startDialog() {
dialog = new Dialog(context);
dialog.setContentView(R.layout.dialog);
mAdapter = new FragmentAdapter(mMain.getSupportFragmentManager());
mPager = (ViewPager) dialog.findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (CirclePageIndicator) dialog.findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
mIndicator.setCurrentItem(0);
dialog.show();
}
}
FragmentAdapter.java
public class FragmentAdapter extends FragmentPagerAdapter {
public FragmentAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int which) {
switch (which) {
case 0:
ImageFragment imageFragment = new ImageFragment();
return imageFragment;
case 1:
DetailFragment detailsFragment = new DetailFragment();
return detailsFragment;
}
return null;
}
@Override
public int getCount() {
return 2;
}
}
DetailsFragment.java
public class DetailFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@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("Testing");
return view;
}
}
ImageFragment.java
public class ImageFragment extends Fragment {
public ImageFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@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.image, container, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView1);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
return view;
}
}
To sum the code up quickly, Main.java is started, clicking on the button shall fire up a dialog with two fragments in a view pager.
There is the stacktrace:
12-11 11:28:15.999: E/AndroidRuntime(7453): FATAL EXCEPTION: main
12-11 11:28:15.999: E/AndroidRuntime(7453): java.lang.IllegalArgumentException: No view found for id 0x7f040006 for fragment ImageFragment{410a2468 #0 id=0x7f040006 android:switcher:2130968582:0}
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:864)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.view.ViewPager.populate(ViewPager.java:804)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1016)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-11 11:28:15.999: E/AndroidRuntime(7453): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.View.measure(View.java:15172)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1077)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.Choreographer.doFrame(Choreographer.java:525)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.os.Handler.handleCallback(Handler.java:615)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.os.Handler.dispatchMessage(Handler.java:92)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.os.Looper.loop(Looper.java:137)
12-11 11:28:15.999: E/AndroidRuntime(7453): at android.app.ActivityThread.main(ActivityThread.java:4966)
12-11 11:28:15.999: E/AndroidRuntime(7453): at java.lang.reflect.Method.invokeNative(Native Method)
12-11 11:28:15.999: E/AndroidRuntime(7453): at java.lang.reflect.Method.invoke(Method.java:511)
12-11 11:28:15.999: E/AndroidRuntime(7453): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
12-11 11:28:15.999: E/AndroidRuntime(7453): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
12-11 11:28:15.999: E/AndroidRuntime(7453): at dalvik.system.NativeStart.main(Native Method)
Again, is it possible to show fragments in a viewpager in a dialog? And if so, where abouts did I go wrong?
回答1:
Again, is it possible to show fragments in a viewpager in a dialog?
Yes, but not the way you tried(if I'm not missing something in your code), the ViewPager
will not be able to attach those child Fragments
as it's placed in the dialog. The 4.2
API level brought nested Fragments(but also available on lower versions with the new versions of the compatibility package) which you should use to show your "in dialog fragments".
In your Main
activity you would create a DialogFragment
and in that DialogFragment
you would setup the ViewPager
and pass getChildFragmentManager()
to its adapter.
Also, just use move the startDialog()
method in the Main
activity and don't instantiate a new Activity
as that is not the way Android goes(in your case it works because you're not doing anything with it).
来源:https://stackoverflow.com/questions/13819516/viewpager-in-simple-dialog