Consiga enfocado View from ViewPager
Utilizo el ViewPager para cambiar las vistas con el deslizar izquierdo / derecho.
El ViewPager necesita un adaptador, por lo que he construido este:
- Android View.bringToFront () causa parpadeo
- Android: ¿puedo crear una vista / lienzo que no sea rectangular, pero por ejemplo, redondo?
- "El niño especificado ya tiene un padre" error usando FragmentStatePagerAdapater
- SetBackground vs setBackgroundDrawable (Android)
- Las vistas agregadas dinámicamente desaparecen en orientación en Android
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) {} }
Ahora, quiero conseguir la vista enfocada actual por el viewpager. Intenté getChildAt (x), pero no funciona.
¿Hay algún ejemplo, o tienes alguna idea de cómo obtener la vista actual?
Gracias
- Cambios en una página web a través de JavaScript que no aparecen en WebView. ¿Hay una manera de forzar el WebView para volver a dibujar su contenido?
- ¿Cómo puedo ver que View se vuelve visible
- Animación de fondo en Android?
- Agregar vista al grupo de vistas xml existente en el código
- Android ampliablelistview grupo / padre imagen de fondo cambiar cuando se colapsan o expanden
- Android WebView ZoomManager.onSizeChanged NullPointerException
- Widgets de Android: Cómo agregar vistas a RemoteViews en tiempo de ejecución
- MPandroidChart: permite acercar y alejar los valores sólo en el eje Y
Es posible guardar el objeto actualmente activo (Ver, Fragmento, …) mediante la sustitución de [PagerAdapter.setPrimaryItem] ( http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html# SetPrimaryItem% 28android.view.ViewGroup,% 20int,% 20java.lang.Object% 29 ). Por ejemplo:
private View mCurrentView; @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { mCurrentView = (View)object; }
Tienes que registrar un oyente en tu ViewPager
:
pager.setOnPageChangeListener(new MyPageChangeListener());
Tienes que personalizar el oyente mediante la extensión de un escucha de escuchas:
private int focusedPage = 0; private class MyPageChangeListener extends ViewPager.SimpleOnPageChangeListener { @Override public void onPageSelected(int position) { focusedPage = position; } }
Encontré esto mirando el código fuente ViewPager.java en la biblioteca de compatibilidad . He leído que podemos hacer más, por ejemplo catch onPageScrollStateChanged
.
Para construir el adaptador, utilicé el código en esta entrada del blog . Es posible que desee echar un vistazo.
Puede agregar una etiqueta a la vista creada en el método instantiateItem:
view.setTag(position);
Más adelante podrá acceder a la vista seleccionada actual:
mPager.findViewWithTag(mPager.getCurrentItem());
Hace poco necesitaba implementar esta solución exacta. Aquí está la manera que lo hice:
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; }
Prueba esto:
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); }
Para obtener una vista enfocada, uso de esta manera:
Cuando infle mi vista antes de agregarla en ViewPager fijé la etiqueta a ella. Entonces compruebo esta etiqueta.
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; }
Las respuestas dadas no eran realmente adecuadas para mí, todos ellos tienen efectos secundarios no deseados. O tengo que añadir variables innecesarias (me gusta el código limpio) o tengo que trabajar en torno al propio marco de Android.
Mi solución se basa en la reflexión, que accede a la lista de todos los objetos del ViewPager y devuelve el objeto seleccionado en el ViewPager. Casi no tiene efectos secundarios (la reflexión es lenta, subclase de una clase existente) y mantiene el código limpio.
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"); } }
Dentro de su FragmentStatePagerAdapter
:
private View mCurrentView; @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { Fragment f = (Fragment) object; mCurrentView = f.getView(); }
Si examina cuidadosamente, hay como máximo 3 vistas guardadas por ViewPager. Puede obtener fácilmente la vista actual
view = MyActivity.mViewPager.getChildAt(1);
¿Me estoy perdiendo de algo? Sólo hay 3 niños dentro de ViewGroup, por lo que se reduce a:
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); }
- GetLocationOnScreen () vs getLocationInWindow ()
- Cómo agregar un fragmento dentro de un ViewPager usando Nested Fragment (Android 4.2)