问题
I am trying to create an alertDialog
with a pageView
inside with a cancel and ok button.
The problem is when I set the adapter in the method onCreateDialog
, I got:
"java.lang.IllegalStateException : Fragment does not have a view".
If I comment out this line, I don't have an exception.
I have tried also by override the method onCreateView()
in the class MyDialog
, the problem is the same.
Someone have an idea?
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>
Edit : Track list error
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:
I haven't tried this, but based on the error my guess would be that you are trying to configure your pager adapter too soon. Since your code is in onCreateDialog, you haven't yet told Android about the view that will go into your dialog, and maybe it needs your view hierarchy to be in place before you work with the child fragment manager.
Try moving all the code having to do with the view pager and tab host into 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);
}
EDIT: Hmmm. Maybe the issue is that you need to let the fragments get built earlier in the life cycle, and then call setAdapter later. Try moving all the code except the actual call to setAdapter back where you had it in onCreateDialog, including saving the FragmentAdapter in a field, and then JUST call setAdapter in your onResume:
@Override
public void onResume() {
super.onResume();
viewPager.setAdapter(fragmentAdapter);
}
来源:https://stackoverflow.com/questions/27041764/android-viewpager-inside-dialogfragment-fragment-does-not-have-a-view