Intereting Posts
Как изменить положение пунктов меню на панели действий Скрытый файл build.xml в библиотеке сервисов Google Play, используемой для google maps v2? Выберите по крайней мере один из каждой категории? Lollipop: рисовать позади statusBar с его цветом, установленным на прозрачный Что вызывает это исключение java.lang.RuntimeException: java.lang.NoSuchMethodException: <init> Eclipse: Android Device Chooser – Неизвестный Android 2.3.4 Устройство Android runOnUiThread объяснение Android – граница для кнопки RecyclerView ambiguos setVisibility функция, нажатие на один вид влияет на несколько просмотров Как вы обрабатываете транзакции фрагментов, когда состояние родительской активности обязательно сохраняется? О каких мерах предосторожности и предупреждениях следует знать при использовании новой «Схемы подписки APK v2»? Автоматически разрешает сборку Android Ошибка: пиксели кадра должны быть сплошными или прозрачными (не промежуточными альфа). – Найден в пикселе # 4 вдоль верхнего края ProGuard: дублированное определение класса библиотеки? Хранение файла в базе данных Android (Пользовательский поставщик содержимого) с использованием поля _data – v1.6 Как использовать delete намерение выполнить некоторые действия по четкому уведомлению?

Получить целенаправленный вид из ViewPager

Я использую ViewPager для переключения видов с помощью левого / правого прокрутки.

ViewPager нуждается в адаптере, поэтому я создал его:

public class ListViewPagerAdapter extends PagerAdapter { protected static final String TAG = "ListViewPagerAdapter"; protected static final int NUM_VIEWS = 3; protected final Activity mActivity; public ListViewPagerAdapter(Activity activity) { mActivity = activity; } @Override public int getCount() { return NUM_VIEWS; } @Override public void startUpdate(View container) {} @Override public Object instantiateItem(View container, int position) { // ViewPager ViewPager viewPager = (ViewPager) container; // Wird verwendet, um die Views aufzurufen LayoutInflater layoutInflater = mActivity.getLayoutInflater(); // Standardmäßig ist news eingeblendet View view = layoutInflater.inflate(R.layout.news_fragment, null); // Falls sich die Position verändert, so verändert sich auch die View if (position == 0) { view = layoutInflater.inflate(R.layout.favorite_fragment, null); } else if (position == 2) { view = layoutInflater.inflate(R.layout.videos_fragment, null); } // View einblenden viewPager.addView(view, 0); return view; } @Override public void destroyItem(View container, int position, Object object) { // ViewPager ViewPager viewPager = (ViewPager) container; // View View view = (View) object; // View löschen viewPager.removeView(view); } @Override public void finishUpdate(View container) {} @Override public boolean isViewFromObject(View view, Object object) { View _view = (View) object; return view == _view; } @Override public Parcelable saveState() { return null; } @Override public void restoreState(Parcelable state, ClassLoader loader) {} } 

Теперь, я хочу получить текущий сфокусированный взгляд на viewpager. Я попробовал getChildAt (x), но он не работает.

Есть ли какой-то пример, или вы знаете, как получить текущий вид?

благодаря

Solutions Collecting From Web of "Получить целенаправленный вид из ViewPager"

Можно сохранить активный объект (View, Fragment, …), переопределив [PagerAdapter.setPrimaryItem] ( http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html# SetPrimaryItem% 28android.view.ViewGroup,% 20int,% 20java.lang.Object% 29 ). Например:

 private View mCurrentView; @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { mCurrentView = (View)object; } 

Вы должны зарегистрировать слушателя на своем ViewPager :

 pager.setOnPageChangeListener(new MyPageChangeListener()); 

Вы должны настроить слушателя, расширив прослушиватель:

 private int focusedPage = 0; private class MyPageChangeListener extends ViewPager.SimpleOnPageChangeListener { @Override public void onPageSelected(int position) { focusedPage = position; } } 

Я нашел это, посмотрев исходный код ViewPager.java в библиотеке совместимости . Я читал, что мы можем сделать больше, например catch onPageScrollStateChanged .

Чтобы построить адаптер, я использовал код в этом сообщении в блоге . Возможно, вы захотите посмотреть.

Вы можете добавить тег к созданному представлению в методе instantiateItem:

 view.setTag(position); 

Позже вы можете получить доступ к текущему выбранному виду:

 mPager.findViewWithTag(mPager.getCurrentItem()); 

Мне недавно нужно было реализовать это точное решение. Вот как я это сделал:

 Map<Integer, Object> views = Maps.newHashMap(); @Override public Object instantiateItem(View container, int position) { /* Create and add your View here */ Object result = ??? views.put(position, result); return result; } @Override public void destroyItem(View container, int position, Object object) { /** Remove your View here */ views.remove(position); } protected View findViewForPosition(int position) { Object object = views.get(position); if (object != null) { for (int i = 0; i < getChildCount(); i++) { View view = getChildAt(i); if (isViewFromObject(view, object)) { return view; } } } return null; } 

Попробуй это:

 public View getCurrentView(ViewPager pager) { for (int i = 0; i < pager.getChildCount(); i++) { View child = pager.getChildAt(i); if (child.getX() <= pager.getScrollX() + pager.getWidth() && child.getX() + child.getWidth() >= pager.getScrollX() + pager.getWidth()) { return child; } } return getChildAt(0); } 

Чтобы получить целенаправленное представление, я использую этот способ:

Когда я раздуваю свое представление, прежде чем добавлять его в ViewPager, я устанавливаю для него тег. Затем я проверяю этот тег.

 private View getCurrentView() { for (int i = 0; i < pager.getChildCount(); i++) { View v = pager.getChildAt(i); if (v != null) { if (v.getTag().equals(pageList.get(pager.getCurrentItem()).getTag())) return v; // pageList is a list of pages that I pass to page adapter } } return null; } 

Эти ответы мне не подходят, все они имеют нежелательные побочные эффекты. Либо я должен добавить ненужные переменные (мне нравится чистый код), либо я должен сам работать с каркасом Android.

Мое решение основано на отражении, которое обращается к списку массивов всех объектов в ViewPager и возвращает текущий выбранный объект в ViewPager. Он почти не имеет побочных эффектов (отражение медленное, подклассификация существующего класса), и он сохраняет код в чистоте.

 public class ViewPagerEx extends ViewPager { private static final String TAG = ViewPagerEx.class.getSimpleName(); public ViewPagerEx(Context context, AttributeSet attrs) { super(context, attrs); } public ViewPagerEx(Context context) { super(context); } public Object getCurrentObject() { try { final Field itemsField = ViewPager.class.getDeclaredField("mItems"); itemsField.setAccessible(true); final ArrayList<Object> items = (ArrayList<Object>) itemsField.get(this); final int currentItemIndex = getCurrentItem(); if (currentItemIndex < 0 || currentItemIndex >= items.size()) { return null; } final Object infoItem = items.get(getCurrentItem()); final Class<?> itemInfoClass = findItemInfoClass(ViewPager.class.getDeclaredClasses()); final Field objectField = itemInfoClass.getDeclaredField("object"); objectField.setAccessible(true); return objectField.get(infoItem); } 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; } private Class<?> findItemInfoClass(final Class<?>[] classes) throws IllegalArgumentException { for (int i = 0; i < classes.length; i++) { if (classes[i].getSimpleName().equals("ItemInfo")) { return classes[i]; } } throw new IllegalArgumentException("cannot find class ItemInfo"); } } 

Внутри вашего FragmentStatePagerAdapter :

  private View mCurrentView; @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { Fragment f = (Fragment) object; mCurrentView = f.getView(); } 

Если вы внимательно изучите, на ViewPager будет сохранено не более 3 просмотров. Вы можете легко получить текущий вид

 view = MyActivity.mViewPager.getChildAt(1); 

Я что-то упускаю? В группе ViewGroup есть только 3 ребенка, поэтому это сводится к:

 int current = viewPager.getCurrentItem(); int childCount = viewPager.getChildCount(); // If there's a single page or we're at the beginning, return the first view if (childCount == 1 || current == 0) { return viewPager.getChildAt(0); } else { //For any other case, we want the second child. This is either the last page or the page in the middle for any other case. return viewPager.getChildAt(1); }