with layout_scrollflags layout_collapsemode ejemplo coordinatorlayout collapsing appbarlayout android android-collapsingtoolbarlayout nestedscrollview
herehere

android - layout_scrollflags - No se puede desplazar AppBarLayout y colapsar la barra de herramientas con NestedScrollView sin problemas



layout_collapsemode (4)

Estoy trabajando en una aplicación de Android en la que estoy usando CoordinatorLayout , AppBarLayout y CollapsingToolbarLayout para usar la funcionalidad de la barra de herramientas de contraer.

Estoy usando NestedScrollView en el diseño para expandir y contraer AppBarLayout en el mismo diseño. Cuando intento desplazarme hacia arriba desde el centro de la pantalla, entonces no funciona, pero cuando intento desplazarme hacia arriba desde la esquina derecha de la pantalla, se desplaza suavemente.

A continuación se menciona mi archivo xml

layout.xml

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:fillViewport="true" android:fitsSystemWindows="true" android:paddingBottom="2dp" android:paddingLeft="5dp" android:paddingRight="5dp" android:paddingTop="5dp" android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/fragment_back_color" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="5dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/new_recharge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dp" android:text="NEW PAYMENT" android:textColor="@color/offer_name_text_color" /> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="@color/white" android:paddingBottom="20dp" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="20dp"> <HorizontalScrollView android:id="@+id/hsv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:fillViewport="true" android:measureAllChildren="false" android:scrollbars="none"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="horizontal"> <LinearLayout android:id="@+id/wallet_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/wallet_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/wallet_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="WALLET" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> <View android:layout_width="5dp" android:layout_height="20dp" android:background="@color/white" /> <LinearLayout android:id="@+id/prepaid_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/prepaid_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/prepaid_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="PREPAID" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> <View android:layout_width="5dp" android:layout_height="20dp" android:background="@color/white" /> <LinearLayout android:id="@+id/postpaid_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/postpaid_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/postpaid_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="POSTPAID" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> <View android:layout_width="5dp" android:layout_height="20dp" android:background="@color/white" /> <LinearLayout android:id="@+id/dth_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/dth_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/dth_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="DTH" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> <View android:layout_width="5dp" android:layout_height="20dp" android:background="@color/white" /> <LinearLayout android:id="@+id/landline_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/landline_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/landline_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="LANDLINE" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> <View android:layout_width="5dp" android:layout_height="20dp" android:background="@color/white" /> <LinearLayout android:id="@+id/datacard_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/datacard_recharge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/datacard_recherge" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="65dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="5dp" android:gravity="center" android:text="DATACARD" android:textColor="@color/offer_name_text_color" android:textSize="12sp" /> > </LinearLayout> </LinearLayout> </HorizontalScrollView> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dp" android:paddingLeft="5dp" android:paddingRight="5dp" android:paddingTop="10dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/recent" /> <com.spiceladdoo.views.RobotTextviewRegular android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dp" android:text="RECENT" android:textColor="@color/offer_name_text_color" /> </LinearLayout> <ListView android:id="@+id/recent_recharge_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="5dp" android:layout_marginRight="5dp"> </ListView> </LinearLayout> <FrameLayout xmlns:tools="http://schemas.android.com/tools" android:id="@+id/recharge_container" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" tools:ignore="MergeRootFrame"> </FrameLayout> </RelativeLayout> </android.support.v4.widget.NestedScrollView>

El resultado deseado es cuando intento desplazarme hacia arriba desde el centro de la pantalla, entonces debería funcionar tan bien como me desplazo hacia arriba desde la esquina derecha del móvil.

Por favor vea el video mencionado abajo para ver el problema más claramente

https://www.dropbox.com/s/gscfc8vfc7kkpxp/device-2015-12-30-160119.mp4?dl=0


Creo, lo he clavado:

Puede encontrar el código fuente here - no dude en probar;

Tomé como ejemplo google/designlibdemo .

Así es como se ve mi Activity :

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_height="match_parent" android:layout_width="match_parent" android:fitsSystemWindows="true"> <include layout="@layout/include_list_viewpager"/> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_height="match_parent" android:layout_width="wrap_content" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" app:menu="@menu/drawer_view"/> </android.support.v4.widget.DrawerLayout>

Alberga ViewPager : include_list_viewpager.xml :

<?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:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|enterAlways|snap" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp" android:fitsSystemWindows="true"> <ImageView android:id="@+id/image" android:src="@drawable/header_image" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerCrop" android:fitsSystemWindows="true" app:layout_collapseMode="parallax"/> <View android:background="#AA50AA00" android:layout_width="match_parent" android:layout_height="200dp" app:layout_collapseMode="parallax"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:title="" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin" /> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:background="#50AA00" app:tabMode="scrollable" app:tabIndicatorColor="#FFF" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout>

CollapsingToolbarLayout hosts Toolbar ( app:layout_collapseMode="pin" ) y por encima de ImageView ( app:layout_collapseMode="parallax" ).

El alojado en el Fragmento ViewPager tiene este diseño:

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:fillViewport="true" android:fitsSystemWindows="true" android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:orientation="vertical" android:background="#DDD" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="16dp"> <ImageView android:src="@drawable/mobile" android:layout_marginTop="2dp" android:layout_width="16dp" android:layout_height="16dp" /> <TextView android:text="@string/prepaid_recharge" android:layout_marginStart="16dp" android:layout_gravity="center_vertical" android:textColor="#000" android:fontFamily="sans-serif-medium" android:textSize="14sp" android:textAllCaps="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> ........ <ListView android:id="@+id/recent_recharge_list" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> </android.support.v4.widget.NestedScrollView>

Así que tiene esta app:layout_behavior="@string/appbar_scrolling_view_behavior" comportamiento app:layout_behavior="@string/appbar_scrolling_view_behavior" y llenando ViewPort ( android:fillViewport="true" )

Y en realidad, eso es todo lo que necesitas. Fragment clase de Fragment es muy estándar:

public class RechargeFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.recharge_fragment, container, false); } }

Activity también se mantiene muy estándar.

De nuevo, puedes encontrar mi ejemplo de código here .

¡NÓTESE BIEN! Encontré que funciona bastante mal (nada suave) en el emulador.

Espero que ayude.


Más o menos tuve un problema similar al trabajar con CoordinatorLayout con AppbarLayout , CollapsingToolbarLayout y NestedScrollView como vistas secundarias.

El siguiente código es una pieza de trabajo directamente desde el área de trabajo de mi proyecto.

<?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:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/cover_pic" android:layout_width="match_parent" android:layout_height="256dp" android:scaleType="centerCrop" app:layout_collapseMode="parallax" android:src="@drawable/cookin"/> <android.support.v7.widget.Toolbar android:id="@+id/mToolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin"/> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_gravity="bottom" android:background="?attr/colorPrimary" app:tabMode="scrollable"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.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/tab_viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.v4.widget.NestedScrollView> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_phone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_marginRight="@dimen/fab_margin" android:visibility="invisible" app:backgroundTint="@color/colorFAB2" app:elevation="6dp" android:layout_margin="5dp" app:pressedTranslationZ="12dp" android:src="@drawable/ic_phone_white_24dp" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_book" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="5dp" android:layout_marginRight="@dimen/fab_margin" android:visibility="invisible" app:elevation="6dp" app:backgroundTint="@color/colorFAB1" app:pressedTranslationZ="12dp" android:src="@drawable/ic_receipt_white_24dp" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" app:elevation="6dp" app:backgroundTint="@color/colorAccent" app:pressedTranslationZ="12dp" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_add_white_24dp" /> </LinearLayout> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>


Parece duplicado de this . Aunque apunta a un hilo "resuelto", el otro está más relacionado con RecyclerView.

Escribí mi comportamiento basado en las soluciones hechas por Manolo Garcia y Kirill Boyarshinov desde el hilo RecyclerView. En mi caso, no se llamó a onNestedFling() cuando onNestedPreScroll() gesto de lanzamiento, por lo que onNestedPreScroll() . He estado trabajando dentro de ViewPager con NestedScroll hoy, no he probado debajo de la solución en un escenario diferente (aunque se basa en un código similar que escribí para RecyclerView hace un año).

Primer comportamiento actualizado (agréguelo en xml como app:layout_behavior="your.package.FlingBehavior"> para android.support.design.widget.AppBarLayout ):

public final class FlingBehavior extends AppBarLayout.Behavior { private static final String TAG = FlingBehavior.class.getName(); private static final int TOP_CHILD_FLING_THRESHOLD = 1; private static final float OPTIMAL_FLING_VELOCITY = 3500; private static final float MIN_FLING_VELOCITY = 20; boolean shouldFling = false; float flingVelocityY = 0; public FlingBehavior() { } public FlingBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int velocityX, int velocityY, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, velocityX, velocityY, consumed); if (velocityY > MIN_FLING_VELOCITY) { shouldFling = true; flingVelocityY = velocityY; } else { shouldFling = false; } } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target) { super.onStopNestedScroll(coordinatorLayout, abl, target); if (shouldFling) { Log.d(TAG, "onNestedPreScroll: running nested fling, velocityY is " + flingVelocityY); onNestedFling(coordinatorLayout, abl, target, 0, flingVelocityY, true); } } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { if (target instanceof RecyclerView && velocityY < 0) { Log.d(TAG, "onNestedFling: target is recyclerView"); final RecyclerView recyclerView = (RecyclerView) target; final View firstChild = recyclerView.getChildAt(0); final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild); consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD; } // prevent fling flickering when going up if (target instanceof NestedScrollView && velocityY > 0) { consumed = true; } if (Math.abs(velocityY) < OPTIMAL_FLING_VELOCITY) { velocityY = OPTIMAL_FLING_VELOCITY * (velocityY < 0 ? -1 : 1); } Log.d(TAG, "onNestedFling: velocityY - " + velocityY + ", consumed - " + consumed); return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } }

Ahora debería desplazarse sin problemas, pero el contenido de NestedScrollView (y RecyclerView) puede desplazarse antes de que se apague AppBarLayout, lo que puede parecer extraño. Para resolverlo sigue esta respuesta . Haga un pequeño cambio para usar el fullScroll(ScrollView.FOCUS_UP) lugar de scrollTo(0, 0) contrario, es posible que note un pequeño parpadeo durante los desplazamientos rápidos, aquí:

AppBarLayout appBarLayout = findViewById(...); appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { shouldScroll = Math.abs(verticalOffset) == appBarLayout.getTotalScrollRange(); } }); NestedScrollView nestedScrollView = findViewById(...); nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { if (!shouldScroll) nestedScrollView.fullScroll(ScrollView.FOCUS_UP); } });

Después de eso lo llamé final, pero es posible que desee seguir avanzando para que se desplace aún más fácilmente como en Google Play, hay un hilo (creo que no resuelto) al respecto here .


pruebe android:clickable="true" en la vista secundaria de NestedScrollView Like a continuación:

<android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:clickable="true"> </LinearLayout> </android.support.v4.widget.NestedScrollView>