如何在DialogFragment中的Dialog中替换Fragment?

时间:2016-02-13 15:50:09

标签: android android-layout android-fragments android-library

我正在尝试使用https://github.com/rockerhieu/emojicon库,以便像WhatsApp和Telegram那样在软键盘上生成EmojiKeyboard。

经过一番研究,我发现他们的做法是通过在软键盘上创建一个Dialog。该库是一个片段,需要在执行时替换布局的某些元素。替换发生在这个类中:

/**
 * Class responsible for managin user's interaction with the Emoji Keyboard
 */
public class EmojiKeyboardManager {

    public static final String TAG = "EmojiKeyboardManager";

    private AppCompatActivity mActivity;

    private FrameLayout mEmojiconContainer;
    private EmojiconEditText mEditEmojicon;
    private LinearLayout mEmojiconButton;
    private ImageView mEmojiconButtonImg;

    // CONSTRUCTOR
    public EmojiKeyboardManager(AppCompatActivity activity) {
        this.mActivity = activity;
        this.implementEmojiconButton();
        this.implementInputTextListener();
        //this.initEmojiconFragment(Boolean.FALSE);
    }

    // INITIALIZATIONS
    private void implementEmojiconButton() {
        this.mEmojiconButtonImg = (ImageView) this.mActivity.findViewById(R.id.emojiButton);
        this.mEmojiconButton = (LinearLayout) this.mActivity.findViewById(R.id.emojiButtonWrapper);
        EmojiKeyboardManager.this.mEmojiconButtonImg.setSelected(Boolean.FALSE);
        this.mEmojiconButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (EmojiKeyboardManager.this.mEmojiconButtonImg.isSelected()) {
                    EmojiKeyboardManager.this.hideEmojiconKeyboard(Boolean.TRUE);
                } else {
                    EmojiKeyboardManager.this.showEmojiconKeyboard();
                }
            }
        });
    }

    public void showEmojiconKeyboard() {
        LayoutUtil.dismissSoftKeyboard(this.mEditEmojicon);
        EmojiKeyboardManager.this.mEmojiconButtonImg.setImageResource(R.drawable.ic_keyboard_black_36dp);

        DialogFragment newFragment = SampleDialogFragment.newInstance();
        newFragment.show(this.mActivity.getSupportFragmentManager(), "dialog");

        //this.mEmojiconContainer.setVisibility(FrameLayout.VISIBLE);
        EmojiKeyboardManager.this.mEmojiconButtonImg.setSelected(Boolean.TRUE);
    }

    public void hideEmojiconKeyboard(Boolean showSoftkeyboard) {
        EmojiKeyboardManager.this.mEmojiconButtonImg.setImageResource(R.drawable.input_emoji);
        LayoutUtil.dismissSoftKeyboard(EmojiKeyboardManager.this.mEditEmojicon);
        //this.mEmojiconContainer.setVisibility(FrameLayout.GONE);
        EmojiKeyboardManager.this.mEmojiconButtonImg.setSelected(Boolean.FALSE);
        if (showSoftkeyboard) {
            EmojiKeyboardManager.this.mEditEmojicon.requestFocus();
            LayoutUtil.showSoftKeyboard(EmojiKeyboardManager.this.mEditEmojicon);
        }
    }

    private void implementInputTextListener() {
        this.mEditEmojicon = (EmojiconEditText) this.mActivity.findViewById(R.id.message);
        this.mEditEmojicon.clearFocus();
    }

    // GETTERS AND SETTERS
    public EmojiconEditText getmEditEmojicon() {
        return this.mEditEmojicon;
    }

    public Boolean isEmojikeyboardAttached() {
        return EmojiKeyboardManager.this.mEmojiconButtonImg.isSelected();
    }

}

为了达到我的需要,我正在使用DialogFragment的子类来创建一个像这样的Dialog:

public class SampleDialogFragment extends DialogFragment {

    private Dialog dialog;

    static SampleDialogFragment newInstance() {
        SampleDialogFragment f = new SampleDialogFragment();
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        this.dialog = new Dialog(this.getActivity(), android.R.style.Theme_NoTitleBar);

        this.dialog.setContentView(R.layout.rsc_emoji_keyboard);
        this.dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        this.dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        this.dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        this.dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        WindowManager.LayoutParams lp = this.dialog.getWindow().getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = (int) App.context().getResources().getDimension(R.dimen.soft_keyboard_min_height);
        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
        lp.dimAmount = 0;

        return this.dialog;
    }
}

我会像那样显示对话:

DialogFragment newFragment = SampleDialogFragment.newInstance();
.show(this.mActivity.getSupportFragmentManager(), "dialog");

Dialog的布局如下:

<?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:gravity="center"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/emoji_keyboard"
        android:layout_width="match_parent"
        android:layout_height="@dimen/soft_keyboard_min_height"/>
</LinearLayout>

FrameLayout应替换为Library Fragment。我在Parent Activity中创建了Dialog并尝试使用了替换Fragment代码,并且还覆盖了DialogFragment的show()方法,但我总是得到一个未找到视图的异常。如何用库片段替换framelayout?

编辑: 跟着它是堆栈跟踪

02-13 22:47:50.613 25553-25606/br.com.instachat.demo D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
02-13 22:47:50.725 25553-25606/br.com.instachat.demo I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: EGL 1.4 QUALCOMM build: Nondeterministic_AU_msm8974_LA.BF.1.1.3_RB1__release_AU (I3193f6e94a)
                                                                   OpenGL ES Shader Compiler Version: E031.28.00.02
                                                                   Build Date: 10/09/15 Fri
                                                                   Local Branch: mybranch15039904
                                                                   Remote Branch: quic/LA.BF.1.1.3_rb1.2
                                                                   Local Patches: NONE
                                                                   Reconstruct Branch: NOTHING
02-13 22:47:50.727 25553-25606/br.com.instachat.demo I/OpenGLRenderer: Initialized EGL, version 1.4
02-13 22:47:50.757 25553-25553/br.com.instachat.demo E/RecyclerView: No adapter attached; skipping layout
02-13 22:47:50.791 25553-25623/br.com.instachat.demo I/RegIntentService: br.com.instachat.demo:string/token_received_successfully
02-13 22:47:50.796 25553-25553/br.com.instachat.demo E/RecyclerView: No adapter attached; skipping layout
02-13 22:47:51.395 25553-25553/br.com.instachat.demo I/RegIntentService: br.com.instachat.demo:string/token_sent_to_app_server_successfully
02-13 22:47:51.410 25553-25553/br.com.instachat.demo I/FragmentContacts: br.com.instachat.demo:string/contact_sync_success
02-13 22:47:53.010 25553-25553/br.com.instachat.demo I/FragmentContacts: br.com.instachat.demo:string/get_chatroomid_success
02-13 22:47:53.011 25553-25553/br.com.instachat.demo I/FragmentContacts:  chatroom retrieved (via request) has title: Hall 9000
02-13 22:47:53.066 25553-25553/br.com.instachat.demo I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
02-13 22:47:53.440 25553-25606/br.com.instachat.demo D/OpenGLRenderer: endAllActiveAnimators on 0xb82bf2a0 (LinearLayout) with handle 0xb83b6700
02-13 22:47:53.952 25553-25553/br.com.instachat.demo E/FragmentManager: No view found for id 0x7f0d00e3 (br.com.instachat.demo:id/emoji_keyboard) for fragment EmojiconsFragment{d8f31ba #1 id=0x7f0d00e3}
02-13 22:47:53.952 25553-25553/br.com.instachat.demo E/FragmentManager: Activity state:
02-13 22:47:53.953 25553-25553/br.com.instachat.demo D/FragmentManager:   Local FragmentActivity a698ff2 State:
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:     mCreated=truemResumed=true mStopped=false mReallyStopped=false
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:     mLoadersStarted=true
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:   Active Fragments in 6fb086b:
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:     #0: SampleDialogFragment{3355fc8 #0 dialog}
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mFragmentId=#0 mContainerId=#0 mTag=dialog
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mState=5 mIndex=0 mWho=android:fragment:0 mBackStackNesting=0
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mRetainInstance=false mRetaining=false mUserVisibleHint=true
02-13 22:47:53.957 25553-25553/br.com.instachat.demo D/FragmentManager:       mFragmentManager=FragmentManager{6fb086b in HostCallbacks{d98e861}}
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mHost=android.support.v4.app.FragmentActivity$HostCallbacks@d98e861
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:     #1: EmojiconsFragment{d8f31ba #1 id=0x7f0d00e3}
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mFragmentId=#7f0d00e3 mContainerId=#7f0d00e3 mTag=null
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mState=0 mIndex=1 mWho=android:fragment:1 mBackStackNesting=0
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mAdded=true mRemoving=false mResumed=false mFromLayout=false mInLayout=false
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mRetainInstance=false mRetaining=false mUserVisibleHint=true
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mFragmentManager=FragmentManager{6fb086b in HostCallbacks{d98e861}}
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mHost=android.support.v4.app.FragmentActivity$HostCallbacks@d98e861
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:       mArguments=Bundle[{useSystemDefaults=false}]
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:   Added Fragments:
02-13 22:47:53.958 25553-25553/br.com.instachat.demo D/FragmentManager:     #0: SampleDialogFragment{3355fc8 #0 dialog}
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:     #1: EmojiconsFragment{d8f31ba #1 id=0x7f0d00e3}
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:   FragmentManager misc state:
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:     mHost=android.support.v4.app.FragmentActivity$HostCallbacks@d98e861
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:     mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@d98e861
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:     mCurState=5 mStateSaved=false mDestroyed=false
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:   View Hierarchy:
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:     com.android.internal.policy.PhoneWindow$DecorView{f889320 V.ED.... ... 0,0-1080,1920}
02-13 22:47:53.959 25553-25553/br.com.instachat.demo D/FragmentManager:       android.widget.LinearLayout{5a1ae9e V.E..... ... 0,0-1080,1776}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:         android.view.ViewStub{ceeaf86 G.E..... ... 0,0-0,0 #10203ab android:id/action_mode_bar_stub}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:         android.widget.FrameLayout{3b1ca13 V.E..... ... 0,72-1080,1776}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:           android.support.v7.widget.FitWindowsLinearLayout{bf70450 V.E..... ... 0,0-1080,1704 #7f0d0080 app:id/action_bar_root}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:             android.support.v7.widget.ViewStubCompat{2bfc047 G.E..... ... 0,0-0,0 #7f0d0081 app:id/action_mode_bar_stub}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:             android.support.v7.widget.ContentFrameLayout{15d6649 V.E..... ... 0,0-1080,1704 #1020002 android:id/content}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:               android.widget.RelativeLayout{f64fb4e V.E..... ... 0,0-1080,1704 #7f0d0094 app:id/activity_canvas}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:                 android.support.design.widget.AppBarLayout{ee4f46f V.E..... ... 0,0-1080,168 #7f0d0095 app:id/toolbar_wrapper}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:                   android.support.v7.widget.Toolbar{6d0157c V.E..... ... 0,0-1080,168 #7f0d0096 app:id/toolbar}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:                     android.widget.RelativeLayout{c997e5a V.E..... ... 168,0-528,168}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:                       com.mikhaellopez.circularimageview.CircularImageView{d196b08 V.ED.... ... 0,15-135,152 #7f0d0097 app:id/thumbnail}
02-13 22:47:53.962 25553-25553/br.com.instachat.demo D/FragmentManager:                       android.widget.LinearLayout{576688b V.E..... ... 150,27-360,141}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                         android.support.v7.widget.AppCompatTextView{dc70d68 V.ED.... ... 0,0-210,65 #7f0d0098 app:id/name}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                         android.support.v7.widget.AppCompatTextView{a469581 V.ED.... ... 0,65-99,114 #7f0d0099 app:id/status}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                     android.widget.ImageButton{70d1e05 VFED..C. ... 0,0-168,168}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                     android.support.v7.widget.ActionMenuView{48ca098 V.E..... ... 816,0-1080,168}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                       android.support.v7.view.menu.ActionMenuItemView{e995357 VFED..CL ... 0,12-144,156 #7f0d00f2 app:id/action_attach_media}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                       android.support.v7.widget.ActionMenuPresenter$OverflowMenuButton{41af862 VFED..C. ... 144,12-264,156}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                 android.support.v7.widget.RecyclerView{4612626 VFE..... F.. 0,168-1080,1506 #7f0d009a app:id/messages}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                 android.widget.LinearLayout{e610267 V.E..... ... 0,1506-1080,1704 #7f0d009b app:id/bottomLayoutWrapper}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                   android.widget.LinearLayout{b39814 V.E..... ... 24,24-1056,174}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                     android.widget.LinearLayout{84608bd V.E..... ... 0,0-882,150}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                       android.widget.LinearLayout{ba97eb2 V.E...C. ... 1,0-145,150 #7f0d00da app:id/emojiButtonWrapper}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                         android.support.v7.widget.AppCompatImageView{b715e03 V.ED.... .S. 36,39-108,111 #7f0d00db app:id/emojiButton}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                       com.rockerhieu.emojicon.EmojiconEditText{33c2180 VFED..CL ... 145,0-822,150 #7f0d00b7 app:id/message}
02-13 22:47:53.963 25553-25553/br.com.instachat.demo D/FragmentManager:                       android.widget.LinearLayout{bcf73b9 V.E..... ... 822,38-822,111}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/FragmentManager:                         android.widget.LinearLayout{624b074 VFE..... ... 0,0-0,0}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/FragmentManager:                         android.support.v7.widget.AppCompatAutoCompleteTextView{6acd3fe VFED..CL ... 0,0-0,73 #7f0d00ec app:id/autotext}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/FragmentManager:                     android.support.v7.widget.AppCompatImageButton{4a1d75f VFED..C. ... 882,0-1032,150 #7f0d00dc app:id/send}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/FragmentManager:       android.view.View{e881223 V.ED.... ... 0,1776-1080,1920 #1020030 android:id/navigationBarBackground}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/FragmentManager:       android.view.View{4ba94d9 V.ED.... ... 0,0-1080,72 #102002f android:id/statusBarBackground}
02-13 22:47:53.964 25553-25553/br.com.instachat.demo D/AndroidRuntime: Shutting down VM
02-13 22:47:53.968 25553-25553/br.com.instachat.demo E/AndroidRuntime: FATAL EXCEPTION: main
                                                                       Process: br.com.instachat.demo, PID: 25553
                                                                       java.lang.IllegalArgumentException: No view found for id 0x7f0d00e3 (br.com.instachat.demo:id/emoji_keyboard) for fragment EmojiconsFragment{d8f31ba #1 id=0x7f0d00e3}
                                                                           at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1059)
                                                                           at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
                                                                           at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                           at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
                                                                           at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                                                                           at android.os.Handler.handleCallback(Handler.java:746)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

解决

我可以使用以下代码管理问题:

public class SampleDialogFragment extends DialogFragment {

    static SampleDialogFragment newInstance() {
        SampleDialogFragment f = new SampleDialogFragment();
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_NoTitleBar);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.rsc_emoji_keyboard, container, false);

        this.getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        this.getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        this.getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        this.getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        WindowManager.LayoutParams lp = this.getDialog().getWindow().getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = (int) App.context().getResources().getDimension(R.dimen.soft_keyboard_min_height);
        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
        lp.dimAmount = 0;

        getChildFragmentManager()
                .beginTransaction()
                .replace(R.id.emoji_keyboard, EmojiconsFragment.newInstance(false))
                .commit();

        return v;
    }
}

0 个答案:

没有答案