Android ViewPager получить текущий вид

У меня есть ViewPager, и я хотел бы получить текущий выбранный и видимый вид, а не позицию.

  1. getChildAt(getCurrentItem) возвращается неправильно View
  2. Это работает не все время. Иногда возвращает ноль, иногда просто возвращает неправильный вид.

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    
        if (isVisibleToUser == true) { 
            mFocusedListView = ListView; 
        }
    }
    
  3. PageListener on ViewPager с getChildAt() также не работает, не давая мне правильный вид каждый раз.

Как я могу получить текущий видимый вид?

View view = MyActivity.mViewPager.getChildAt(MyActivity.mViewPager.getCurrentItem()).getRootView();
ListView listview = (ListView) view.findViewById(R.id.ListViewItems);

18 ответов

Решение

Я понял это. Я позвонил setTag() с именем для всех Views/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);
Другие вопросы по тегам