Отправка данных из Activity во Fragment, когда фрагмент находится в onCreateView
Извините за мой английский. У меня есть одно действие, и в этом действии в FragmentPagerAdapter существуют 5 фрагментов. Все фрагменты используют одну объектную модель для информации (название продукта, изображение продукта...).
Моя деятельность получает данные из базы данных. И тогда данные отправляются на все фрагменты. Мой пример
@BindView(R.id.tabs_sep_prod) TabLayout tabs_sep_prod;
@BindView(R.id.viewpager_sep_prod) ViewPager viewpager_sep_prod;
PrepBaseProdFragment prepBaseProdFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sep_product);
ButterKnife.bind(this);
prepBaseProdFragment = new PrepBaseProdFragment();
// there i have another fragments
// ...
setupViewPager(viewpager_sep_prod);
tabs_sep_prod.setupWithViewPager(viewpager_sep_prod);
}
private void setupViewPager(ViewPager viewPager) {
SepProductActivity.ViewPagerAdapter adapter = new SepProductActivity.ViewPagerAdapter(
adapter.addFrag(prepBaseProdFragment, getString(R.string.sep_prep_base));
// there i have another addFrag
// ...
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(adapter);
}
@Override
public void onResume() {
super.onResume();
// this i call method from presenter, it return data in method setData
if(idCat != null && idProd != null)
sepProductPresenter.getSepProd(idCat, idProd);
}
@Override
public void setData(SepProductModel sepProductModel) {
// there i send data to fragment
prepBaseProdFragment.setDataInf(sepProductModel);
// ...
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
мой фрагмент
public class PrepBaseProdFragment extends BaseFragment {
@BindView(R.id.text) TextView text;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about_prod_prepare_base, parent, false);
ButterKnife.bind(this, view);
Log.e("PrepBaseProdFragment", "PrepBaseProdFragment");
return view;
}
public void setDataInf(SepProductModel sepProductModel) {
text.setText(sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT());
}
}
Мой вопрос: когда я отправляю данные из активности во фрагмент, мое представление не успевает инициализироваться. Во фрагменте text.setText(sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT());
ошибка
java.lang.NullPointerException: попытка вызвать виртуальный метод 'void android.widget.TextView.setText(java.lang.CharSequence)' для ссылки на пустой объект
Пожалуйста, помогите мне решить мою проблему. Я трачу много раз на это
2 ответа
Вы можете проверить, является ли текстовое представление пустым, сохранить данные в переменной внутри фрагмента и в onCreateView использовать переменную данных, если она заполнена, и установить текстовое представление текста. Что-то вроде этого:
// Inside the Fragment body
private SepProductModel sepProductModel;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about_prod_prepare_base, parent, false);
ButterKnife.bind(this, view);
Log.e("PrepBaseProdFragment", "PrepBaseProdFragment");
if(this.sepProductModel != null)
text.setText(this.sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT());
return view;
}
public void setDataInf(SepProductModel sepProductModel) {
if(text != null){
// use text
}
else this.sepProductModel=sepProductModel;
}
Я могу посоветовать вам дождаться ваших данных и затем показать фрагменты адаптеру, более того, все они используют одну и ту же модель. Пока у вас нет данных, вы можете показать индикатор выполнения. Когда вам нужна модель, вы можете создавать экземпляры своих фрагментов и устанавливать для них аргументы связки. Вы можете использовать метод следующим образом:
public static MyFragment newInstance(MyModel model){
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putSerializable(KEY, model);//or args.putParcelable(KEY, model);
fragment.setArguments(args);
return fragment;
}
Обратите внимание: ваша модель должна реализовывать Serializable или Parcelable для помещения в пакет. Вы можете прочитать о разнице здесь. Затем в вашем методе set data, когда у вас уже есть модель, вы можете настроить свой адаптер и настроить его на просмотр пейджера, но с этим подходом:
adapter.addFrag(MyFragment.newInstance(model), getString(R.string.sep_prep_base));
Это должно помочь вам, спросите меня, если у вас есть вопросы.