Здесь я попытался с помощью этого подхода:
import numpy as np
#converting to one_hot
def one_hot_encoder(value, datal):
datal[value] = 1
return datal
def _one_hot_values(labels_data):
encoded = [0] * len(labels_data)
for j, i in enumerate(labels_data):
max_value = [0] * (np.max(labels_data) + 1)
encoded[j] = one_hot_encoder(i, max_value)
return np.array(encoded)
, выбрав опцию, мне нужно обновить фрагмент, который в настоящее время виден.
blockquote>Простым способом сделать это является использование трюка, связанного с реализацией
FragmentPagerAdapter
:case R.id.addText: Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem()); // based on the current position you can then cast the page to the correct // class and call the method: if (ViewPager.getCurrentItem() == 0 && page != null) { ((FragmentClass1)page).updateList("new item"); } return true;
Пожалуйста, переосмыслите свое соглашение об именах переменных, используя в качестве имени переменной имя класса очень сбивает с толку (поэтому нет
ViewPager ViewPager
, например, используйтеViewPager mPager
).
final ViewPager.OnPageChangeListener onPageChangeListener =
new ViewPager.OnPageChangeListener() {
@Override public void onPageSelected(int position) {
switch (position) {
case 0:
FragmentClass1 frag1 =
(FragmentClass1) viewPager.getAdapter()
.instantiateItem(viewPager, viewPager.getCurrentItem());
frag1.updateList("Custom text");
break;
case 1:
break;
case 2:
break;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override public void onPageScrollStateChanged(int state) {
}
};
viewPager.addOnPageChangeListener(onPageChangeListener);
viewPager.setAdapter(adapter);
viewPager.post(new Runnable() {
@Override public void run() {
onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
}
});
Иногда фрагмент может отправлять нулевой объект, поэтому вы можете запустить новый Runnable для решения проблемы при первой загрузке.
Спасибо, rick
У меня была такая же проблема и я решил использовать этот код.
MyFragment fragment = (MyFragment) thisActivity.getFragmentManager().findFragmentById(R.id.container);
Просто замените имя MyFragment на имя вашего фрагмента и добавьте идентификатор вашего контейнера фрагментов.
Я использовал следующее:
int index = vpPager.getCurrentItem();
MyPagerAdapter adapter = ((MyPagerAdapter)vpPager.getAdapter());
MyFragment suraVersesFragment = (MyFragment)adapter.getRegisteredFragment(index);
Получить текущий фрагмент - получить позицию в ViewPager в public void onPageSelected (конечная позиция int), а затем
public PlaceholderFragment getFragmentByPosition(Integer pos){
for(Fragment f:getChildFragmentManager().getFragments()){
if(f.getId()==R.viewpager && f.getArguments().getInt("SECTNUM") - 1 == pos) {
return (PlaceholderFragment) f;
}
}
return null;
}
SECTNUM - аргумент позиции, назначенный публичному статическому PlaceholderFragment newInstance (int sectionNumber); of fragment
getChildFragmentManager () или getFragmentManager () - зависит от того, как созданные SectionsPagerAdapter
Заменить setPrimaryItem из вашего FragmentPagerAdapter: объект является видимым фрагментом:
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (mCurrentFragment != object) {
mCurrentFragment = (LeggiCapitoloFragment) object;
}
super.setPrimaryItem(container, position, object);
}
getSupportFragmentManager().getFragments().get(viewPager.getCurrentItem());
Передайте экземпляр, полученный из указанной выше строки, фрагменту, с которым вы хотите работать. Работает отлично.
viewPager
- это экземпляр пейджера, управляющий фрагментами.
Текущий фрагмент:
Это работает, если вы создали проект с шаблоном табуляции фрагментов.
Fragment f = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
Обратите внимание, что это работает с реализацией шаблона действия с вкладками по умолчанию.
В моей деятельности у меня есть:
int currentPage = 0;//start at the first tab
private SparseArray<Fragment> fragments;//list off fragments
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int pos) {
currentPage = pos;//update current page
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if(fragment instanceof Fragment1)
fragments.put(0, fragment);
if(fragment instanceof Fragment2)
fragments.put(2, fragment);
if(fragment instanceof Fragment3)
fragments.put(3, fragment);
if(fragment instanceof Fragment4)
fragments.put(4, fragment);
}
Then I have the following method for getting the current fragment
public Fragment getCurrentFragment() {
return fragments.get(currentPage);
}
FragmentStatePagerAdapter имеет открытый метод с именем instantiateItem, который возвращает ваш фрейм-график на основе заданных значений параметров, этот метод имеет два параметра ViewGroup (ViewPager) и позицию.
public Object instantiateItem(ViewGroup container, int position);
Используется этот метод для получения указанной позиции фрагмент,
Fragment fragment = (Fragment) adaper.instantiateItem(mViewPager, position);
Этот код поможет мне, проверьте его.
Здесь много ответов, которые на самом деле не затрагивают основополагающего факта, что НАСТОЯТЕЛЬНО НЕ ИМЕЕТ этого сделать предсказуемо, и таким образом, чтобы вы не стреляли в ногу в какой-то момент в будущем .
FragmentStatePagerAdapter
- единственный класс, который знает, как надежно получить доступ к фрагментам, которые отслеживаются с помощью FragmentManager
- любая попытка попытаться угадать идентификатор или тег фрагмента не является надежным, долгосрочным , И попытки отслеживания экземпляров вручную, скорее всего, не сработают, когда состояние будет сохранено / восстановлено, потому что FragmentStatePagerAdapter
может не вызывать обратные вызовы при восстановлении состояния.
О единственном, что у меня есть был способен заставить работу копировать код для FragmentStatePagerAdapter
и добавлять метод, который возвращает фрагмент, с учетом позиции (mFragments.get(pos)
). Обратите внимание, что этот метод предполагает, что фрагмент действительно доступен (т. Е. Он был видимым в какой-то момент).
Если вы особенно предприимчивы, вы можете использовать отражение для доступа к элементам частного mFragments
списка , но затем мы вернемся к квадрату (имя списка не будет оставаться неизменным).
public class MyPagerAdapter extends FragmentPagerAdapter {
private Fragment mCurrentFragment;
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
//...
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
}
onPageSelected
/ onPageDeselected
и все мои фрагменты пейджера расширяют его. Затем setPrimaryitem
может соответствующим образом вызывать эти методы, когда пользователь перебирает новую страницу. Это означает, что вы можете реализовать более ленивую стратегию для загрузки данных на страницах, которые даже не показаны. Однако вы должны иметь в виду, что во время перехода страницы лучше выглядеть, если на следующей странице уже заполнены данные, поэтому ленивая загрузка всех данных в onPageSelected
может быть не идеальной.
– JHH
18 December 2015 в 10:59
if
? Фрагмент просто вызывает метод equals
объекта, который является неглубоким сравнением. Так почему бы просто не называть всегда mCurrentFragment = ((Fragment) object);
?
– Sumido
16 May 2017 в 14:42
Вы можете реализовать BroadcastReceiver во Фрагменте и отправить Intent из любого места. Приемник фрагмента может прослушивать конкретное действие и вызывать метод экземпляра.
Одно из предостережений заключается в том, что компонент View уже создан и (и для некоторых операций, таких как прокрутка списка, ListView уже должен отображаться).
Просто получите текущий элемент из пейджера, а затем попросите адаптер к фрагменту этой позиции.
int currentItem = viewPager.getCurrentItem();
Fragment item = mPagerAdapter.getItem(currentItem);
if (null != item && item.isVisible()) {
//do whatever want to do with fragment after doing type checking
return;
}
После прочтения всех комментариев и ответов я собираюсь объяснить оптимальное решение этой проблемы. Лучшим вариантом является решение @ rik, поэтому мое улучшение основывается на его.
Вместо того, чтобы задавать каждый FragmentClass, как
if(FragmentClass1){
...
if(FragmentClass2){
...
}
Создайте свой собственный интерфейс и создайте его дочерние фрагменты, например
public interface MyChildFragment {
void updateView(int position);
}
Затем вы можете сделать что-то подобное, чтобы инициировать и обновлять внутренние фрагменты.
Fragment childFragment = (Fragment) mViewPagerDetailsAdapter.instantiateItem(mViewPager,mViewPager.getCurrentItem());
if (childFragment != null) {
((MyChildFragment) childFragment).updateView();
}
PS Будьте осторожны, когда вы вставляете этот код, если вы вызываете insatiateItem до того, как система действительно создаст его, savedInstanceState
вашего дочернего фрагмента будет пустым для него
public void onCreate(@Nullable Bundle savedInstanceState){
super(savedInstanceState)
}
Сбой вашего приложения.
Удачи
Вы можете определить PagerAdapter
как это, тогда вы сможете получить любой Fragment
в ViewPager
.
private class PagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
}
Чтобы получить текущий Fragment
Fragment currentFragment = mPagerAdapter.getItem(mViewPager.getCurrentItem());
Я знаю его слишком поздно, но у меня есть очень простые способы сделать это,
// для фрагмента в 0-м случае
((mFragment) viewPager.getAdapter().instantiateItem(viewPager, 0)).yourMethod();
, выбрав опцию, мне нужно обновить фрагмент, который в настоящее время виден.
blockquote>Чтобы получить ссылку на текущий видимый фрагмент, предположим, что у вас есть ссылка на
ViewPager
какmPager
. Затем следующие шаги получат ссылку наcurrentFragment
:
PageAdapter adapter = mPager.getAdapter();
int fragmentIndex = mPager.getCurrentItem();
FragmentStatePagerAdapter fspa = (FragmentStatePagerAdapter)adapter;
Fragment currentFragment = fspa.getItem(fragmentIndex);
Обычно используется только литая строка 3.
FragmentStatePagerAdapter
является полезным адаптером для ViewPager.
Когда мы используем viewPager, хорошим способом доступа к экземпляру фрагмента в активности является instantiateItem (viewpager, index). // индекс-индекс фрагмента, который вы хотите использовать.
Например, я обращаюсь к экземпляру фрагмента из 1 index-
Fragment fragment = (Fragment) viewPageradapter.instantiateItem(viewPager, 1);
if (fragment != null && fragment instanceof MyFragment) {
((MyFragment) fragment).callYourFunction();
}
FragmentStatePagerAdapter
имеет переменную частного экземпляра, называемую mCurrentPrimaryItem
типа Fragment
. Можно только задаться вопросом, почему разработчики Android не предоставили его с помощью геттера. Эта переменная создается в setPrimaryItem()
методе. Таким образом, переопределите этот метод таким образом, чтобы вы могли получить ссылку на эту переменную. Я просто закончил с объявлением своего mCurrentPrimaryItem
и копированием содержимого setPrimaryItem()
в мое переопределение.
В вашей реализации FragmentStatePagerAdapter
:
private Fragment mCurrentPrimaryItem = null;
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
public TasksListFragment getCurrentFragment() {
return (YourFragment) mCurrentPrimaryItem;
}
Это более надежное будущее, чем принятый ответ:
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
/* ------------------------------------------------------------------------------------------ */
// region Private attributes :
private Context _context;
private FragmentManager _fragmentManager;
private Map<Integer, String> _fragmentsTags = new HashMap<>();
// endregion
/* ------------------------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------------------------ */
// region Constructor :
public MyFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {
super(fragmentManager);
_context = context;
_fragmentManager = fragmentManager;
}
// endregion
/* ------------------------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------------------------ */
// region FragmentPagerAdapter methods :
@Override
public int getCount() { return 2; }
@Override
public Fragment getItem(int position) {
if(_fragmentsTags.containsKey(position)) {
return _fragmentManager.findFragmentByTag(_fragmentsTags.get(position));
}
else {
switch (position) {
case 0 : { return Fragment.instantiate(_context, Tab1Fragment.class.getName()); }
case 1 : { return Fragment.instantiate(_context, Tab2Fragment.class.getName()); }
}
}
return null;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// Instantiate the fragment and get its tag :
Fragment result = (Fragment) super.instantiateItem(container, position);
_fragmentsTags.put(position, result.getTag());
return result;
}
// endregion
/* ------------------------------------------------------------------------------------------ */
}
Это самый простой взлом:
fun getCurrentFragment(): Fragment? {
return if (count == 0) null
else instantiateItem(view_pager, view_pager.currentItem) as? Fragment
}
(код kotlin)
Просто вызовите instantiateItem(viewPager, viewPager.getCurrentItem()
и переведите его в Fragment
. Ваш объект уже будет создан. Чтобы убедиться, что вы можете добавить проверку для getCount
.
Работает как с FragmentPagerAdapter
, так и с FragmentStatePagerAdapter
!
Если ваш пейджер находится внутри фрагмента, используйте это:
private fun getPagerCurrentFragment(): Fragment? {
return childFragmentManager.findFragmentByTag("android:switcher:${R.id.myViewPagerId}:${myViewPager.currentItem}")
}
Где R.id.myViewPagerId
- это идентификатор вашего ViewPager внутри макета xml.
Этот сценарий лучше всего обслуживает каждый фрагмент, добавляя свои собственные пункты меню и непосредственно обрабатывая onOptionsItemSelected (), как описано в официальной документации . Лучше избегать недокументированных трюков.
ViewPager
?
– Suragch
6 December 2016 в 07:21
Основываясь на том, что он ответил @chahat jain:
«Когда мы используем viewPager, хорошим способом доступа к экземпляру фрагмента в активности является instantiateItem (viewpager, index). // index-index of фрагмент которого вам нужен. "
Если вы хотите сделать это в kotlin
val fragment = mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
if ( fragment is YourFragmentFragment)
{
//DO somthign
}
0 на экземпляр фрагмента 0
// = ================================================== ====================== // // ######################## ##### Пример использования ################################## // // ===== ================================================== ================== // //
Вот полный пример, чтобы получить самое лёгкое видение
.xml file ...
<android.support.v4.view.ViewPager
android:id="@+id/mv_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"/>
...
И домашняя активность, в которую я вставляю вкладку
...
import kotlinx.android.synthetic.main.movie_tab.*
class HomeActivity : AppCompatActivity() {
lateinit var adapter:HomeTabPagerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
...
}
override fun onCreateOptionsMenu(menu: Menu) :Boolean{
...
mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
...
override fun onQueryTextChange(newText: String): Boolean {
if (mv_viewpager.currentItem ==0)
{
val fragment = mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
if ( fragment is ListMoviesFragment)
fragment.onQueryTextChange(newText)
}
else
{
val fragment = mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 1) as Fragment
if ( fragment is ListShowFragment)
fragment.onQueryTextChange(newText)
}
return true
}
})
return super.onCreateOptionsMenu(menu)
}
...
}
Прежде всего, отслеживайте все «активные» фрагменты. В этом случае вы отслеживаете страницы фрагментов в FragmentStatePagerAdapter, которые используются ViewPager.
@Override
public Fragment getItem(int index) {
Fragment myFragment = MyFragment.newInstance();
mPageReferenceMap.put(index, myFragment);
return myFragment;
}
Чтобы избежать ссылки на «неактивные» фрагментные страницы, вам необходимо реализовать FragmentStatePagerAdapter destroyItem (...):
@Override
public void destroyItem (ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferenceMap.remove(position);
}
, и когда вам нужно получить доступ к отображаемой в данный момент странице, вы вызываете:
int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);
Где getFragment (int) MyAdapter метод выглядит следующим образом:
public MyFragment getFragment(int key) {
return mPageReferenceMap.get(key);
}
Надеюсь, это поможет!
Это единственный способ, которым я не получаю исключение NullPointerException для переменных экземпляра этих классов фрагментов. Это может быть полезно для других, которые придерживаются одного и того же. В onOptionsItemSelected () я закодировал ниже:
if(viewPager.getCurrentItem() == 0) {
FragmentClass1 frag1 = (FragmentClass1)viewPager
.getAdapter()
.instantiateItem(viewPager, viewPager.getCurrentItem());
frag1.updateList(text);
} else if(viewPager.getCurrentItem() == 1) {
FragmentClass2 frag2 = (FragRecentApps)viewPager
.getAdapter()
.instantiateItem(viewPager, viewPager.getCurrentItem());
frag2.updateList(text);
}
FragmentStatePagerAdapter
без переопределения какого-либо кода. Фактически, это должно быть так просто, как только функция возвращает viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem())
.
– John Pang
30 December 2016 в 18:44
instantiateItem()
и сами ссылаясь на соответствующие фрагменты. – Luksprog 29 January 2014 в 08:48mAdapter.getItem(position)
, удивительного ... По крайней мере сейчас я знаю, что другие 8512 испытаний не сработали. благодаря – Diolor 7 April 2014 в 21:24