gpt4 book ai didi

java - 如何在 DialogFragment 中获取(或模拟)ViewPager?

转载 作者:太空宇宙 更新时间:2023-11-03 13:50:16 24 4
gpt4 key购买 nike

我想要一个包含几页的 dialogFragment 来为我的应用输入一些设置。当我使用 AlertDialog.Builder 时,我得到一个 IllegalStateException 说“Fragment 没有 View ”,这让我很困惑(堆栈也很无用)。

我可以获得一个与其中的 ViewPager 一起工作的弹出窗口,完全按照我想要的方式执行,但它没有我想要的按钮。我真的很喜欢默认 AlertDialog 的外观,所以我最好尽可能使用它(出于一致性原因)。如果不是,我可以制作一个看起来完全一样的自定义对话框。

那么,如何让 ViewPagerAlertDialog/dialogFragment(或类似的)中工作?

编辑: 澄清一下,它不一定是AlertDialog,但我想要设置标题的选项(永久)消息和按钮。

EDIT2: 所以在 FragmentFirst newInstance()。这应该向 adapter 中的 getItem() 方法返回一个 fragment ,它应该返回与正确位置关联的 fragment 。我希望这可以帮助任何人查明问题所在。

EDIT3: 在弄乱了一些东西后,我现在得到了这个错误:No view found for id 0x7f0c00b7 (com.example.tim.timapp:id/pager)对于 fragment FragmentDefault{47febfa #1 id=0x7f0c00b7 android:switcher:2131493047:0},基本上是在告诉我有什么东西试图在错误的 fragment 中找到寻呼机 View ?不太清楚如何解决这个问题。注意。 FragmentDefaultFragmentFirst 完全相同,除了它的名称和一些 id。

EDIT4:(2016 年 3 月 11 日)一个问题:当使用 newInstance 方法时(就像我在 fragment 中所做的那样),返回的 fragment 是否应该具有一个看法?当我调用 if (f.getView() == null) 时,它返回 true,这让我想知道 f 是否应该有一个 View 。如果是这样,为什么不呢?我在网上看到的每个 newInstance 方法都与我的布局完全相同,所以看起来我没有遗漏什么。
此外,由于某些原因, fragment (FragmentFirst、FragmentSecond 等)中的 onCreateView 从未达到。我在 onCreateView 之后有一个 Log.d,它从不显示在 logcat 中。有什么想法吗?

代码:
调用dialogFragment

TestActivityFragment newFragment = new TestActivityFragment();  
newFragment.show(getChildFragmentManager(), "dialog");

测试 Activity fragment :

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;
}
}
}

其中一个 fragment

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

附言。如果我忘记添加一段代码,请告诉我,以便我添加。

最佳答案

所以,我终于设法得到了我想要的东西。不过,有些东西已经发生了变化。


onCreateDialog() 方法没有改变,只是将 return builder.create(); 替换为 return builder.show();,以及一些外观上的变化。


正确(咳咳)命名的 TestAdapter 现在是 PagerAdapter 而不是 FragmentStatePagerAdapter。它可能不漂亮,但它确实有效。

private class TestAdapter extends PagerAdapter {

private int mCurrentPosition = -1;

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

@Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = getActivity().getLayoutInflater();
int layoutThingy;

switch(position) {
case 0:
layoutThingy = R.layout.fragment_generalsettingsinputdialog1;
break;
case 1:
layoutThingy = R.layout.fragment_generalsettingsinputdialog2;
break;
case 2:
layoutThingy = R.layout.fragment_generalsettingsinputdialog3;
break;
default:
layoutThingy = R.layout.fragment_viewpagererror;
}

View view = inflater.inflate(layoutThingy, null);
container.addView(view);
view.requestFocus();
return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
View view = (View) object;
CustomPager pager = (CustomPager) container;
if (view != null) {
mCurrentPosition = position;
pager.measureCurrentView(view);
}
}
}
}

fragment (那些在原始帖子中提到的 One of the fragments 已经消失了。不再需要它们了。


test_dialog.xml 文件也发生了变化。它现在包含一个自定义 viewpager(和一些页面指示器,但这不是困扰我的部分)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">

<com.example.tim.timapp.CustomStuff.CustomPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>

<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/circlePageIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fillColor="@color/colorPrimary"
app:strokeColor="@color/lightGrey"/>

</LinearLayout>

继续,CustomPager 如下所示:

package com.example.tim.timapp.CustomStuff;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;

public class CustomPager extends ViewPager {

private View mCurrentView;

public CustomPager(Context context) {
super(context);
}

public CustomPager(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}

int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public void measureCurrentView(View currentView) {
mCurrentView = currentView;
requestLayout();
}

public int measureFragment(View view) {
if (view == null)
return 0;

view.measure(0, 0);
return view.getMeasuredHeight();
}
}

它可能看起来令人生畏,但它并没有比将 viewpager 的大小调整到其当前显示页面的大小更多。它在各种动画中看起来并不漂亮,而且速度很慢,但它每次都能完成这项工作。


最后是 frag_first.xml XML。这些可以是您想要的任何类型的布局 XML,只要它适合 AlertDialog。


只是为了(证明)显示它正在工作,这是一张图片。
如果您需要更多信息,请随时询问。我已经为此苦苦挣扎了很长时间,所以我很乐意提供帮助。


(点击查看大图)

关于java - 如何在 DialogFragment 中获取(或模拟)ViewPager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35894949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com