Пользовательский вид, вызывающий startActivityForResult - PullRequest
12 голосов
/ 05 июля 2011

Я создал собственный составной вид, в котором я включаю функции для фотографирования.

Я называю это так (из вида):

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
((Activity)mContext).startActivityForResult(intent, index);

Эта часть работает хорошо.Чего я не знаю, как это сделать, так это как реализовать onActivityResult в моем настраиваемом представлении?

Или я должен поймать это в Activity и затем перенаправить в свое представление?Не похоже на очень хорошее решение ..

Ответы [ 5 ]

13 голосов
/ 14 марта 2014

Вы действительно можете сделать это так:

@Override
public void onClick(View v) {
    final FragmentManager fm = ((FragmentActivity) getContext()).getSupportFragmentManager();
    Fragment auxiliary = new Fragment() {
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            //DO WHATEVER YOU NEED
            super.onActivityResult(requestCode, resultCode, data);
            fm.beginTransaction().remove(this).commit();
        }
    };
    fm.beginTransaction().add(auxiliary, "FRAGMENT_TAG").commit();
    fm.executePendingTransactions();

    auxiliary.startActivityForResult(new Intent(getContext(), ToStartActivity.class), 3333);
}

Хитрость заключается в использовании вспомогательного временного фрагмента.

8 голосов
/ 27 ноября 2011

У меня та же проблема, что и в первоначальном вопросе. Я знаю, что вы все опубликовали рабочее решение, НО, во всех решениях отсутствует одна вещь: инкапсуляция. Что я имею в виду - если в одном действии у меня есть 10 представлений, которые должны (по какому-либо событию) начинать другое упражнение, то должно быть НОРМАЛЬНО, чтобы иметь возможность запускать это новое действие из представления, которое нуждается в этом действии. Вы все пытаетесь убедить, что лучше обрабатывать все новые возможные действия из первоначального, чем почему мы добавили различную логику в каждом представлении. Мы можем захотеть переиспользовать код и создать одно пользовательское представление, которое может работать независимо от того, где мы его используем (работа может включать показ другого действия, например, для выбора чего-либо).

Я знаю, что это невозможно (или пока что не возможно) и является явным доказательством того, что Android SDK еще не готов для обработки действительно больших приложений.

Если вам нужен пример: в любом реальном бизнес-приложении, которое имеет, например, список клиентов (это должно быть представление), представление должно иметь возможность самостоятельно запускать действия addcustomer, редактировать действия клиентов и т. Д., Независимо от куда вы помещаете это представление списка клиентов (элемент управления) - потому что в больших приложениях вам нужно повторно использовать компоненты (вам может потребоваться показать элемент управления списком клиентов в операции заказа продукта, в операции расписания и т. д.).

Одним из возможных решений может быть: - начать новое действие (используя контекст представления (обычно это должно быть родительское действие). - при новом событии закрытия активности либо вызовите метод напрямую в вызывающем представлении (в зависимости от случая и возможностей): либо статический, который обрабатывает код, который вы обычно выполняете в результате действия, либо попытайтесь передать экземпляр вызывающего просматривать новое действие и делать то же самое. Таким образом, вы можете обрабатывать новое действие, не позволяя содержащемуся действию ничего о нем знать.

1 голос
/ 05 июля 2011

Нет способа поймать onActivityResult с вашей точки зрения, только с Activity.

И небезопасно предполагать, что Context объект - Activity. В общем, не стоит полагаться на этот факт. Даже если это кажется разумным в случае с представлениями, вы все равно должны использовать только методы, доступные через Context интерфейс. Это потому, что вы не можете предсказать все побочные эффекты для Activity, когда вы вызываете Activity определенные функции.

1 голос
/ 05 июля 2011

Вы должны поймать это из своей деятельности. startActivityForResult вызывается для вашей активности, поэтому он запустит Intent и получит результат. Я бы сказал, что вообще плохо запускать его прямо из кода представления. Лучшее решение было бы с clickListener (или checkChangeListener, или с чем угодно), установленным вашей деятельностью, и вызовом метода, такого как "openImageCapture".

Когда намерение вернется, ваша деятельность позаботится о результате и при необходимости обновит ваши представления.

Представления предназначены только для отображения материала на экране и получения пользовательского ввода, а действие - для выполнения реальной работы.

0 голосов
/ 01 июля 2017

Вот статическая функция для реализации решения @ riwnodennyk при преодолении ошибки Fragment must be static and not in anonymous class:

public static void myStartActivityForResult(FragmentActivity act, Intent in, int requestCode, OnActivityResult cb) {
    Fragment aux = new FragmentForResult(cb);
    FragmentManager fm = act.getSupportFragmentManager();
    fm.beginTransaction().add(aux, "FRAGMENT_TAG").commit();
    fm.executePendingTransactions();
    aux.startActivityForResult(in, requestCode);
}

public interface OnActivityResult {
    void onActivityResult(int requestCode, int resultCode, Intent data);
}

@SuppressLint("ValidFragment")
public static class FragmentForResult extends Fragment {
    private OnActivityResult cb;
    public FragmentForResult(OnActivityResult cb) {
        this.cb = cb;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (cb != null)
            cb.onActivityResult(requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
        getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
    }
}

Пример использования:

    Intent inPhonebook = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
    myStartActivityForResult((FragmentActivity) getContext(),
            inPhonebook, REQUEST_CODE_PICK_CONTACT, this::onContacts);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...