viewpager tablayout studio fragments example ejemplo android android-layout android-viewpager android-support-library

studio - tablayout android ejemplo



ViewPager en un NestedScrollView (19)

Necesito crear una interfaz como Google Newsstand, que es una especie de ViewPager (desplazamiento horizontal) sobre un encabezado colapsante (desplazamiento vertical). Uno de mis requisitos es utilizar la nueva Biblioteca de soporte de diseño presentada en Google IO 2015. ( http://android-developers.blogspot.ca/2015/05/android-design-support-library.html )

Basado en la muestra creada por Chris Banes ( https://github.com/chrisbanes/cheesesquare ) he llegado al punto en que puedo hacer el comportamiento de colapso pero con un LinearLayout básico (sin desplazamiento horizontal).

Intenté reemplazar LinearLayout por un ViewPager y obtuve una pantalla en blanco. Jugué con: ancho, peso y todo tipo de grupos de vistas, pero ... todavía una pantalla en blanco. Parece que ViewPager y NestedScrollView no se caen bien.

Intenté una solución usando un HorizontalScrollView: funciona pero pierdo el beneficio de la función PagerTitleStrip y el enfoque en un solo panel (puedo detener el horizontal entre 2 paneles).

Ahora no tengo más ideas, si alguien me puede llevar a una solución ...

Gracias

Aquí está mi último archivo de diseño:

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="@dimen/header_height" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginEnd="64dp" app:expandedTitleMarginStart="48dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <include layout="@layout/part_header" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_collapseMode="parallax"/> <android.support.v7.widget.Toolbar android:id="@+id/activity_main_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/activity_main_nestedscrollview" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.view.ViewPager android:id="@+id/activity_main_viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFA0"/> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>


Agregue android:fillViewport="true" en su NestedScrollView . período.


Bien, hice una pequeña demostración con ViewPager y NestedScrollView . El problema que enfrenté fue con la altura de ViewPager y ListView . Así que hice una pequeña modificación en ViewPager''s medición de altura de ListView y ViewPager''s .

Si a alguien le gustaría ver el código, aquí está el enlace: https://github.com/TheLittleNaruto/SupportDesignExample/

Salida:


Conozco una solución de trabajo: usa Activity, con CoordinatorLayout y usa FrameLayout, contenedor. Entonces. use el administrador de fragmentos para poner el fragmento en el contenedor. Por ejemplo mi código:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" app:layout_scrollFlags="scroll|enterAlways" android:layout_height="@dimen/toolbar_height" android:background="?attr/colorPrimary" android:gravity="center"> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> </FrameLayout>

Y fragmento:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.improvemdia.inmyroom.MainFragment"> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" />

Luego use FragmentManager

getSupportFragmentManager().beginTransaction() .replace(R.id.container, new MainFragment()) .commit();


Después de pasar horas probando todas las sugerencias anteriores, finalmente lo hice funcionar. La clave es poner NestedScrollView dentro de PageViewer , Y establecer layout_behavior en ''@string/appbar_scrolling_view_behavior'' para AMBAS vistas. El diseño final es como

<CoordinatorLayout> <ViewPager app:layout_behavior="@string/appbar_scrolling_view_behavior"> <NestedScrollView fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <Content>...</Content> </NestedScrollView> </ViewPager> <AppBarLayout>...</AppBarLayout> </CoordinatorLayout>


En lugar de colocar ViewPager dentro de NestedScrollView, hágalo al revés.

Coloque el NestedScrollView en las Vistas secundarias dentro del ViewPager, que en esencia es el diseño del Fragmento. También es muy probable que ni siquiera necesite usar NestedScrollView si el diseño de la lista de su Fragmento es muy simple.

Diseños de ejemplo

Diseño de la actividad:

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="@dimen/app_bar_height" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="@dimen/app_bar_height" android:scaleType="centerCrop" android:src="@drawable/my_bg" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.8" app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.design.widget.TabLayout android:id="@+id/content_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout>

Si no necesita TabLayout, puede deshacerse de LinearLayout y hacer que ViewPager sea independiente. Pero asegúrese de usar app:layout_behavior="@string/appbar_scrolling_view_behavior" en los atributos de ViewPager.

Diseño del fragmento simple:

<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" />

Diseño del fragmento complejo:

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:fillViewport="true" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello World"/> </RelativeLayout> </android.support.v4.widget.NestedScrollView>

Aplicación de ejemplo: CollapsingToolbarPoc


En realidad, NestedScrollView no necesita ser hermano directo de CollapsingToolbarLayout en CoordinatorLayout. He logrado algo realmente extraño. Appbar_scrolling_view_behavior funciona en 2 fragmentos anidados.

El diseño de mi actividad:

<android.support.design.widget.CoordinatorLayout> <android.support.design.widget.AppBarLayout> <android.support.design.widget.CollapsingToolbarLayout> <include layout="@layout/toolbar"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <FrameLayout android:id="@+id/container" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </android.support.design.widget.CoordinatorLayout>

En el marco del "contenedor", he inflado este fragmento:

<android.support.constraint.ConstraintLayout> ... some content ... <android.support.v4.view.ViewPager/> ... </android.support.constraint.ConstraintLayout>

Y los fragmentos dentro de ese ViewPager se ven así:

<RelativeLayout> <android.support.v7.widget.RecyclerView/> .... </RelativeLayout>

El hecho de que NestedScrollView puede ser tan profundo en la jerarquía de niños CoordinatorLayout y los comportamientos de desplazamiento aún funciona me sorprendieron.


Estaba teniendo un problema similar (pero sin CollapsingToolbarLayout , solo una simple Toolbar + TabLayout dentro de AppBarLayout ). Quería que la barra de herramientas desapareciera de la vista al desplazar hacia abajo el contenido de un ViewPager dentro de NestedScrollView .

Mi diseño fue algo así:

<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:animateLayoutChanges="true"> <android.support.v7.widget.Toolbar android:id="@+id/my_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|enterAlways"/> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/my_tab_layout" android:fillViewport="false" app:tabMode="fixed"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.view.ViewPager android:id="@+id/my_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> </android.support.v4.view.ViewPager> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>

Este diseño no funcionaba según lo previsto, pero lo resolví simplemente deshaciéndome de NestedScrollView y usando un LinearLayout en LinearLayout lugar. Funcionó para mí de inmediato en la Biblioteca de soporte de Android v23.1.0. Así es como terminó el diseño:

<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:animateLayoutChanges="true"> <android.support.v7.widget.Toolbar android:id="@+id/my_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|enterAlways"/> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/my_tab_layout" android:fillViewport="false" app:tabMode="fixed"/> </android.support.design.widget.AppBarLayout> <LinearLayout android:orientation="vertical" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="4dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.view.ViewPager android:id="@+id/my_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> </android.support.v4.view.ViewPager> </LinearLayout> </android.support.design.widget.CoordinatorLayout>

PD: Estos fueron en realidad dos archivos de diseño en mi proyecto. Los copié y pegué aquí e intenté estructurarlos como se vería en un solo archivo. Lo siento si me equivoqué al copiar y pegar, pero avíseme si ese es el caso para que pueda solucionarlo.


Lo siguiente debe garantizar la altura adecuada del localizador de vistas. El fragmento es el primer fragmento proporcionado por el buscapersonas.

<android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"/> <fragment class="com.mydomain.MyViewPagerFragment" android:id="@+id/myFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"/> </LinearLayout> </android.support.v4.widget.NestedScrollView>


Me encuentro con este problema, lo setFillViewport (true) mediante setFillViewport (true)

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:id="@+id/nest_scrollview" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="mio.kon.yyb.nestedscrollviewbug.ScrollingActivity" tools:showIn="@layout/activity_scrolling"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent"/>

en actividad

NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nest_scrollview); scrollView.setFillViewport (true);


No necesita usar NestedScrollView para tener los efectos de paralaje. prueba algo como esto:

<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:animateLayoutChanges="true"> <android.support.v7.widget.Toolbar android:id="@+id/my_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|enterAlways"/> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/my_tab_layout" android:fillViewport="false" app:tabMode="fixed"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/my_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </android.support.design.widget.CoordinatorLayout>


Tenía los mismos problemas.

Al colocar el NestedScrollView alrededor del ViewPager, no funcionaría.

Sin embargo, lo que sí funcionó fue poner el NestedScrollView dentro del diseño del fragmento que estoy cargando dentro del ViewPager.

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="fill_parent" android:layout_height="fill_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/fragment_detail" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="fill_vertical" android:orientation="vertical"> ...Content... </LinearLayout> </android.support.v4.widget.NestedScrollView>


Tenía un diseño con una barra de herramientas de la aplicación con NestedScrollView debajo, luego dentro de la barra de herramientas anidada había un LinearLayout, debajo del LinearLayout había un visor de buscapersonas. La idea era que LinearLayout dentro de NestedScrollView estaba arreglado: podía deslizarse hacia la izquierda / derecha entre las vistas del localizador de vistas, pero este contenido no se movería, al menos horizontalmente . Aún debería poder desplazar todo el contenido verticalmente debido a la vista de desplazamiento anidada. Esa fue la idea. Así que configuré la altura de NestedScrollView anidada en match_parent, llené la ventana gráfica y luego todos los diseños secundarios / ViewPager en wrap_content.

En mi cabeza eso estaba bien. Pero no funcionó: ViewPager me permitió ir a izquierda / derecha, pero sin desplazamiento vertical, independientemente de si el contenido de la página del visor se encontraba debajo de la parte inferior de la pantalla actual o no. Resulta que fue básicamente porque ViewPager no respeta wrap_content en sus diversas páginas.

Lo resolví subclasificando el ViewPager para hacer que cambie la altura según el elemento seleccionado actual, forzando a que se comporte como layout_height = "wrap_content":

public class ContentWrappingViewPager extends ViewPager { public ContentWrappingViewPager(Context context) { super(context); } public ContentWrappingViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; if (getChildCount() > getCurrentItem()) { View child = getChildAt(getCurrentItem()); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if(h > height) height = h; } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }

La solución se inspiró en esta respuesta . ¡Trabajó para mi!


Tengo el mismo deseo, anidar un ViewPager dentro de un NestedScrollView . Pero tampoco funciona para mí. En mi caso, ViewPager está dentro de un Fragment para que pueda cambiar el contenido dependiendo de las interacciones con el cajón. Por supuesto, AppBar, colapso, etc. y todas las nuevas características de la biblioteca de soporte deben funcionar.

Si un usuario desplaza verticalmente una página en el localizador, quiero que otras páginas se desplacen de la misma manera, para darle al usuario la impresión general de que el localizador se desplazó.

Lo que hice, que funciona, es que ya no ViewPager dentro de un NestedScrollView , sino que NestedScrollView el contenido de los fragmentos contenidos dentro de un NestedScrollView .

Luego, en caso de un desplazamiento en un fragmento, informo al contenedor de la nueva posición de desplazamiento, que lo almacena.

Finalmente, en un deslizamiento hacia la izquierda o hacia la derecha detectado desde el buscapersonas (usando addOnPageChangeListener buscando estados de arrastre), informo al fragmento objetivo izquierdo o derecho dónde debe desplazarse (según el conocimiento del contenedor) para alinearse con el fragmento del que procedo .


Tuve el mismo problema y lo solucioné con algunos cambios. ViewPager no funciona dentro de NestedScrollView . Simplemente ponga su ViewPager como hijo directo de su CoordinatorLayout . Luego, el contenido de cada Fragmento de ViewPager debe incluirse en NestedScrollView . Eso es.


Use la clase personalizada a continuación para resolver su problema. No olvides llamar al método onRefresh () en pagechangelistener.

public class ContentWrappingViewPager extends ViewPager { private int width = 0; public ContentWrappingViewPager(Context context) { super(context); } public ContentWrappingViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; width = widthMeasureSpec; if (getChildCount() > getCurrentItem()) { View child = getChildAt(getCurrentItem()); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if(h > height) height = h; } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public void onRefresh() { try { int height = 0; if (getChildCount() > getCurrentItem()) { View child = getChildAt(getCurrentItem()); child.measure(width, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if(h > height) height = h; } int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); ViewGroup.LayoutParams layoutParams = this.getLayoutParams(); layoutParams.height = heightMeasureSpec; this.setLayoutParams(layoutParams); } catch (Exception e) { e.printStackTrace(); } } }


acaba de eliminar el NestedScrollView en su xml y agrega este código en su clase

yourGridView.setNestedScrollingEnabled(true);


puede intentar así, el visor funciona bien, pero la altura del visor es fija.

Todavía estoy encontrando la mejor solución ..., así que por favor hágamelo saber cualquier punto puede hacerlo mejor, gracias

<android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="800dp" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> </android.support.v4.widget.NestedScrollView>


solo ponga esta línea en NestedScrollView

android:fillViewport="true"


Eliminé NestedScrollView del diseño principal e inserté como padre en todos mis diseños de fragmentos que se suponía que debían cargarse en ViewPager, me solucionaron este problema.