Как сохранить ссылку на объект через изменение конфигурации? - PullRequest
1 голос
/ 18 ноября 2011

Я создал фрагмент диалога текстового запроса для повторного использования. Но это не обрабатывать конфиг. изменения. После восстановления фрагмента mClickListener имеет значение null (как и ожидалось). Вопрос - как я могу сохранить обратный вызов? (Я новичок в Java и не знаю общих шаблонов / решений Java)

public class TextQueryDialogFragment extends DialogFragment {
private OnDialogListener mClickListener;
private EditText mTextWidget;

public void setClickListener(OnDialogListener listener) {
    mClickListener = listener;
}

public String getQueryText() {
    return mTextWidget.getText().toString();
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View queryView = factory.inflate(R.layout.query_dialog_text, null);
    mTextWidget = (EditText) queryView.findViewById(R.id.query_dialog_text);

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
    .setView(queryView)
    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            if(null != mClickListener)
                mClickListener.OnPositiveClick();
            dialog.dismiss();
        }
    })
    .setNegativeButton(android.R.string.cancel, 
                                           new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            if(null != mClickListener)
                mClickListener.OnNegativeClick();
            dialog.cancel();
        }
    });

    return builder.create();
}
}

Использование:

TextQueryDialogFragment dialog = new TextQueryDialogFragment();
dialog.setQueryText(mBookmarkTitle);
dialog.setClickListener(new OnDialogListener() {
        @Override
        public void OnPositiveClick() {
            String title = dialog.getQueryText();
            //do work here
        }

        @Override
        public void OnNegativeClick() {}
    });
dialog.show(getFragmentManager(), "MYTAG");

Serializable не будет работать, и, следовательно, onSaveInstanceState - это не то, что мне нужно. Parcelable может сделать (с помощью aidl и IBinder), но это слишком много для такой простой задачи.

Пока я нашел два более или менее подходящих решения:

  • Хранить обратные вызовы в приложении и извлекать их по идентификатору / тегу взяты отсюда
  • обновление обратных вызовов при создании родительского фрагмента:

    TextQueryDialogFragment dialog = (TextQueryDialogFragment) . GetFragmentManager () findFragmentByTag (RENAME_TAG); if (null! = dialog) { dialog.setClickListener (getListener ()); }

Есть ли лучшие решения или эти два в порядке?

Ответы [ 3 ]

2 голосов
/ 29 ноября 2011

Решение простое и не имеет ничего общего с onRetainConfigurationInstance или другими методами, упомянутыми здесь. Просто найдите экземпляр TextQueryDialogFragment в FragmentManager при воссоздании родительского фрагмента и снова установите прослушиватель, если экземпляр все еще там.

Добавьте следующий код к методу onCreateView родителя:

TextQueryDialogFragment retFragment = 
(TextQueryDialogFragment)getFragmentManager().findFragmentByTag("MYTAG");

if(retFragment != null)
{
    retFragment.setClickListener(new OnDialogListener() {
        @Override
        public void OnPositiveClick() {
            String title = dialog.getQueryText();
            //do work here
        }

        @Override
        public void OnNegativeClick() {}
    }
);
}

В этом случае я бы предпочел реализовать onClickListener вашим классом фрагмента, чтобы вы могли переписать его следующим образом:

TextQueryDialogFragment retFragment = 
(TextQueryDialogFragment )getFragmentManager().findFragmentByTag("MYTAG");

if(retFragment != null)
{
    retFragment.setClickListener(this);
}
0 голосов
/ 29 октября 2013

У меня была похожая проблема, и ответ от vitakot был решением!Но мой случай был немного более сложным: у меня есть фрагмент MyAttributeFragment, который использует DialogFragment для ввода текста.Этот MyAttributeFragment используется более одного раза в одной и той же операции, поэтому статический тег типа «MYTAG» для DialogFragment не является уникальным.Я решил эту проблему, взяв идентификатор MyAttributeFragment для определения фрагмента-владельца.

//Create DialogFragment with the unique ID of the owning fragment 
newFragment.show(getFragmentManager(), String.valueOf(this.getId()));
0 голосов
/ 18 ноября 2011

Я думаю, что вы ищете onRetainConfigurationInstance, вы можете вернуть любой объект, который вы хотите.

public Object onRetainNonConfigurationInstance() { ... }

Тогда вы можете получить его в onCreate():

if (getLastNonConfigurationInstance() != null) {
  instance = (Type) getLastNonConfigurationInstance();
}

Однако я не уверен, почему вам нужно сохранить OnClickListener.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...