Intereting Posts
Изменение размера поверхности для изменения соотношения сторон в видеоизображении в андроиде Android-устройство отключается от отладчика через несколько секунд после достижения точки останова Почему этот сценарий оболочки называется скриптом python? Как поймать мягкую клавиатуру «введите / сделать» нажмите? «Аргумент« контекст »не может быть нулевым» Android: Как освободить ресурсы, когда приложение завершается? Получить текущее системное время Использует ли ProGuard проблему? Запуск приложений Android на аппаратном устройстве от Android Studio USB Volley – отправка запроса POST с использованием JSONArrayRequest Удержание камеры возвращает небольшое изображение Как установить цвет для изображения в Android Как добавить onclicklistener к кнопке внутри адаптера listview? Скриншот андроидной медиафотографии содержит черную рамку FFMpeg на Android, неопределенные ссылки на функции libavcodec, хотя он указан в командной строке

Как обновить-обновить фрагмент в ViewPager по основной активности программно

Я создаю приложение, в котором используется фрагмент и единственная MainActivity которые показывают разные фрагменты в одном и том же ViewPager, чтобы реплицировать поведение типичного приложения MVC.

Проблема в том, что я не понял, как я могу программно обновить фрагмент, чтобы обновить ViewPager новыми изменениями фрагментов

Например, у меня есть этот Fragment который показывает диаграмму (в моем намерении), когда я setFragment(int interval, Point[] snodePoint) из основного, диаграмму следует обновить в ViewPager

 public class LineFragment extends Fragment { static int interval; static Point snodePoints[]; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.fragment_linegraph, container, false); Bundle bundle = this.getArguments(); ChartConfig cg = bundle.getParcelable("FragmentData"); snodePoints = cg.getPoints(); interval= cg.getInterval(); Line l = new Line(); for(int i=0; i<snodePoints.length; i++){ LinePoint p = new LinePoint(); Point sp=snodePoints[i]; p.setX(sp.getX()); p.setY(sp.getY()); l.addPoint(p) } l.setColor(getResources().getColor(R.color.green)); LineGraph li = (LineGraph) v.findViewById(R.id.linegraph); li.addLine(l); li.setRangeY(0, interval); li.setLineToFill(0); li.setOnPointClickedListener(new OnPointClickedListener() { @Override public void onClick(int lineIndex, int pointIndex) { // TODO Auto-generated method stub } }); return v; } } 

В нескольких словах мне нужно

  • 1 – создать фрагмент, основанный на данных, полученных основным действием.
  • 2-изменение данных фрагмента каждый раз в основной деятельности происходит что-то вроде setFragment (…) с новыми данными (генерируемыми всегда основным).

Как я могу это сделать?

Основная деятельность с помощью FragmentAdapter

 public class MainActivity extends FragmentActivity { ViewPager mViewPager; MyFragmentAdapter mMyFragmentAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.view_pager); final ActionBar bar = this.getActionBar(); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); LineFragment lineFrag = new LineFragment(); BarFragment barFrag = new BarFragment(); PieFragment pieFrag = new PieFragment(); mMyFragmentAdapter = new MyFragmentAdapter(this, mViewPager); mMyFragmentAdapter.addTab(bar.newTab().setText("Line"), LineFragment.class, null, lineFrag); mMyFragmentAdapter.addTab(bar.newTab().setText("Bar"), BarFragment.class, null, barFrag); mMyFragmentAdapter.addTab(bar.newTab().setText("Pie"), PieFragment.class, null, pieFrag); mViewPager.setOffscreenPageLimit(mMyFragmentAdapter.getCount() - 1); } public static class MyFragmentAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener { private final MainActivity mContext; private final ActionBar mActionBar; private final ViewPager mViewPager; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); private final ArrayList<Fragment> mFrag = new ArrayList<Fragment>(); static final class TabInfo { private final Class<?> clss; private final Bundle args; TabInfo(Class<?> _class, Bundle _args) { clss = _class; args = _args; } } public MyFragmentAdapter(MainActivity activity, ViewPager pager) { super(activity.getSupportFragmentManager()); mContext = activity; mActionBar = activity.getActionBar(); mViewPager = pager; mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, Fragment frag) { TabInfo info = new TabInfo(clss, args); tab.setTag(info); tab.setTabListener(this); mTabs.add(info); mFrag.add(frag); mActionBar.addTab(tab); notifyDataSetChanged(); } @Override public int getCount() { return mTabs.size(); } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); Bundle args = new Bundle(); ChartConfig cg = new ChartConfig(interval, snodePoint); args.putParcelable("FragmentData", cg); Fragment f = mFrag.get(position); f.setArguments(args); return f; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } @Override public void onPageScrollStateChanged(int state) { } public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) { Object tag = tab.getTag(); for (int i = 0; i < mTabs.size(); i++) { if (mTabs.get(i) == tag) { mViewPager.setCurrentItem(i); } } } public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) { } @Override public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) { } } 

}

В первый раз, когда я создаю фрагмент, основная активность пропускает параметры для фрагмента через переопределенный getItem(int position) , но если я попытаюсь изменить данные, также если я попытаюсь вызвать notifyDataSetChanged() на адаптере mMyFragmentAdapter , Ничего не происходит, и фрагменты в ViewPager продолжают использовать те же данные, которые были переданы при создании.

РЕДАКТИРОВАТЬ

После некоторого частичного кода, рассмотренного в другом вопросе об обновлении фрагмента, я также пробовал это

 public void update() { try{ LineFragment fragment = (LineFragment) getSupportFragmentManager().findFragmentByTag( "android:switcher:"+R.id.view_pager+":0"); if(fragment != null) { if(fragment.getView() != null) { fragment.updateDisplay(); } } } catch(RuntimeException e){ e.printStackTrace(); } } 

Предполагая, что 0 является идентификатором первого фрагмента фрагмента-вкладки (я не уверен в этом типе операции), но fragment.updateDisplay(); Не вызывается.

Solutions Collecting From Web of "Как обновить-обновить фрагмент в ViewPager по основной активности программно"

В вашем адаптере override getItemPosition

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

После этого

 viewPager.getAdapter().notifyDataSetChanged() 

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

Мне нужно понять, как Фрагмент может получить данные, переданные по основному каналу, возможно, я что-то пропустил, но на самом деле я не понял, как это сделать.

Из этого кажется, что вы хотите передать данные в момент создания Fragment . Если это то, что вы хотите, вы не должны создавать пользовательский конструктор (и, как правило, для Fragment вас должен быть только конструктор no-args по умолчанию (потому что платформе нужно его воссоздать Fragment в определенное время)).

Вместо этого вы должны либо передать данные в Bundle :

 @Override public Fragment getItem(int position) { switch (position) { //... Bundle args = new Bundle(); args.put("a_string_representing_theKey", data) LineFragment f = new LineFragment(); f.setArguments(args); return f; //... } } 

Это будет работать, только если данные могут быть помещены в Bundle (см. Метод put... класса Bundle , все примитивы + объекты, которые являются Parcelable ). В фрагменте вы можете получить аргументы, используя getArguments() .

Вы также можете заставить Fragment извлекать данные непосредственно из Activity :

 // in the lifecycle method where you want the data ((MainActivity)getActivity()).getDataForFragment(); // use the data 

Например, у меня есть этот фрагмент, который показывает диаграмму (в моем намерении), когда я вызываю setFragment (int interval, Point [] snodePoint) из основного, диаграмму следует обновить в ViewPager

Вы, кажется, противоречите себе. Для этого используйте код из вопроса, к setFragment() , конечно, просто вызывая ваш текущий setFragment() , ничего не сделает, поскольку вы просто обновляете значение двух переменных, вам нужно, чтобы пользовательский интерфейс знал об изменении (например, Вызов другого метода для воссоздания иерархии представлений, установка новых значений в виде диаграммы и вызов invalidate() т. Д.).

Редактировать:

Код, используемый в вопросе, с которым я связан, должен работать, но вы не используете правильный код. У вас есть FragmentStatePagerAdapter но вы используете код для FragmentPagerAdapter который не будет работать:

 FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) mViewPager.getAdapter(); LineFragment f = (LineFragment) a.instantiateItem(pager, thePositionYouWant); 

Имейте в виду, что приведенный выше код будет работать только для видимого фрагмента плюс 1 фрагмент с каждой стороны, другие фрагменты будут недоступны (и поскольку пользователь не видит их или не может сразу перейти к ним, T будет обновлено).

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

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

Код ссылки

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

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

В своем фрагменте добавьте ниже код для обновления интерфейса

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

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

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

Как получить выбранную позицию tablayout

 ((YourActivityName) getContext()).tablayout.getSelectedPosition(); 

Очень просто переопределить метод в фрагменте

@Override

 public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ actionView(); } else{ //no } } 
 #How to update-refresh Fragment in ViewPager by Main Activity programmatically #after long struggle I find proper solution tablayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { refreshTab(tab.getPosition());// create a method viewpager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } }); private void refreshTab(int position) { switch (position) { case 0: break; case 1: CompaniesInterest comP1 = (CompaniesInterest) viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem()); comP1.refreshpage(); break; case 2: TotalSelectedCompanies toTal = (TotalSelectedCompanies) viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem()); toTal.refreshpage(); } } // Create a interface for refresh data for fragmen public interface Refreshpage { void refreshpage(); } // implements Refreshpage interface in both fragment TotalSelectedCompanies and CompaniesInterest // @Override`enter code here` public void refreshpage() { // do what you want to refresh }