Java – how to get (or simulate) the viewpager in dialogfragment?

When I use alertdialog. Builder, I receive an IllegalStateException that says "the fragment has no view", which puzzles me (and the stack is useless)

I can pop up a pop-up window using viewpager, which can perform the actions I want, but it doesn't have the buttons I want. I really like the appearance of the default alertdialog, so I'd better use it if possible (for consistency reasons). If not, I can make a custom dialog that looks exactly the same

So how do I make viewpager work in alertdialog / dialogfragment (or similar)?

Edit: just to clarify, it doesn't have to be alertdialog, but I want to choose the option of setting title, (permanent) message and button

Edit2: therefore, when f is returned in fragmentfirst newinstance(), a "fragment has no view" error occurs. This should return the fragment to the getitem() method in the adapter, which should return the fragment associated with the correct location. I hope this can help anyone find out what the problem is

Edit3: after messing up some things, I now get this error: fragment is not found. Fragment default {47febfa#1 id = 0x7f0c00b7 Android: switcher: 2131493047 ID 0x7f0c00b7 (COM. Example. Tim. Timapp: ID / pager) view: 0}, basically telling me something to try to find pager view in the wrong fragment? Not sure how to solve this problem. Note that fragmentdefault is exactly the same as fragmentfirst except for its name and some IDs

Edit4: (March 11, 2016) a question: when using the newinstance method (such as the operation I did inside the fragment), should the returned fragment have a view? When I call if (f.getview() = = null), it returns true, which makes me wonder if F should even have a view. If so, why not? The layout of each newinstance method I see on the Internet is exactly the same as my layout, so it looks as if I haven't lost anything. In addition, for some reason, oncreateview in fragments (fragmentfirst, fragmentsecond, etc.) will never arrive. I have a log. D after oncreateview, which has never been displayed in logcat. Do you have any ideas?

Code: call 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;
        }
    }
}

One of the fragments

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>

(I have also made viewpager as the parent layout, and there is nothing in it and nothing has changed.)

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>

Logging

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

PS. if I forget to add a piece of code, please let me know so that I can add it

resolvent:

So I finally managed to get what I wanted. However, some things have changed

In addition to replacing return builder. Create(); In addition, the oncreatedialog() method remains unchanged. Use return builder. Show(); And some appearance changes

The correct (cough) name is testadapter now pageradapter, not fragmentstatepageradapter. It may not be beautiful, but it works

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

Fragments (the fragments mentioned as one of the fragments in the original post have disappeared. They are no longer needed

test_ The dialog.xml file has also been changed. Now it contains a custom viewpager (and some page indicators, but this is not part of what bothers me)

<?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>

To continue, the custompager is as follows:

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

It may look daunting, but it doesn't do much after adjusting the viewpager to the size of the current display page. It doesn't look beautiful in all types of animation, and it's slow, but it can be done every time

Finally, frag_ First. XML. These can be any layout XML you want, as long as it fits alertdialog. XML

Just to (prove) that it's working. This is a picture. If you need more information, please feel free to ask. I've been struggling for a long time, so I'm glad to help you

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>