#java #android #android-fragments #android-activity
#java #Android #android-фрагменты #android-активность
Вопрос:
У меня проблема с порядком инициализации моей активности Android.
Основы:
Действие содержит ViewPager, содержащий 3 фрагмента. Активность открывается таким образом:
Intent foodsActivityIntent = new Intent(getActivity(), FoodsActivity.class);
foodsActivityIntent.putExtra("NavigationPosition", navigationPosition);
foodsActivityIntent.putExtra("SearchQuery", searchQuery);
foodsActivityIntent.putExtra("SelectedDateMillis", _currentDay.toDate().getTime());
startActivityForResult(foodsActivityIntent, 200);
В onCreate — методе я улавливаю намерение и делаю некоторые вещи:
Intent intent = getIntent();
if (intent != null) {
//Some stuff
_foodsPagerAdapter.performSearch();
}
Интересная часть здесь — «_foodsPagerAdapter.performSearch()». При этом я хочу выполнить поиск в каждом фрагменте.
public void performSearch() {
if (_foodSearchFragment != null)
_foodSearchFragment.performSearch();
if (_foodFavoritesFragment != null)
_foodFavoritesFragment.performSearch();
if (_foodCustomFragment != null)
_foodCustomFragment.performSearch();
}
Проблема:
Как вы можете видеть, метод поиска в каждом фрагменте вызывается только в том случае, если фрагмент не равен null. Моя проблема в том, что GetItem() — метод (который инициализирует фрагменты в адаптере) вызывается после завершения метода onCreate (и OnStart). Таким образом, метод performSearch для каждого фрагмента никогда не вызывается.
Вы можете лучше понять это с помощью этого вывода Logcat:
Сначала вызывается performSearch, а затем GetItem() . Но GetItem должен быть вызван первым, чтобы мой код работал.
GetItem():
@Override
public Fragment getItem(int i) {
Log.i("FoodActivityTest", "call getItem in FragmentPagerAdapter");
Fragment fragment = null;
switch (i) {
case 0:
if (_foodSearchFragment == null)
_foodSearchFragment = new FoodSearchFragment();
fragment = _foodSearchFragment;
break;
case 1:
if (_foodFavoritesFragment == null)
_foodFavoritesFragment = new FoodFavoritesFragment();
fragment = _foodFavoritesFragment;
break;
case 2:
if (_foodCustomFragment == null)
_foodCustomFragment = new FoodCustomFragment();
fragment = _foodCustomFragment;
break;
}
return fragment;
}
Что я делаю не так? Нужно ли мне подходить к проблеме по-другому?
РЕДАКТИРОВАТЬ 1:
FoodsActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foods);
//Init some views
_viewPager = findViewById(R.id.viewpager_foods);
_foodsPagerAdapter = new FoodsPagerAdapter(getSupportFragmentManager(), this);
_viewPager.setAdapter(_foodsPagerAdapter);
handleOpenIntent();
//do more stuff (show ads etc.)
Log.i("FoodActivityTest", "onCreate finished");
}
@Override
protected void onStart() {
super.onStart();
Log.i("FoodActivityTest", "onStart finished");
}
private void handleOpenIntent() {
Intent intent = getIntent();
if (intent != null) {
int navigationPosition = intent.getExtras().getInt("NavigationPosition");
String searchQuery = intent.getExtras().getString("SearchQuery");
_viewPager.setCurrentItem(navigationPosition);
_foodsPagerAdapter.performSearch(searchQuery);
}
}
РЕДАКТИРОВАТЬ 2:
FoodsPagerAdapter:
public class FoodsPagerAdapter extends FragmentPagerAdapter {
private Context _context;
private FoodSearchFragment _foodSearchFragment;
private FoodFavoritesFragment _foodFavoritesFragment;
private FoodCustomFragment _foodCustomFragment;
public FoodsPagerAdapter(FragmentManager fm, Context context) {
super(fm);
_context = context;
}
@Override
public Fragment getItem(int i) {
Log.i("FoodActivityTest", "call getItem in FragmentPagerAdapter");
Fragment fragment = null;
switch (i) {
case 0:
if (_foodSearchFragment == null)
_foodSearchFragment = new FoodSearchFragment();
fragment = _foodSearchFragment;
break;
case 1:
if (_foodFavoritesFragment == null)
_foodFavoritesFragment = new FoodFavoritesFragment();
fragment = _foodFavoritesFragment;
break;
case 2:
if (_foodCustomFragment == null)
_foodCustomFragment = new FoodCustomFragment();
fragment = _foodCustomFragment;
break;
}
return fragment;
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return _context.getString(R.string.activity_foods_search);
case 1:
return _context.getString(R.string.activity_foods_favorites);
case 2:
return _context.getString(R.string.activity_foods_customfood);
default:
return "Error";
}
}
public void performSearch(String query) {
Log.i("FoodActivityTest", "call performSearch");
if (_foodSearchFragment != null)
_foodSearchFragment.performSearch(query);
if (_foodFavoritesFragment != null)
_foodFavoritesFragment.performSearch(query);
if (_foodCustomFragment != null)
_foodCustomFragment.performSearch(query);
}
Комментарии:
1. Можете ли вы предоставить всю свою FoodActivity.class ?
2. Я добавил его в упрощенной форме. Итак, что я считаю актуальным.
3. Я думаю, что нашел решение. Но не знаю, хорошее ли это решение. Кажется грязным, но, похоже, работает: _viewPager.postDelayed(new Runnable() { @Override public void run() { _foodsPagerAdapter.performSearch(SearchQuery); } }, 500);
4.
adapter
для понимания проблемы требуется полный код5. Я добавил код адаптера
Ответ №1:
Вы должны иметь возможность извлекать значения из своего намерения перед инициализацией других объектов. Судя по тому, как это выглядит в настоящее время, вы пытаетесь заполнить представление без данных, а затем назначить данные позже. Чтобы решить, вы могли бы либо лучше обработать значение null в вашем адаптере, либо переместить назначение данных. Я бы, вероятно, сделал последнее.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foods);
// Added this. Moved part of handleOpenIntent() here, other half is below view init.
String searchQuery = "";
Intent intent = getIntent();
if (intent != null) {
int navigationPosition = intent.getExtras().getInt("NavigationPosition");
searchQuery = intent.getExtras().getString("SearchQuery");
//should probably have some error handling if the SearchQuery is missing or the value is invalid.
}
// End of additions
//Init some views
_viewPager = findViewById(R.id.viewpager_foods);
_foodsPagerAdapter = new FoodsPagerAdapter(getSupportFragmentManager(), this);
_viewPager.setAdapter(_foodsPagerAdapter);
// added this too, moved out of handleOpenIntent()
_viewPager.setCurrentItem(navigationPosition);
_foodsPagerAdapter.performSearch(searchQuery);
// end of additions
//removed
//handleOpenIntent();
//do more stuff (show ads etc.)
Log.i("FoodActivityTest", "onCreate finished");
}