50

У меня есть приложение для рабочего планшета, которое я теперь пытаюсь сделать и на телефонах. На столе есть два фрагмента на экране фрагмента списка и фрагмента детали. Когда на телефоне появляется фрагмент списка и создается новое действие при нажатии элемента списка. Эта операция просто создает фрагмент в методе onCreate() и передает его на экран следующим образом.getView возвращает null, когда фрагмент был создан из-за активности

// Place an DeallDetailsFragment as our content pane 
DealDetailsFragment f = new DealDetailsFragment(); 
getFragmentManager().beginTransaction().add(android.R.id.content, f).commit(); 
getFragmentManager().executePendingTransactions(); 

Это работает как ожидалось, однако из-за этого действия мне нужно сообщить фрагменту, какие детали загружать и отображать. В моем классе DealDetailsFragment у меня есть метод updateDeal(), который обновляет содержимое следующим образом.

if (deal==null) { // could be null if user presses the loading deals list item before it loads 
    return; 
} 
this.deal=deal; 
if (dealTitle==null) { // get the view objects only once 
    holder = new ViewHolder(); 
    holder.dealHeat=(TextView) getView().findViewById(R.id.dealDetails_heat_textView); 
    holder.dealPrice=(TextView) getView().findViewById(R.id.dealDetails_price_textView); 
    holder.dealRetailer=(TextView) getView().findViewById(R.id.dealDetails_retailer_textView); 
    holder.dealTitle=(TextView) getView().findViewById(R.id.dealDetails_title_textView); 
    holder.dealDesc=(TextView) getView().findViewById(R.id.dealDetails_desc_textView); 
    holder.goToButton= (LinearLayout) getView().findViewById(R.id.dealDetails_goToDeal); 
    holder.dealImage=(ImageView) getView().findViewById(R.id.dealDetails_imageView); 
    holder.postedBy=(TextView) getView().findViewById(R.id.dealDetails_poster_textView); 
    holder.datePosted=(TextView) getView().findViewById(R.id.dealDetails_date_textView); 

getView() возвращается нуль, когда приложение бегала по телефону, где есть только один фрагмент показан.

Любые идеи? К сожалению, в Интернете не так много примеров фрагментов.

+0

На каком этапе жизненного цикла фрагмента является метод updateDeal называется? –

+0

Когда фрагмент создан и загружен. – bencallis

+1

какой именно метод? OnCreate? onCreateView? OnStart? onResume? –

ответ

110

Переведите вызов метода, который должен быть выполнен в течение onCreateView, и используйте вид, который вы раздуваете для справки вместо getView(). См жизненного цикла фрагмента для получения дополнительной информации: https://developer.android.com/guide/components/fragments.html#Creating

и документация getView(), что объясняет, почему она возвращает нуль, прежде чем onCreateView(LayoutInflater, ViewGroup, Bundle) возвращений:

GetView() Получить вид корневой макета фрагмента (один возвращаемый onCreateView (LayoutInflater, ViewGroup, Bundle)), если предоставлено.

https://developer.android.com/reference/android/app/Fragment.html#getView()

+0

Вы экономите мой день .... нет, Я нахожу этот ответ после того, как я выкопал пять часов. darn .. – Youngjae

+1

Perfect! К счастью, это только за 1 час до того, как найти этот ответ :). –

+2

Поиск вида таким образом предоставит новый вид, но я хочу ссылку на тот же вид? –

18

Перемещение метода к onCreateView() не помогло me.so ... Создать глобальную переменную mView

protected View mView; 

и onCreateView()

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Log.d(TAG, "oncreateView"); 
     super.onCreateView(inflater, container, savedInstanceState); 

     View view = inflater.inflate(R.layout.activity_secure_cloud_drive_folder, container, false); 
     this.mView = view; 
     return view; 
} 

и замените все ваши getView() на mView

+1

Кроме того, установите mView = null внутри метода onDetach(), чтобы избежать утечки памяти –

4

Вы должны проверить жизненный цикл Android, чтобы понять, ПОЧЕМУ это значение null для функции onAttach (...).

Добавлена ​​первая функция, называемая при создании фрагмента: onAttach(), но на самом деле представление не создано. Вот почему null возвращается, когда вы пытаетесь получить доступ к этому вызову.

Следующая функция onCreate() ... но пока нет созданного объекта !!!!

Третья функция называется это onCreateView(), и это здесь, где вы должны указать, что мнение прилагается к этому фрагменту .... И это только из этого вызова, когда объект представления существует и может быть доступен ,

Прочтите и изучите полный жизненный цикл here.

Приветствия

4

Вы можете исправить, поставив свой код внутри onViewCreated() -метода, который вы должны переопределить. Не забудьте позвонить по телефону super().

+0

Как-то это лучший ответ и недооцененный. Я не понимаю, почему вы должны поместить свой код в onCreateView, если он не имеет никакого отношения к инфляции. Вы должны быть немного более серьезными, замените «делать X-вещи» на «ваш код в метод onViewCreated». – HopefullyHelpful

+0

Бывают ситуации, когда вам нужно 'getView()' вне методов жизненного цикла. –

0

Это будет null в основном, потому что вы вызываете getview() перед тем, как вид завышен. Создание View объекта и заполнить с помощью inflater, а затем найти свой элемент пользовательского интерфейса см ниже код

View view = inflater.inflate(R.layout.fragment_albumslist, container, false); 
     TextView t= (TextView)view.findViewById(R.id.txtTest); 
     t.setText(strtext); 
     return view; 
1

Поскольку OnCreate() вызывается перед onCreateView(), вы раздувать ли вид в onCreateView() или нет, вы будете получить ничего через getView() в onCreate(), потому что за это время onCreate() еще не был вызван.

Android Lifecycle

+0

Я думаю, вы должны добавить источник или что-то вроде этого: http://i.imgur.com/6Jl56FA.jpg – Teocci

+0

спасибо, что делает его более ясным –