Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo conectar múltiples recyclerview o fragmento de animación como se muestra

Uno de mis clientes recientemente surgió con una inspiración extraña, que realmente quiere integrar en su aplicación

Animación de prototipos aquí

  • Android OpenGL ES 2, Dibujo de cuadrados
  • WebView Javascript cross domain de un archivo HTML local
  • Cómo agregar EditText en listview y obtener su valor dinámicamente en todas las filas?
  • Retrofit con Rxjava Schedulers.newThread () vs Schedulers.io ()
  • Poner texto constante dentro de EditText que no debería ser editable - Android
  • ¿Hay alguna biblioteca o algoritmo para el calendario persa (Shamsi o Jalali) en Android?
  • Estoy tratando de mi duro para lograr esto, pero estoy realmente confundido. ¿Puede alguien simplemente guiarme los pasos para lograr este tipo de transición con animación.

    Permítanme hacerles una pregunta específica para que puedan contestarla fácilmente

    1. ¿Qué debemos utilizar aquí fragmentos o elementos de vistas diferentes?
    2. ¿Cómo interactuar ambos? Al igual que cuando se hace clic en la categoría de salón, ¿cómo llevar esa sección de categoría a la sección superior y mantenerla seleccionada?
    3. ¿Cómo convertirlos también a números de buscapersonas también?

  • Geofencing API triggers ingresa el evento cuando ya está en la zona
  • Cómo hacer un fondo 20% transparente en Android
  • ¿Cuál es la diferencia entre match_parent y fill_parent?
  • ¿Por qué la aceleración de hardware no funciona en mi vista?
  • Galaxy Nexus ignora la metaetiqueta del visor
  • Android webview.loadUrl no cargará otra página web
  • One Solution collect form web for “Cómo conectar múltiples recyclerview o fragmento de animación como se muestra”

    Gif

    Nota: El código de trabajo completo está disponible en https://github.com/mwajeeh/AnimationsPlayground

    Más explicación en este post: https://medium.com/p/implementing-complex-animations-in-android-full-working-code-41979cc2369e

    La animación de expansión de la tarjeta se puede hacer mediante la transición de elementos compartidos. Voy a darle suficiente material para iniciar la implementación de la apertura de categorías y el colapso de los indicadores de buscapersonas.

    Estoy asumiendo que los encabezados de categoría están en RecyclerView . Cuando se pulsa una categoría, abra la actividad de detalle con transiciones de elementos compartidos de la siguiente manera:

     int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition(); int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); List<Pair<View, String>> pairs = new ArrayList<Pair<View, String>>(); for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; i++) { ViewHolder holderForAdapterPosition = (ViewHolder) list.findViewHolderForAdapterPosition(i); View itemView = holderForAdapterPosition.image; pairs.add(Pair.create(itemView, "tab_" + i)); } Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, pairs.toArray(new Pair[]{})).toBundle(); //launch detail activity on tap Intent intent = new Intent(context, DetailActivity.class); context.startActivity(intent, bundle); 

    En la siguiente actividad he modificado la versión de https://github.com/JakeWharton/ViewPagerIndicator/blob/master/library/src/com/viewpagerindicator/IconPageIndicator.java

    Sólo se modifican estos dos métodos:

     public void notifyDataSetChanged() { mIconsLayout.removeAllViews(); IconPagerAdapter iconAdapter = (IconPagerAdapter) mViewPager.getAdapter(); int count = iconAdapter.getCount(); LayoutInflater inflater = LayoutInflater.from(getContext()); for (int i = 0; i < count; i++) { View parent = inflater.inflate(R.layout.indicator, mIconsLayout, false); ImageView view = (ImageView) parent.findViewById(R.id.icon); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // must be same as off previous activity view.setTransitionName("tab_" + i); } view.setImageResource(iconAdapter.getIconResId(i)); mIconsLayout.addView(parent); } if (mSelectedIndex > count) { mSelectedIndex = count - 1; } setCurrentItem(mSelectedIndex); requestLayout(); } @Override public void setCurrentItem(int item) { if (mViewPager == null) { throw new IllegalStateException("ViewPager has not been bound."); } mSelectedIndex = item; mViewPager.setCurrentItem(item); int tabCount = mIconsLayout.getChildCount(); for (int i = 0; i < tabCount; i++) { View child = mIconsLayout.getChildAt(i); boolean isSelected = (i == item); child.setSelected(isSelected); View foreground = child.findViewById(R.id.foreground); if (isSelected) { animateToIcon(item); foreground.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.fg_white)); } else { foreground.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.fg_gray)); } } } 

    Y este método se agrega en IconPageIndicator para apoyar el colapso del indicador:

     public void collapse(float top, float total) { //do not scale to 0 float newTop = top / 1.2F; float scale = (total - newTop) / (float) total; ViewCompat.setScaleX(this, scale); ViewCompat.setScaleY(this, scale); int tabCount = mIconsLayout.getChildCount(); float alpha = (total - top) / (float) total; for (int i = 0; i < tabCount; i++) { View parent = mIconsLayout.getChildAt(i); View child = parent.findViewById(R.id.foreground); ViewCompat.setAlpha(child, 1 - alpha); } } 

    En onCreate() de DetailActivity , posponga la transición hasta que el indicador esté establecido.

     supportPostponeEnterTransition(); indicator.post(new Runnable() { @Override public void run() { supportStartPostponedEnterTransition(); } }); 

    Otros archivos importantes relacionados:

    Activity_detail.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:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/black" app:elevation="0dp"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <!--dummy view--> <View android:layout_width="match_parent" android:layout_height="200dp"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@android:color/transparent" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:elevation="0dp" app:layout_collapseMode="pin"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <com.example.mwajeeh.animations.IconPageIndicator android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" app:centered="true" app:layout_behavior="com.example.mwajeeh.animations.CollapsingIndicatorBehaviour"/> <!--add fragments in this view pager with RecyclerView as root and app:layout_behavior="@string/appbar_scrolling_view_behavior"--> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </android.support.design.widget.CoordinatorLayout> 

    CollapsingIndicatorBehaviour.java

     import android.content.Context; import android.support.annotation.NonNull; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.WindowInsetsCompat; import android.util.AttributeSet; import android.view.View; public class CollapsingIndicatorBehaviour extends ViewOffsetBehavior<IconPageIndicator> { private static final String TAG = "CollapsingIndicatorBehaviour"; private WindowInsetsCompat lastInsets; public CollapsingIndicatorBehaviour() { } public CollapsingIndicatorBehaviour(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, IconPageIndicator child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, IconPageIndicator child, View dependency) { //keep child centered inside dependency respecting android:fitsSystemWindows="true" int systemWindowInsetTop = 0; if (lastInsets != null) { systemWindowInsetTop = lastInsets.getSystemWindowInsetTop(); } int bottom = dependency.getBottom(); float center = (bottom - systemWindowInsetTop) / 2F; float halfChild = child.getHeight() / 2F; setTopAndBottomOffset((int) (center + systemWindowInsetTop - halfChild)); if (dependency instanceof AppBarLayout) { float totalScrollRange = ((AppBarLayout) dependency).getTotalScrollRange(); child.collapse(-dependency.getTop(), totalScrollRange); } return true; } @NonNull @Override public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, IconPageIndicator child, WindowInsetsCompat insets) { lastInsets = insets; return super.onApplyWindowInsets(coordinatorLayout, child, insets); } } 

    Copie android.support.design.widget.ViewOffsetBehavior.java y android.support.design.widget.ViewOffsetHelper en su código desde la biblioteca de diseño. Estos archivos no son públicos, pero los necesitamos para que nuestro comportamiento funcione.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.