Viewpager con altura dinámica no funciona (siempre use la altura del primer fragmento)

He seguido esto y que las respuestas, también he encontrado este enlace.

Utilizo esos recursos para hacer pruebas y errores. Ahora, mi ViewPager personalizado ViewPager éxito su contenido, pero solo se muestra el primero . FYI, mi ViewPager tiene algunas vistas complejas, como ExpendableListView – thats por qué ninguno de los códigos en los recursos que funcionan perfectamente, tengo que modificar el código por mí mismo.

Tengo 4 fragmentos (contenido), así que uso pager.setOffscreenPageLimit(3);

Este es mi ViewPager personalizado:

 public class CustomViewPager extends ViewPager{ public CustomViewPager (Context context) { super(context); } public CustomViewPager (Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; final View tab = getChildAt(0); int width = getMeasuredWidth(); int tabHeight = tab.getMeasuredHeight(); if (wrapHeight) { // Keep the current measured width. widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); } int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView()); heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public int measureFragment(View view) { if (view == null) return 0; view.measure(0, 0); return view.getMeasuredHeight(); } } 

Este es mi CustomPagerTabStrip :

 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); android.view.ViewGroup.LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); 

Y este es mi XML:

  <RelativeLayout android:id="@+id/relativePager" android:layout_width="match_parent" android:layout_height="wrap_content" > <com.xxx.yyy.util.CustomViewPager android:id="@+id/detailPager" android:layout_width="match_parent" android:layout_height="wrap_content" > <com.xxx.yyy.util.CustomPagerTabStrip android:id="@+id/detailTab" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#161C28" android:textColor="#FFFFFF" /> </com.xxx.yyy.util.CustomViewPager> </RelativeLayout> 

El caso de ejemplo:

Si la altura del primer fragmento es 100px, entonces todos los demás fragmentos permanecerán en 100px. Así que si la altura del segundo fragmento es 130px, se cortará a 100px.

Cuando intenté depurar , el onMeasure en mi CustomViewPager siempre llamado 4 veces cuando se crea la Activity , pero todos ellos sólo leen el primer fragmento. La onMeasure nunca se vuelve a llamar después de eso, incluso cuando cambio (desliza hacia la izquierda / derecha) de un fragmento a otro.

Por favor, ayúdame, he gastado muchas horas para que esta cosa funcione. Simplemente pregúnteme si necesita más información, Gracias por su tiempo.

Hola Blaze encontró algo de uso completo, la siguiente solución está funcionando para mí.

Incluye una vista de desplazamiento personalizado y un paginador de vista personalizada. El paginador de visualización personalizado de propósito es su calcular la altura dinámicamente de acuerdo a la altura de sus hijos, su hieght está configurado para envolver el contenido inicialmente y el propósito de la vista de desplazamiento es manejar el evento táctil, si los usuarios desplaza la pantalla verticalmente no pasará el tacto Incluso para desplazarse y por lo tanto el usuario es capaz de desplazarse por la página.

Vista de desplazamiento personalizada

 public class CustomScrollView extends ScrollView { private GestureDetector mGestureDetector; public CustomScrollView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new YScrollDetector()); setFadingEdgeLength(0); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev); } // Return false if we're scrolling in the x direction class YScrollDetector extends SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return (Math.abs(distanceY) > Math.abs(distanceX)); } } } 

Paginador de vista personalizado

 public class CustomPager extends ViewPager{ public CustomPager (Context context) { super(context); } public CustomPager (Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; final View tab = getChildAt(0); int width = getMeasuredWidth(); int tabHeight = tab.getMeasuredHeight(); if (wrapHeight) { // Keep the current measured width. widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); } int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView()); heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public int measureFragment(View view) { if (view == null) return 0; view.measure(0, 0); return view.getMeasuredHeight(); } } 

Archivo de diseño

 <com.example.demo2.activity.widget.CustomScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView style="@style/text" android:text="Text 1" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 2" /> <com.example.demo2.activity.widget.CustomPager android:id="@+id/myViewPager" android:layout_width="match_parent" android:layout_height="wrap_content" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 4" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 5" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 6" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 7" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 8" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 9" /> <View style="@style/text_divider" /> <TextView style="@style/text" android:text="Text 10" /> </LinearLayout> 

Actividad

 public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyPagerAdapter pageAdapter = new MyPagerAdapter(getSupportFragmentManager()); ViewPager pager = (ViewPager)findViewById(R.id.myViewPager); pager.setAdapter(pageAdapter); } } 

Adaptador de fragmento

Fragmentos con diferentes alturas se agregan al viewpager, FragmentBlue, etc verde son sólo fragmentos utilizados para agregar a la viewpager puede utilizar sus propios fragmentos, una cosa para recordar es su diseño exterior debe ser el mismo en mi caso he utilizado forro de diseño para todos

 public class MyPagerAdapter extends FragmentPagerAdapter { private List<Fragment> fragments; public MyPagerAdapter(FragmentManager fm) { super(fm); this.fragments = new ArrayList<Fragment>(); fragments.add(new FragmentBlue()); fragments.add(new FragmentGreen()); fragments.add(new FragmentPink()); fragments.add(new FragmentRed()); } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } } 
 public CustomPager (Context context) { super(context); } public CustomPager (Context context, AttributeSet attrs) { super(context, attrs); } int getMeasureExactly(View child, int widthMeasureSpec) { child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int height = child.getMeasuredHeight(); return MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; final View tab = getChildAt(0); if (tab == null) { return; } int width = getMeasuredWidth(); if (wrapHeight) { // Keep the current measured width. widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); } Fragment fragment = ((Fragment) getAdapter().instantiateItem(this, getCurrentItem())); heightMeasureSpec = getMeasureExactly(fragment.getView(), widthMeasureSpec); //Log.i(Constants.TAG, "item :" + getCurrentItem() + "|height" + heightMeasureSpec); // super has to be called again so the new specs are treated as // exact measurements. super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 
  • ViewPager con FragmentPagerAdapter no se muestra
  • Dos fragmentos en una página de viewpager
  • Cómo reemplazar Fragment dentro de ViewPager, usando PagerAdapter?
  • Vista personalizada que divide el diseño en diagonal con diferentes vistas secundarias
  • Establecer la altura del buscador dinámicamente
  • ViewPager establece la página actual por programación
  • Vista de calendario personalizado en Android
  • ViewPagerIndicator CirclePageIndicator no se puede instanciar
  • Transición de página de paginación personalizada
  • ViewPager con indicador sin la biblioteca de soporte de Android
  • Comportamiento de desplazamiento de AppBarLayout
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.