Android: Фрагмент не может получить активность

18

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

DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

работает отлично. Теперь я знаю в своей деятельности динамическую строку, которую мне нужно заменить в макете, который у меня есть в newFragment. Я думал, что я могу позвонить после transaction.commit () только что-то вроде

newFragment.setMyString("my dynamic value");

И в newFragment.java у меня есть

public void setMyString(String s)
{
 TextView tv = (TextView) getActivity().findViewById(R.id.myobject);
 tv.setText(s);
}

Дело в том, что getActivity () возвращает значение null. Как я могу получить контекст, который мне нужен, чтобы найти элементы макета?

Edit:

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

Bundle b = new Bundle();
b.putString("text", "my dynamic Text");
DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

Мой фрагмент onCreateView выглядит так:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
   View v = inflater.inflate(R.layout.mylayout, container, false);
   TextView t = (TextView) v.findViewById(R.id.texttobereplaced);
   t.setText(savedInstanceState.getString("text");
}

Кажется, что savedInstranceState пуст. Где я должен найти свой пакет?

Edit2:

пропустил getArguments () в ответе. теперь работает.

    
задан AndyAndroid 31.07.2012 в 17:11
источник

4 ответа

18

Ваш Fragment еще не присоединился к Activity , что также означает, что ваш макет еще не завышен (см. жизненный цикл фрагмента ). Лучшим решением здесь будет добавить значение String в качестве аргумента для Fragment через Fragment.setArguments(Bundle) . Это можно получить в получающем Fragment через Fragment.getArguments() .

    
ответ дан Jason Robinson 31.07.2012 в 17:19
источник
  • Мой макет раздувается, когда вызывается onViewCreated. Я вижу свой макет. –  AndyAndroid 31.07.2012 в 20:02
20

Убедитесь, что вы вызываете getActivity() в или после onAttach() , как и раньше, он возвращает null .

    
ответ дан Alex Lockwood 31.07.2012 в 17:33
источник
  • извините, я не понимаю, где я буду называть getActivity () и передать его моей функции setMyString (). И если я сделаю это там, где вы предлагаете, что вы все еще пишете, он может или не может вернуть значение null. Как я это понимаю? –  AndyAndroid 31.07.2012 в 20:05
  • Фрагмент будет привязан к нулевому действию до тех пор, пока onActivityCreated ... то есть, если вы вызываете getActivity () в onCreate или onCreateView, он вернет null, потому что Activity еще не создана. Поэтому убедитесь, что у вас есть все ваши вызовы getActivity () в или после onActivityCreated. –  Alex Lockwood 31.07.2012 в 20:12
  • Это неправильно. Как только onAttach называется getActivity (), можно вызвать без его возврата null. onActivityCreated - это просто обратный вызов для того, когда действие было полностью создано, и был создан экземпляр фрагмента. –  dymmeh 03.04.2014 в 17:35
  • @AlexLockwood Почему вы заявляете, что он вернет null в onCreate ()? Я вижу множество примеров в платформе Android, где они называют getActivity () внутри onCreate (). Вот один пример: androidxref.com/4.4.3_r1.1/xref/packages/apps/Calendar/src/com/... –  Igor Ganapolsky 10.07.2014 в 20:26
  • Да, я не уверен, почему я написал это ... действие должно быть доступно, если вы вызываете getActivity () после onAttach (). Я отредактировал свой оригинальный ответ, чтобы ответить на этот вопрос ... и, честно говоря, я не уверен, как этот ответ получил 5 upvotes. Думаю, я был еще 2 года назад. :П –  Alex Lockwood 11.07.2014 в 07:12
2

Итак, я также использую один и тот же менеджер транзакций фрагментов, и единственная проблема, которую я вижу с вашим кодом, заключается в том, что вы определяете текст TextView внутри вашего метода onCreateView вашего нового класса Fragment, а затем создаете его следующим образом:

public class AboutFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.newFragment, container, false);
        TextView tv = (TextView) v.findViewById(R.id.textview);
        return v;
    }

    public void setMyString(String s) {
        tv.setText(s);
    }
}

Я знаю, что это не имеет особого смысла, но вот как я запускаю свой код, и он отлично работает:)

    
ответ дан Android2390 31.07.2012 в 17:18
источник
  • извините, не знал, что это так важно :) изменил это ... теперь выглядит лучше –  Android2390 31.07.2012 в 17:38
  • Конечно, ваш код очень важен для StackOverflow ... люди не думают, что вы очень надежный источник, если ваш код явно нечитабель. Я только что отредактировал ваш ответ и удалил нижний план. –  Alex Lockwood 31.07.2012 в 17:43
0

Если вам нужно вызвать getActivity в OnCreateView, переместите весь ur-код из onCreateView в onActivityCreate и только левые строки

View v = inflater.inflate(R.layout.xxxx, container, false);
    return v;

в onCreateView

, но у меня странная ситуация.

в My onActivityCreated

Spinner s1 = (Spinner) getActivity().findViewById(R.id.bitlength);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            getActivity(), R.array.bitlengths,
            android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    s1.setAdapter(adapter);

Когда-то действие onActivityCreated не будет работать (правильно !?) и, следовательно, spinner s1 станет пустым.     

ответ дан 8086 Eve 24.03.2013 в 19:55
источник