Откройте фрагмент из recyclerview (который является фрагментом) [duplicate]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

47
задан Léo Lam 9 November 2014 в 12:17
поделиться

4 ответа

На самом деле легко вызвать операцию для замены фрагмента.

Вам нужно использовать getActivity ():

((MyActivity) getActivity())

. Тогда вы можете вызывать методы из MyActivity, например :

((MyActivity) getActivity()).replaceFragments(Object... params);

Конечно, это предполагает, что у вас есть метод replaceFragments () в вашей деятельности, который обрабатывает процесс замены фрагмента.

Редактировать: @ismailarilik добавил возможный код replaceFragments в этом коде с первым комментарием ниже, который был написан @ silva96:

Код replaceFragments может быть:

public void replaceFragments(Class fragmentClass) {
    Fragment fragment = null;
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment)
            .commit();
}
39
ответ дан ismailarilik 20 August 2018 в 12:43
поделиться
  • 1
    Код replaceFragments может быть: public void replaceFragments(Class fragmentClass) { Fragment fragment = null; try { fragment = (Fragment) fragmentClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } // Insert the fragment by replacing any existing fragment FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit(); } – silva96 3 August 2015 в 14:51
  • 2
    @ silva96 Можно ли добавить этот комментарий к исходному ответу, чтобы его легче было читать? :) Благодаря. – admrply 10 December 2015 в 02:35
  • 3
    @admrply Я должен добавить, что это не очень хорошая практика, вы должны использовать обратные вызовы для взаимодействия между действиями и фрагментами, как говорят другие в комментариях. Я использую библиотеку с именем EventBus, которая для этого удивительна. github.com/greenrobot/EventBus – silva96 10 December 2015 в 13:19
  • 4
    @ silva96 Почему это не очень хорошая практика? У меня есть красный этот , и он похож на ответ, но я новичок в android. Каковы преимущества использования обратных вызовов? – Elkin 29 January 2017 в 14:36

из официальных документов:

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

В этом примере newFragment заменяет любой фрагмент (если он есть) в настоящее время в контейнере макета, идентифицированном идентификатором R.id.fragment_container. Вызывая addToBackStack(), замененный фрагмент сохраняется в фоновом стеке, поэтому пользователь может отменить транзакцию и вернуть предыдущий фрагмент, нажав кнопку «Назад».

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

http://developer.android.com/guide/components/fragments.html

52
ответ дан Anup Cowkur 20 August 2018 в 12:43
поделиться
  • 1
    Куда должен идти этот код? В деятельности, содержащей фрагменты или фрагмент? – Little Tiny Dev 21 October 2013 в 04:49
  • 2
    В деятельности. Фрагменты должны быть разделены, они должны просто уведомлять о деятельности, а затем деятельность должна выполнять эту работу. – Peter 14 May 2014 в 14:54
  • 3
    спасибо, что это работает – Gujarat Santana 21 October 2015 в 00:30

Так же, как сказал Марсин, у вас не должно быть фрагмента, начинающегося с другого фрагмента или активности. Лучший способ справиться с этой ситуацией - создать реализацию обратного вызова для основного действия для обработки запросов, таких как запуск нового фрагмента. Здесь - отличный пример в руководстве разработчика Android.

3
ответ дан DroidT 20 August 2018 в 12:43
поделиться

Обратите внимание, что фрагмент НЕ должен непосредственно заменять себя или любые другие фрагменты. Фрагменты должны быть отдельными объектами. Какой фрагмент должен сделать, так это сообщить родительской активности о том, что произошло какое-то событие. Но это опять-таки не фрагментная работа, чтобы решить, что с этим делать! Это должно быть действием, чтобы принять решение о замене фрагмента на телефоне, но, то есть добавлении другого в существующий на планшетах. Таким образом, вы в основном делаете что-то неправильно по дизайну.

И, как уже упоминалось, ваша деятельность должна использовать FragmentManager («родной» или из библиотеки совместимости) для выполнения задания (например, replace() или add() или remove()):

http://developer.android.com/guide/components/fragments.html

25
ответ дан Marcin Orlowski 20 August 2018 в 12:43
поделиться
  • 1
    Ага! Я попытался создать фрагмент, у которого был свой собственный метод .show (), который мог бы получить менеджер фрагментов и создать его, но он не работает. – Deminetix 18 September 2013 в 06:17
  • 2
    Связанная страница не поддерживает ваше заявление. В приведенном примере показан один заменяющий фрагмент, он предлагает только определение интерфейса обратного вызова, если требуется. – Leon 6 November 2015 в 13:13
  • 3
    Прочтите мой ответ еще раз. – Marcin Orlowski 6 November 2015 в 15:31
  • 4
    Кто-то должен сказать менеджерам продуктов и дизайнерам, что. в моем случае родительская активность настолько далека, что она не имеет представления о том, что отображается в ее иерархии представлений. – Brill Pappin 16 June 2017 в 11:40
Другие вопросы по тегам:

Похожие вопросы: