【发布时间】:2016-03-09 14:53:45
【问题描述】:
我想要一个有几页的dialogFragment,以便为我的应用程序输入一些设置。当我使用AlertDialog.Builder 时,我得到一个IllegalStateException 说“片段没有视图”,这让我感到困惑(而且堆栈也毫无用处)。
我可以使用其中的ViewPager 弹出一个弹出窗口,完全按照我的意愿进行操作,但它没有我想要的按钮。我真的很喜欢默认AlertDialog 的外观,所以如果可能的话,我最好使用它(出于一致性原因)。如果没有,我可以制作一个看起来完全相同的自定义对话框。
那么,我怎样才能让ViewPager 在AlertDialog / dialogFragment(或类似的)中工作?
编辑: 澄清一下,它不一定是AlertDialog,但我想要设置标题、(永久)消息和按钮的选项。
EDIT2: 所以在FragmentFirst newInstance() 中返回f 时出现“片段没有视图”错误。这应该将片段返回到adapter 中的getItem() 方法,该方法应该返回与正确位置关联的片段。我希望这可以帮助任何人查明问题所在。
EDIT3: 在搞砸了一些东西后,我现在得到了这个错误:No view found for id 0x7f0c00b7 (com.example.tim.timapp:id/pager) for fragment FragmentDefault{47febfa #1 id=0x7f0c00b7 android:switcher:2131493047:0},基本上是在告诉我一些事情是试图在错误的片段中找到寻呼机视图?不太确定如何解决。注意。 FragmentDefault 和FragmentFirst 完全一样,除了它的名字和一些id。
EDIT4:(2016 年 3 月 11 日)一个问题:当使用 newInstance 方法时(就像我在片段中所做的那样),返回的片段是否应该有视图?当我调用if (f.getView() == null) 时,它返回true,这让我想知道f 是否应该有一个视图。如果是这样,为什么不呢?我在网上看到的每个newInstance 方法的布局都与我的完全相同,所以看起来我并没有遗漏什么。
此外,由于某种原因,片段(FragmentFirst、FragmentSecond 等)中的onCreateView 永远无法到达。我在onCreateView 之后有一个Log.d,它永远不会显示在logcat 中。有什么想法吗?
代码:
调用 dialogFragment
TestActivityFragment newFragment = new TestActivityFragment();
newFragment.show(getChildFragmentManager(), "dialog");
TestActivityFragment:
package com.example.fragments.MainFragments.Test;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.tim.timapp.R;
public class TestActivityFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view = inflater.inflate(R.layout.test_dialog, null);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view)
.setPositiveButton("POS", null)
.setNegativeButton("NEG", null)
.setTitle("TEST_TITLE")
.setMessage("TEST_MESSAGE");
ViewPager mPager = (ViewPager) view.findViewById(R.id.pager);
FragmentStatePagerAdapter mPagerAdapter = new TestAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);
return builder.create();
}
private class TestAdapter extends FragmentStatePagerAdapter {
public TestAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch(position) {
case 0: return FragmentFirst.newInstance("FragmentFirst, Instance 1");
case 1: return FragmentSecond.newInstance("SecondFragment, Instance 1");
case 2: return FragmentThird.newInstance("ThirdFragment, Instance 1");
case 3: return FragmentThird.newInstance("ThirdFragment, Instance 2");
default: return FragmentDefault.newInstance("DefaultFragment");
}
}
@Override
public int getCount() {
return 5;
}
}
}
其中一个片段
package com.example.fragments.MainFragments.Test;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.tim.timapp.R;
public class FragmentFirst extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_first, container, false);
TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(getArguments().getString("msg"));
return v;
}
public static FragmentFirst newInstance(String text) {
FragmentFirst f = new FragmentFirst();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}
XML 的
test_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.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
(我也有 viewPager 作为父布局,里面没有任何东西,没有改变任何东西)
frag_first.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvFragFirst"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:text="TextView"
android:textAppearance="?android:textAppearanceMedium"/>
</RelativeLayout>
日志
03-09 15:30:55.910 23343-23343/? I/art: Not late-enabling -Xcheck:jni (already on)
03-09 15:30:55.940 23343-23349/? E/art: Failed sending reply to debugger: Broken pipe
03-09 15:30:55.940 23343-23349/? I/art: Debugger is no longer active
03-09 15:30:55.950 23343-23343/? W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-2/lib/x86_64
03-09 15:30:56.060 23343-23356/? D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
03-09 15:30:56.150 23343-23356/? I/OpenGLRenderer: Initialized EGL, version 1.4
03-09 15:30:56.210 23343-23356/? W/EGL_emulation: eglSurfaceAttrib not implemented
03-09 15:30:56.210 23343-23356/? W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f5f5597db40, error=EGL_SUCCESS
03-09 15:30:58.870 23343-23343/com.example.tim.timapp D/GSF - getChildCount: 0
03-09 15:30:58.910 23343-23343/com.example.tim.timapp D/AndroidRuntime: Shutting down VM
03-09 15:30:58.910 23343-23343/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tim.timapp, PID: 23343
java.lang.IllegalStateException: Fragment does not have a view
at android.app.Fragment$1.onFindViewById(Fragment.java:2181)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:963)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.BackStackRecord.run(BackStackRecord.java:793)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:562)
at android.support.v13.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1177)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1545)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1112)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:632)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
at android.view.View.measure(View.java:18788)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1191)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-09 15:35:59.030 23343-23343/? I/Process: Sending signal. PID: 23343 SIG: 9
附言。如果我忘记添加一段代码,请告诉我,以便我添加。
【问题讨论】:
-
stacktrace 不是没用的,它告诉你缺少一个视图。那是因为您没有在 DialogFragment 中实现 onCreateView()。见这里android-developers.blogspot.de/2012/05/…
-
我已经完成了一些(随机)测试,将 onCreateView() 方法添加到 dialogFragment。由于视图在 onCreateDialog() 方法中被夸大了,我认为它是可消耗的。晚饭后我会更深入地查看您的链接。
-
刚刚使用 onCreateView() 进行了测试。我应该如何准确地使用它?无论什么顺序,onCreateDialog() 都会在 onCreateView 之前被调用,如果您在 onCreateView 中设置视图,则会导致视图出现 NPE,除此之外,我不知道我需要 onCreateView() 来做什么。
-
是的,我想我有点草率了。我自己测试了一下,当使用 onCreateDialog 时,我无法让它与 viewPager 一起工作,如果你使用像 textView 这样的普通视图,它可以工作,但这对你的情况没有帮助。使用 onCreateView 时,viewPager 可以工作,但是您会丢失所有对话框属性,例如按钮。 Frak 碎片。
标签: java android android-fragments android-viewpager