Есть ли метод, который работает как начать фрагмент для результата?


в настоящее время у меня есть фрагмент в наложении. Это для входа в сервис. В приложении для телефона каждый из шагов, которые я хочу показать в наложении, - это их собственные экраны и действия. Существует 3 части процесса входа, и каждая из них имела свою собственную активность, которая вызывалась с помощью startActivityForResult().

теперь я хочу сделать то же самое, используя фрагменты и наложение. Наложение покажет фрагмент, соответствующий каждому действию. Проблема в том, что эти фрагменты размещаются в действии в Honeycomb API. Я могу получить первый фрагмент работает, но тогда мне нужно startActivityForResult(), который не представляется возможным. Есть ли что-то вроде startFragmentForResult (), где я могу начать новый фрагмент, и когда это будет сделано, он вернет результат к предыдущему фрагменту?

7 65

7 ответов:

все фрагменты живут внутри деятельности. Запуск фрагмента для результата не имеет большого смысла, потому что деятельность, в которой он находится, всегда имеет к нему доступ, и наоборот. Если фрагмент должен передать результат, он может получить доступ к своей активности и установить свой результат и завершить его. В случае замены фрагментов в одном действии, хорошо, что действие по-прежнему доступно обоими фрагментами, и все ваши сообщения могут просто пройти через действие.

просто помните, что всегда есть связь между фрагментом и его деятельности. Начиная с результата и заканчивая результатом - это механизм связи между действиями-действия могут затем делегировать любую необходимую информацию своим фрагментам.

Если вы хотите, есть некоторые методы для связи между фрагментами,

setTargetFragment(Fragment fragment, int requestCode)
getTargetFragment()
getTargetRequestCode()

вы можете перезвонить с помощью этих.

Fragment invoker = getTargetFragment();
if(invoker != null) {
    invoker.callPublicMethod();
}

мои 2 цента.

я переключаюсь между фрагментами, меняя старый фрагмент на новый с помощью hide и show/add (existing / new). Так что этот ответ для разработчиков, которые используют фрагменты, как я делаю.

тогда я использую onHiddenChanged метод, чтобы знать, что старый фрагмент был переключен на обратно из нового. Смотрите код ниже.

перед выходом из нового фрагмента я задаю результат в глобальном параметре, который будет запрашиваться старым фрагментом. Это очень наивно решение.

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) return;
    Result result = Result.getAndReset();
    if (result == Result.Refresh) {
        refresh();
    }
}

public enum Result {
    Refresh;

    private static Result RESULT;

    public static void set(Result result) {
        if (RESULT == Refresh) {
            // Refresh already requested - no point in setting anything else;
            return;
        }
        RESULT = result;
    }

    public static Result getAndReset() {
        Result result = RESULT;
        RESULT = null;
        return result;
    }
}

в вашем фрагменте вы можете вызвать getActivity (). Это даст вам доступ к деятельности, которая создается фрагмент. Оттуда вы можете вызвать свой метод настройки, чтобы установить значения или передать значения.

есть библиотека Android - FlowR что позволяет запускать фрагменты для получения результатов.

запуск фрагмента для результата.

Flowr.open(RequestFragment.class)
    .displayFragmentForResults(getFragmentId(), REQUEST_CODE);

обработка результатов в вызывающем фрагменте.

@Override
protected void onFragmentResults(int requestCode, int resultCode, Bundle data) {
    super.onFragmentResults(requestCode, resultCode, data);

    if (requestCode == REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            demoTextView.setText("Result OK");
        } else {
            demoTextView.setText("Result CANCELED");
        }
    }
}

установка результата во фрагменте.

Flowr.closeWithResults(getResultsResponse(resultCode, resultData));

самый простой способ передать данные обратно-это setArgument (). Например, у вас есть fragment1, который вызывает fragment2, который вызывает fragment3, fragment1 - > framgnet2 - > fargment3

в fragment1

public void navigateToFragment2() {
    if (fragmentManager == null) return;

    Fragment2 fragment = Fragment2.newInstance();
    String tag = "Fragment 2 here";
    fragmentManager.beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .add(R.id.flContent, fragment, tag)
            .addToBackStack(null)
            .commitAllowingStateLoss();
}

в fragment2 мы называем fragment3 как обычно

private void navigateToFragment3() {
    if (fragmentManager == null) return;
    Fragment3 fragment = new Fragment3();
    fragmentManager.beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .replace(R.id.flContent, fragment, tag)
            .addToBackStack(null)
            .commit();
}

когда мы закончили нашу задачу в fragment3 теперь мы называем так:

FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
if (fragmentManager == null) return;
fragmentManager.popBackStack();
Bundle bundle = new Bundle();
bundle.putString("bundle_filter", "data");
fragmentManager.findFragmentByTag("Fragment 2 here").setArguments(bundle);

теперь в fragment2 мы можем легко вызвать аргументы

@Override
public void onResume() {
    super.onResume();
    Bundle rgs = getArguments();
    if (args != null) 
        String data = rgs.getString("bundle_filter");
}

можно использовать EventBus. Это упрощает связь между действиями, фрагментами, потоками, службами и т. д. Меньше кода, лучшее качество.