Android ViewPager получить текущий вид
У меня есть ViewPager, и я хотел бы получить текущий выбранный и видимый вид, а не позицию.
getChildAt(getCurrentItem)
возвращается неправильноView
Это работает не все время. Иногда возвращает ноль, иногда просто возвращает неправильный вид.
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser == true) { mFocusedListView = ListView; } }
PageListener on
ViewPager
сgetChildAt()
также не работает, не давая мне правильный вид каждый раз.
Как я могу получить текущий видимый вид?
View view = MyActivity.mViewPager.getChildAt(MyActivity.mViewPager.getCurrentItem()).getRootView();
ListView listview = (ListView) view.findViewById(R.id.ListViewItems);
18 ответов
Я понял это. Я позвонил setTag()
с именем для всех View
s/ListView
и просто позвони findViewWithTag(mytag)
, mytag
быть тегом.
К сожалению, нет другого способа решить эту проблему.
Я только что столкнулся с той же проблемой и решил ее с помощью:
View view = MyActivity.mViewPager.getFocusedChild();
Я использую этот метод с android.support.v4.view.ViewPager
View getCurrentView(ViewPager viewPager) {
try {
final int currentItem = viewPager.getCurrentItem();
for (int i = 0; i < viewPager.getChildCount(); i++) {
final View child = viewPager.getChildAt(i);
final ViewPager.LayoutParams layoutParams = (ViewPager.LayoutParams) child.getLayoutParams();
Field f = layoutParams.getClass().getDeclaredField("position"); //NoSuchFieldException
f.setAccessible(true);
int position = (Integer) f.get(layoutParams); //IllegalAccessException
if (!layoutParams.isDecor && currentItem == position) {
return child;
}
}
} catch (NoSuchFieldException e) {
Log.e(TAG, e.toString());
} catch (IllegalArgumentException e) {
Log.e(TAG, e.toString());
} catch (IllegalAccessException e) {
Log.e(TAG, e.toString());
}
return null;
}
Вы можете получить текущий элемент, обратившись к своему списку itens из вызова вашего адаптера. myAdapter.yourListItens.get(myViewPager.getCurrentItem());
Как видите, ViewPager может извлечь текущий индекс элемента вашего адаптера (текущая страница).
Если вы используете FragmentPagerAdapter, вы можете сделать следующее:
FragmentPagerAdapter adapter = (FragmentPagerAdapter)myViewPager.getAdapter();
и позвонить
adapter.getItem(myViewPager.getCurrentItem());
Это работает очень хорошо для меня;)
Используйте адаптер, расширяющий PagerAdapter, и переопределите метод setPrimaryItem внутри вашего PagerAdapter.
https://developer.android.com/reference/android/support/v4/view/PagerAdapter.html
class yourPagerAdapter extends PagerAdapter
{
// .......
@Override
public void setPrimaryItem (ViewGroup container, int position, Object object)
{
int currentItemOnScreenPosition = position;
}
// .......
}
viewpager.getChildAt(0)
это всегда возвращает мой текущий выбранный вид. это сработало для меня, но я не знаю, как это сделать.
Как это разыгрывается для всех вас?
public Object instantiateItem(final ViewGroup container, final int position) {
CustomHomeView RL = new CustomHomeView(MainActivity.ctxt);
if (position==0){
container.setId(R.id.home_container);} ...rest of code
тогда вот код для доступа к вашей странице
((ViewGroup)pager.findViewById(R.id.home_container)).getChildAt(pager.getCurrentItem()).setBackgroundColor(Color.BLUE);
Если вы хотите, вы можете настроить маленький мясной ход
RelativeLayout getPageAt(int index){
RelativeLayout rl = ((RelativeLayout)((ViewGroup)pager.findViewById(R.id.home_container)).getChildAt(index));
return rl;
}
Во время моих попыток найти способ декорирования представлений Android я думаю, что определил альтернативное решение проблемы OP, которое я задокументировал в своем блоге. Я ссылаюсь на него, так как код кажется слишком сложным для включения всего, что здесь есть.
Решение, которое я предлагаю:
- держит адаптер и вид полностью отделены
- можно легко запросить представление с любым индексом из пейджера представления, и он будет возвращен либо
null
если этот вид в данный момент не загружен или соответствующий вид.
Я должен был сделать это более общим, поэтому я решил использовать приватную "позицию" ViewPager.LayoutParams
final int childCount = viewPager.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = viewPager.getChildAt(i);
final ViewPager.LayoutParams lp = (ViewPager.LayoutParams) child.getLayoutParams();
int position = 0;
try {
Field f = lp.getClass().getDeclaredField("position");
f.setAccessible(true);
position = f.getInt(lp); //IllegalAccessException
} catch (NoSuchFieldException | IllegalAccessException ex) {ex.printStackTrace();}
if (position == viewPager.getCurrentItem()) {
viewToDraw = child;
}
}
Попробуй это
final int position = mViewPager.getCurrentItem();
Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.rewards_viewpager + ":"
+ position);
Это ваше первое занятие на экране, или вы уже расположили несколько слоев друг над другом?
попробуй это:
findViewById(android.R.id.content).getRootView()
или просто:
findViewById(android.R.id.content)
Также в зависимости от того, что вы хотите попробовать:
((ViewGroup)findViewById(android.R.id.content)).getChildAt(0)
Я использую ViewPagerUtils от FabulousFilter:
ViewPagerUtils.getCurrentView(ViewPager viewPager)
Используйте этот метод.
View getCurrentView(ViewPager viewPager) {
try {
final int currentItem = viewPager.getCurrentItem();
for (int i = 0; i < viewPager.getChildCount(); i++) {
final View child = viewPager.getChildAt(i);
final ViewPager.LayoutParams layoutParams = (ViewPager.LayoutParams) child.getLayoutParams();
Field f = layoutParams.getClass().getDeclaredField("position"); //NoSuchFieldException
f.setAccessible(true);
int position = (Integer) f.get(layoutParams); //IllegalAccessException
if (!layoutParams.isDecor && currentItem == position) {
return child;
}
}
} catch (NoSuchFieldException e) {
Log.e(TAG, e.toString());
} catch (IllegalArgumentException e) {
Log.e(TAG, e.toString());
} catch (IllegalAccessException e) {
Log.e(TAG, e.toString());
}
return null;
}
он может вернуть null в androidx, если кто-нибудь знает комментарий решения здесь
Вы можете найти фрагмент по системному тегу. Это работа для меня. Я использовал это в OnMeasure
функция.
id
- идентификатор ViewPager
position
- фрагмент, который вы хотите получить
Важный! Вы получите этот фрагмент, если ваш фрагмент был создан в адаптере. Так что вы должны проверить supportedFragmentManager.findFragmentByTag("android:switcher:" + id + ":" + position)
сводить на нет
Вы можете получить вид, как это:
supportedFragmentManager.findFragmentByTag("android:switcher:" + id + ":" + position).view
Вы не должны давать пользовательский тег в адаптере
Правильный способ сделать это — переопределитьonViewAttachedToWindow(holder: Holder)
метод в классе адаптера (расширение RecyclerView.Adapter).
Также, если вы хотите выполнить некоторые операции (освобождение ресурсов, остановку прослушивателей анимации и т. д.) в представлении, которое только что было удалено, это можно сделать, переопределивonViewDetachedFromWindow(holder: Holder)
в классе адаптера.
Вы можете получить его с помощью прослушивателя viewpager, чтобы получить позицию выбранного элемента.
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
}
})
Пожалуйста, проверьте это
((ViewGroup))mViewPager.getChildAt(MyActivity.mViewPager.getCurrentItem()));
еще проверьте эту ссылку.
Если вы внимательно изучите, то ViewPager сохранит не более 3 видов. Вы можете легко получить текущий вид по
view = MyActivity.mViewPager.getChildAt(1);