Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在DialogFragment中获取(或模拟)ViewPager?_Java_Android_Android Fragments_Android Viewpager - Fatal编程技术网

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

Java 如何在DialogFragment中获取(或模拟)ViewPager?,java,android,android-fragments,android-viewpager,Java,Android,Android Fragments,Android Viewpager,我想要一个带有几页的对话框片段,为我的应用程序输入一些设置。当我使用AlertDialog.Builder时,我得到一个IllegalStateException说“Fragment没有视图”,这让我很困惑(堆栈也很无用) 我可以在其中使用ViewPager弹出窗口,做我想让它做的事情,但它没有我想要的按钮。我非常喜欢默认的AlertDialog的外观,因此如果可能的话,我最好使用它(出于一致性的原因)。如果没有,我可以制作一个看起来完全一样的自定义对话框 那么,如何让ViewPager在Ale

我想要一个带有几页的
对话框片段
,为我的应用程序输入一些设置。当我使用
AlertDialog.Builder
时,我得到一个
IllegalStateException
说“Fragment没有视图”,这让我很困惑(堆栈也很无用)

我可以在其中使用
ViewPager
弹出窗口,做我想让它做的事情,但它没有我想要的按钮。我非常喜欢默认的
AlertDialog
的外观,因此如果可能的话,我最好使用它(出于一致性的原因)。如果没有,我可以制作一个看起来完全一样的自定义对话框

那么,如何让
ViewPager
AlertDialog/dialogFragment
(或类似)中工作

编辑:只是为了澄清一下,它不一定是一个
警报对话框
,但我想选择设置标题、(永久性)消息和按钮的选项

EDIT2:因此在
FragmentFirst newInstance()
中返回
f
时出现“片段没有视图”错误。这将向
适配器中的
getItem()
方法返回一个片段,该方法将返回与正确位置关联的片段。我希望这有助于任何人找出问题所在

EDIT3:在搞乱了一些东西之后,我现在得到了这个错误:
找不到id为0x7f0c00b7(com.example.tim.timapp:id/pager)的片段片段默认{47febfa#1 id=0x7f0c00b7 android:switcher:2131493047:0}
,基本上告诉我有什么东西试图在错误的片段中找到寻呼机视图?我不太清楚如何解决这个问题。注意
FragmentDefault
FragmentFirst
完全相同,只是它的名称和一些id不同

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

代码:
调用对话框片段

TestActivityFragment newFragment = new TestActivityFragment();  
newFragment.show(getChildFragmentManager(), "dialog");  
测试活动片段:

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的 测试对话框.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>
<?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>

注:如果我忘记添加一段代码,请告诉我,这样我就可以添加它。

我做了类似的操作,但在视图页面中添加了自定义视图

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

            <package.CustomViewOne
                android:id="@+id/custom_view_one"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <package.CustomViewTwo
                android:id="@+id/custom_view_two"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <package.CustomViewThree
                android:id="@+id/custom_view_three"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </android.support.v4.view.ViewPager>

所以,我终于得到了我想要的东西。但有些东西已经改变了


onCreateDialog()
方法没有改变,除了替换
returnbuilder.create()返回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);
            }
        }
    }
}

片段(那些在原始帖子中提到的
片段之一
已经消失了,不再需要它们了


test\u dialog.xml
文件也已更改。它现在包含一个自定义的viewpager(和一些页面指示器,但这不是困扰我的部分)

它可能看起来令人望而生畏,但除了将viewpager调整到其当前显示页面的大小之外,它没有做更多的事情。它不适合所有类型的动画,而且速度非常慢,但它每次都能完成这项工作


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


为了(证明)它起作用,这里有一张图片。
如果你需要更多的信息,尽管问吧。我已经为此挣扎了很长时间,所以我很乐意帮助你



(单击以获取更大的版本)

我对如何使用它感到有点困惑。我需要创建新视图吗?包在xml中如何工作?您必须用视图类所在的packagename替换包。是的,您需要创建自定义视图并在自定义视图中扩大布局。因此在您的示例中,包将是
我添加了一个自定义视图sampl因此,当您创建一个java类CustomViewOne.java时,在类的第一行您将看到包名。因此,取包名并在其旁边添加类名。如果我可以问(为了更好地理解发生了什么),为什么需要三个构造函数(我相信这就是它的名称)对于CustomViewOne?最后一个似乎与前两个做了相同的事情,并添加了一些内容。stacktrace不是无用的,它告诉您缺少一个视图。这是因为您没有在DialogFragment中实现onCreateView()。在这里,我已经对添加onCreateView()做了一些(随机)测试方法添加到dialogFragment。由于onCreateDialog()方法中的视图膨胀,我认为它是可消耗的。晚饭后我将更深入地查看您的链接。刚刚使用onCreateView()运行了一个测试。我应该如何准确地使用它?无论顺序如何,onCreateDialog()都可以在onCreateView之前被调用,如果在onCreateView中设置视图,则会导致该视图的NPE,而在其他视图中,我不知道需要onCreateView()做什么。是的,我想我有点仓促。我自己对其进行了一点测试,在使用onCreateDialog时无法使其与viewPager一起工作,如果
class SlidePagerAdapter extends PagerAdapter {

    private ViewPager viewPager;

    public SlidePagerAdapter(ViewPager viewPager) {
        this.viewPager = viewPager;
    }

    public View instantiateItem(ViewGroup collection, int position) {
        return viewPager.getChildAt(position);
    }

    @Override
    public int getCount() {
        return viewPager.getChildCount();
    }

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

    @Override
    public int getItemPosition(Object object) {

        for (int i = 0; i < getCount(); i++) {
            if (object == viewPager.getChildAt(i)) {
                return i;
            }
        }

        return POSITION_NONE;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        viewPager.removeView((View) object);
    }
}
public class CustomViewOne extends LinearLayout {

    public CustomViewOne(Context context) {
        super(context);
        initLayout();
    }

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

    public CustomViewOne(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initLayout();
    }

    public void initLayout() {
        LayoutInflater.from(getContext()).inflate(R.layout.custom_view_one_layout, this);
    }
}
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);
            }
        }
    }
}
<?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>
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();
    }
}