Обновить fragment из ViewPager

У меня есть Activity с ViewPager . У меня также есть Dialog которое будет извлекать список с некоторыми элементами, которые пользователь выберет. Теперь, как я могу обновить Fragment где объекты должны отображаться как новые представления, прикрепленные к этому fragmentу?

Вот мой ViewPager :

 public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return 1; } @Override public android.support.v4.app.Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); default: return null; } } } 

Теперь вот Fragment :

 public class Fragment1 extends Fragment{ @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); } @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public ViewGroup onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub ViewGroup view = (ViewGroup)inflater.inflate(R.layout.screen1, container, false); } return view; } } 

Это метод, который я хочу использовать для добавления элементов в мой Fragment

 private void addItem() { // Instantiate a new "row" view. final ViewGroup[] newViews = new ViewGroup[selectedItems.length]; for(int i = 0; i < selectedItems.length; i++){ newViews[i] = (ViewGroup) LayoutInflater.from(this).inflate( R.layout.animated_layout_item, mContainerView, false); // Set the text in each new row. ((TextView) newViews[i].findViewById(android.R.id.text1)).setText(selectedItems[i]); // Because mContainerView has android:animateLayoutChanges set to true, // adding this view is automatically animated. mContainerView.addView(newViews[i], 0); // Set a click listener for the "X" button in the row that will remove the row. OnClickListener listener = new MyAddItemListener(newViews[i], mContainerView, this); newViews[i].findViewById(R.id.delete_button).setOnClickListener(listener); } } 

Обновить fragment из ViewPager

Вам необходимо реализовать getItemPosition(Object obj) .

Этот метод вызывается, когда вы вызываете

 notifyDataSetChanged() 

на вашем ViewPagerAdaper . Неявно этот метод возвращает значение POSITION_UNCHANGED что означает что-то вроде этого: «Фрагмент – это то, где он должен быть, поэтому ничего не меняйте».

Поэтому, если вам нужно обновить Fragment, вы можете сделать это с помощью:

  • Всегда возвращайте POSITION_NONE из getItemPosition() . Это означает: «Фрагмент должен всегда воссоздаваться»
  • Вы можете создать некоторый метод update (), который будет обновлять ваш fragment (fragment будет обрабатывать сами обновления)

Пример второго подхода:

 public interface Updateable { public void update(); } public class MyFragment extends Fragment implements Updateable { ... public void update() { // do your stuff } } 

И в FragmentPagerAdapter вы сделаете что-то вроде этого:

 @Override public int getItemPosition(Object object) { MyFragment f = (MyFragment ) object; if (f != null) { f.update(); } return super.getItemPosition(object); } 

И если вы выберете первый подход, это может выглядеть так:

 @Override public int getItemPosition(Object object) { return POSITION_NONE; } 

Примечание. Стоит подумать о том, какой подход вы поднимете.

Я столкнулся с проблемой несколько раз, чтобы в этом случае всегда избегать FragmentPagerAdapter и использовать FragmentStatePagerAdapter.

Это работает для меня. Надеюсь, это сработает и для вас.

Я реализую демонстрацию приложения после ответа Саймона. Только для тех, кто ищет этот вопрос.

Вы можете получить исходный код на GitHub

введите описание изображения здесь

В вашем PagerAdapter переопределить getItemPosition

 @Override public int getItemPosition(Object object) { // POSITION_NONE makes it possible to reload the PagerAdapter return POSITION_NONE; } 

После этого добавьте viewPager.getAdapter (). NotifyDataSetChanged (); этот код, как показано ниже

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { viewPager.getAdapter().notifyDataSetChanged(); } @Override public void onPageScrollStateChanged(int state) { } }); 

должно сработать.

Вы можете обновить fragment двумя способами,

Первый путь

как @ Саймон

Вам необходимо реализовать getItemPosition(Object obj) .

Этот метод вызывается, когда вы вызываете

 notifyDataSetChanged() 

Вы можете найти пример в Github и получить дополнительную информацию в этом сообщении .

введите описание изображения здесь

Второй путь

Мой подход к обновлению fragmentов в viewpager заключается в использовании метода setTag() для любого инстанцированного представления в методе instantiateItem() . Поэтому, когда вы хотите изменить данные или сделать недействительными требуемое представление, вы можете вызвать метод findViewWithTag() на ViewPager, чтобы получить ранее созданное представление и изменить / использовать его, как вы хотите, без необходимости удаления / создания нового представления каждый раз, когда вы хотите обновить некоторое значение.

 @Override public Object instantiateItem(ViewGroup container, int position) { Object object = super.instantiateItem(container, position); if (object instanceof Fragment) { Fragment fragment = (Fragment) object; String tag = fragment.getTag(); mFragmentTags.put(position, tag); } return object; } public Fragment getFragment(int position) { Fragment fragment = null; String tag = mFragmentTags.get(position); if (tag != null) { fragment = mFragmentManager.findFragmentByTag(tag); } return fragment; } 

Вы можете найти пример в Github или более подробную информацию в этом сообщении :

введите описание изображения здесь

Принятый ответ не понял, поэтому добавлено простое решение. после долгой борьбы найти Рабочее решение.

Просто сообщите об этом своему адаптеру , он работает потрясающе,

Код ссылки

  void setAdapter(int position) { PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(pagerAdapter); // when notify then set manually current position. viewPager.setCurrentItem(position); pagerAdapter.notifyDataSetChanged(); } 

вызовите этот код, когда вы устанавливаете адаптер, и когда вы хотите обновить интерфейс.

В своем fragmentе добавьте этот код для обновления

 ((YourActivityName) getContext()).setAdapter(selectedTabPosition); 

Используйте instanceof для контекста трансляции.

Этот общий код помогает только тем, кто находит решение.

Очень просто переопределить метод в fragmentе:

 @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ actionView(); } else{ //no } } 

Очень простое, но эффективное решение для обновления представлений fragmentов . Используйте setUserVisibleHint() . Он будет вызван, когда fragment будет видимым для пользователя. Там вы можете обновить наш вид ( setText() или setVisibility() и т. Д.)

 @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ //Write your code to be executed when it is visible to user } } 

Это сработало в моем случае. Надеюсь, поможет!

Возможно, ваш метод добавления элементов в fragment должен быть общедоступным (помещен в желаемый fragment) и должен иметь параметр того же типа, что и selectedItems ..

Это сделает его видимым из активности, в котором будет выбран массив элементов и вуаля.

ps лучше называть его addItemsFromArray(typeOfSelectedItems[] pSelectedItems) вызвать имя addItem() довольно неописательно

Редактировать: stackoverflow просто предложил аналогичную тему 🙂 Проверьте здесь, чтобы получить подробную идею реализации .. 🙂

1) Создайте обработчик в fragmentе, который вы хотите обновить.

 public static Handler sUpdateHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... sUpdateHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); // call you update method here. } }; } 

2) В Activity / Fragment / Dialog, где бы вы ни запускали вызов обновления, получите ссылку на этот обработчик и отправьте сообщение (сообщив об обновлении вашего fragmentа)

 // Check if the fragment is visible by checking if the handler is null or not. Handler handler = TaskTabCompletedFragment.sUpdateHandler; if (handler != null) { handler.obtainMessage().sendToTarget(); } 

Если вы используете Kotlin, вы можете сделать следующее:

1. Во-первых , вы должны создать Interface и реализовать его в своем Fragment

 interface RefreshData { fun refresh() } class YourFragment : Fragment(), RefreshData { ... override fun refresh() { //do what you want } } 

2. Следующий шаг – добавить OnPageChangeListener в ViewPager

 viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { } override fun onPageSelected(position: Int) { viewPagerAdapter.notifyDataSetChanged() viewPager.currentItem = position } override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { } }) 

3. переопределить getItemPosition в вашем Adapter

 override fun getItemPosition(obj: Any): Int { if (obj is RefreshData) { obj.refresh() } return super.getItemPosition(obj) } 
Interesting Posts

Как установить расширение Imagick / imagemagick PHP на Windows 7

Почему Matlab’s inv медленно и неточно?

Существуют ли лучшие методы для организации пакетов (Java)?

Аккумулятор внезапно падает примерно с 25% до 6%

Проводка файла и связанных данных в RESTful WebService предпочтительно в виде JSON

Таймер WPF Как таймер C #

Проверьте, является ли файл реальным или символическая ссылка

Как сгенерировать разные случайные числа в цикле в C ++?

Заменить новую строку в TSQL

Представления, наложенные выше YouTubePlayerFragment или YouTubePlayerView в иерархии компоновки, приводят к тому, что воспроизведение приостанавливается немедленно

получить имя приложения из имени пакета

Создавать распределение размеров файлов из командной строки

Какая польза от статической переменной в C #? Когда его использовать? Почему я не могу объявить статическую переменную внутри метода?

Редактирование PDF для удаления раздела?

Java: boolean in println (boolean? “Print true”: “print false”)

Давайте будем гением компьютера.