Intereting Posts
Android – сбой приложений на устройствах Pre-Lollipop Блокировка элементов управления плеером и метаданных Как найти «общедоступные» намерения, которые мы можем использовать при использовании других приложений в наших приложениях Webview не загружает автономные кешированные данные Использование панели действий в качестве кнопки «вверх», операция home saveInstanceState всегда равна нулю Блокировка Android onClick onFling Как отобразить ответ строки из db как один на один в Android? Как правильно очистить ImageView? Где разместить XML-файл, содержащий данные в приложении для Android Изменить цвет текста простого списка ViewView Множественный выбор Android Пользовательский Rangeeekbar android одним пальцем ShrinkResources установлено в true, но все неиспользуемые ресурсы (в частности, drawables) не удаляются Почему Paint.ANTI_ALIAS_FLAG не работает при рисовании в том же месте на Canvas? Настройка ViewModel для MvxFragment Значок приложения Android не меняется на телефоне, несмотря на перезагрузку, удаление и переустановку

Viewpager с динамической высотой не работает (всегда используйте высоту первого фрагмента)

Я последовал за этим и этим ответам, я также нашел эту ссылку.

Я использую эти ресурсы для проб и ошибок. Теперь мой пользовательский ViewPager успешно ViewPager его содержимое, но отображается только первый . FYI, мой ViewPager содержит несколько сложных представлений, таких как ExpendableListView – вот почему ни один из кода в этих ресурсах не работает отлично, мне нужно изменить код самостоятельно.

У меня есть 4 фрагмента (содержание), поэтому я использую pager.setOffscreenPageLimit(3);

Это мой пользовательский ViewPager :

 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(); } } 

Это мой 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(); 

И это мой 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> 

Пример:

Если высота первого фрагмента равна 100px, тогда все остальные фрагменты останутся на 100px. Поэтому, если высота второго фрагмента составляет 130 пикселей, он будет сокращен до 100 пикселей.

Когда я пытался отлаживать , onMeasure на моем CustomViewPager всегда вызывал 4 раза при создании Activity , но все они только считывали первый фрагмент. После этого onMeasure никогда не будет вызываться снова, даже когда я изменяю (слайд слева / справа) от одного фрагмента к другому.

Пожалуйста, помогите мне, я потратил много часов, чтобы заставить эту работу работать. Просто спросите меня, нужна ли вам дополнительная информация, спасибо за ваше время.

Привет, Blaze нашел, что какая-то вещь используется полностью, после меня работает решение.

Он включает пользовательский просмотр прокрутки и пользовательский пейджер. Пейджер настраиваемого представления – это вычисление высоты динамически в соответствии с высотой их дочерних элементов, его высота устанавливается для первоначального обертывания содержимого, а цель просмотра прокрутки обрабатывает событие касания, если пользователи прокручивают экран по вертикали, он не пройдет сенсорный Даже для прокрутки и, таким образом, пользователь может прокручивать страницу.

Пользовательский просмотр прокрутки

 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)); } } } 

Пользовательский просмотр пейджера

 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(); } } 

Файл макета

 <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> 

Мероприятия

 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); } } 

Адаптер фрагмента

Фрагменты с разной высотой добавляются в viewpager, FragmentBlue, Green и т. Д. – это всего лишь фрагменты, используемые для добавления в просмотрщик, который вы можете использовать своими собственными фрагментами. Одна вещь, которую нужно запомнить, – это их внешний макет, должен быть таким же, в моем случае я использовал макет лайнера для всех

 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); }