Замена фрагментов в окне просмотра довольно сложна, но очень возможна и может выглядеть супер гладко.Во-первых, вам нужно позволить самому viewpager обрабатывать удаление и добавление фрагментов.Что происходит, когда вы заменяете фрагмент внутри SearchFragment, ваш viewpager сохраняет свои представления фрагментов.Таким образом, в итоге вы получаете пустую страницу, потому что SearchFragment удаляется при попытке ее заменить.
Решение состоит в том, чтобы создать прослушиватель внутри вашего окна просмотра, который будет обрабатывать изменения, сделанные вне его, поэтому сначала добавьте этот кодв нижней части вашего адаптера.
public interface nextFragmentListener {
public void fragment0Changed(String newFragmentIdentification);
}
Затем вам нужно создать закрытый класс в вашем viewpager, который становится слушателем, когда вы хотите изменить свой фрагмент.Например, вы можете добавить что-то вроде этого.Обратите внимание, что он реализует интерфейс, который был только что создан.Поэтому всякий раз, когда вы вызываете этот метод, он запускает код внутри класса ниже.
private final class fragmentChangeListener implements nextFragmentListener {
@Override
public void fragment0Changed(String fragment) {
//I will explain the purpose of fragment0 in a moment
fragment0 = fragment;
manager.beginTransaction().remove(fragAt0).commit();
switch (fragment){
case "searchFragment":
fragAt0 = SearchFragment.newInstance(listener);
break;
case "searchResultFragment":
fragAt0 = Fragment_Table.newInstance(listener);
break;
}
notifyDataSetChanged();
}
Здесь следует указать две основные вещи:
- fragAt0 is a "гибкий »фрагмент.Он может принимать любой тип фрагмента, который вы ему дадите.Это позволяет ему стать вашим лучшим другом в замене фрагмента в позиции 0 на нужный вам фрагмент.
Обратите внимание на слушателей, которые размещены в конструкторе 'newInstance (listener).Вот как вы будете вызывать фрагмент 0Changed (String newFragmentIdentification) `.В следующем коде показано, как создать прослушиватель внутри фрагмента.
static nextFragmentListener listenerSearch;
public static Fragment_Journals newInstance(nextFragmentListener listener){
listenerSearch = listener;
return new Fragment_Journals();
}
Вы можете вызвать изменение внутри вашего onPostExecute
private class SearchAsyncTask extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... params){
.
.//some more operation
.
}
protected void onPostExecute(Void param){
listenerSearch.fragment0Changed("searchResultFragment");
}
}
Это приведет к тому, что код внутри вашего viewpager переключит ваш фрагмент в нулевой позиции fragAt0, чтобы стать новым searchResultFragment.Есть еще две маленькие части, которые вам нужно добавить в пейджер, прежде чем он станет функциональным.
Один из них будет в методе переопределения getItem в пейджере.
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
//this is where it will "remember" which fragment you have just selected. the key is to set a static String fragment at the top of your page that will hold the position that you had just selected.
if(fragAt0 == null){
switch(fragment0){
case "searchFragment":
fragAt0 = FragmentSearch.newInstance(listener);
break;
case "searchResultsFragment":
fragAt0 = FragmentSearchResults.newInstance(listener);
break;
}
}
return fragAt0;
case 1:
// Games fragment activity
return new CreateFragment();
}
Теперь без этого финалакусок вы все равно получите пустую страницу.Вид хромает, но это неотъемлемая часть viewPager.Вы должны переопределить метод getItemPosition окна просмотра.Обычно этот метод возвращает POSITION_UNCHANGED, который сообщает ViewPager, чтобы все оставалось прежним, и поэтому getItem никогда не будет вызываться для размещения нового фрагмента на странице.Вот пример того, что вы могли бы сделать
public int getItemPosition(Object object)
{
//object is the current fragment displayed at position 0.
if(object instanceof SearchFragment && fragAt0 instanceof SearchResultFragment){
return POSITION_NONE;
//this condition is for when you press back
}else if{(object instanceof SearchResultFragment && fragAt0 instanceof SearchFragment){
return POSITION_NONE;
}
return POSITION_UNCHANGED
}
Как я уже сказал, код сильно усложняется, но вам, в основном, нужно создать собственный адаптер для вашей ситуации.Вещи, которые я упомянул, позволят изменить фрагмент.Скорее всего, потребуется много времени, чтобы все впитать, поэтому я буду терпелив, но все это будет иметь смысл.Совершенно стоит потратить время, потому что это может сделать действительно привлекательное приложение.
Вот самородок для обработки кнопки возврата.Вы помещаете это в MainActivity
public void onBackPressed() {
if(mViewPager.getCurrentItem() == 0) {
if(pagerAdapter.getItem(0) instanceof FragmentSearchResults){
((Fragment_Table) pagerAdapter.getItem(0)).backPressed();
}else if (pagerAdapter.getItem(0) instanceof FragmentSearch) {
finish();
}
}
. Вам нужно будет создать метод с именем backPressed () внутри FragmentSearchResults, который будет вызывать Frag00olated.Это в сочетании с кодом, который я показал ранее, будет обрабатывать нажатие кнопки назад.Удачи вам в вашем коде для изменения виджета.Требуется много работы, и, насколько я обнаружил, нет никаких быстрых адаптаций.Как я уже сказал, вы в основном создаете собственный адаптер viewpager и позволяете ему обрабатывать все необходимые изменения с помощью слушателей