Intereting Posts
Записать на экран Android Wear "Java.lang.IllegalArgumentException: никакие конфиги не соответствуют configSpec" При открытии камеры Intent Android Wear и Google Fit: как заставить обновлять наборы данных между смартваром и смартфоном? Android Layout: горизонтальный Recyclerview внутри вертикального Recyclerview внутри Viewpager с поведением прокрутки Есть ли способ получить уведомление, когда пользователь отключает устройство? Телефонная связь и подсказка () Visual Studio 2017 – Xamarin – Файл «obj \ Debug \ android \ bin \ packaged_resources» не существует Android Studio: javadoc пуст при наведении Получил «неподдерживаемый файл класса версии 52.0» после включения модуля в проект Приложение не появляется на рынке Android / google play Использование Gradle с существующим проектом Android Можно ли рисовать прямоугольник в XML? Создайте рябь без прозрачности Одновременное распознавание речи и аудиозапись Android Google теперь обрабатывает обмен сообщениями whatsapp

Альфа-кроссфейдинг OnPageChangeListener

Есть много вопросов относительно кроссфейдинга в Android, но все они включают анимацию. Мой вопрос о кроссфейде, используя OnPageChangeListener ViewPager.

У меня есть ViewPager, который может иметь неограниченное количество просмотров, но на практике использует около 6 или 7 просмотров. Не так много происходит там.

Каждый вид в ViewPager имеет фоновое растровое изображение, которое должно быть зафиксировано и перечеркнуто на фоне следующего (или предыдущего) вида вместо прокрутки вместе с остальной частью представления.

Для этого я отделил фоны и добавлю в ArrayList и назначим их ImageViews позже. Но так как я не хочу рисковать тем, что моя активность закончится многочисленными ImageViews, я подумал о следующей структуре:

<FrameLayout android:id="@+id/backgroundContainer" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/bottomImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <ImageView android:id="@+id/middleImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <ImageView android:id="@+id/topImage" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> </FrameLayout> 

Затем OnPageChangeListener назначается ViewPager для назначения фонов для ImageViews.

 @Override public void onPageSelected(int position) { MyLog.i(TAG, "PAGE SELECTED: " + position); if(position == 0) { _bottomBackground.setImageBitmap(null); _topBackground.setImageBitmap(_backgroundStack.get(position+1)); } else if (position == NUM_ITEMS-1) { _bottomBackground.setImageBitmap(_backgroundStack.get(position-1)); _topBackground.setImageBitmap(null); } else { _bottomBackground.setImageBitmap(_backgroundStack.get(position-1)); _topBackground.setImageBitmap(_backgroundStack.get(position+1)); } _middleBackground.setImageBitmap(_backgroundStack.get(position)); // Make the top front background transparent _topBackground.setAlpha(0f); _currentBackgroundPosition = position; } 

Это работает отлично, если бы мне хотелось просто поменять фоны. Я хочу, чтобы фоны пересекались друг с другом, пока пользователь просматривает ViewPager. У меня есть затухание для прямого прокрутки, но я не понимаю, почему исчезновение прокрутки назад как-то не дает хорошего результата. Во время обратного прокрутки средний фон должен исчезать на нижнем фоне.

Боюсь, что я что-то упустил. Я никогда не изменяю альфа нижнего фона, но результаты журнала всегда показывают то же самое значение для getAlpha() что и для среднего фона.

 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if(_currentBackgroundPosition == position) { // scroll forward _topBackground.setAlpha(positionOffset) } else { //scroll backward _middleBackground.setAlpha(positionOffset); } MyLog.i(TAG, "Bottom BackgroundAlpha: " + _bottomBackground.getAlpha()); MyLog.i(TAG, "Middle BackgroundAlpha: " + _middleBackground.getAlpha()); MyLog.i(TAG, "Top BackgroundAlpha: " + _topBackground.getAlpha()); } 

И ждать! Еще одна вещь, которую я действительно не могу понять, как исправить. Хотя работает прямая прокрутка прокрутки. В фоновом режиме есть супер короткое мерцание. Я предполагаю, что это происходит из-за того, как я настроил метод onPageSelected .

Есть ли другой способ, как я могу создать / исправить это поведение?

Solutions Collecting From Web of "Альфа-кроссфейдинг OnPageChangeListener"

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

Каждый Fragment в ViewPager будет иметь такой макет:

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_view" android:layout_height="match_parent" android:layout_width="match_parent" android:scaleType="center" /> <LinearLayout android:id="@+id/content_area" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- content goes here --> </LinearLayout> </FrameLayout> 

И вы создадите PageTransformer который манипулирует макетом в зависимости от позиции, которую он провел:

 public class CustomPageTransformer implements ViewPager.PageTransformer { public void transformPage(View view, float position) { int pageWidth = view.getWidth(); View imageView = view.findViewById(R.id.image_view); View contentView = view.findViewById(R.id.content_area); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left } else if (position <= 0) { // [-1,0] // This page is moving out to the left // Counteract the default swipe view.setTranslationX(pageWidth * -position); if (contentView != null) { // But swipe the contentView contentView.setTranslationX(pageWidth * position); } if (imageView != null) { // Fade the image in imageView.setAlpha(1 + position); } } else if (position <= 1) { // (0,1] // This page is moving in from the right // Counteract the default swipe view.setTranslationX(pageWidth * -position); if (contentView != null) { // But swipe the contentView contentView.setTranslationX(pageWidth * position); } if (imageView != null) { // Fade the image out imageView.setAlpha(1 - position); } } else { // (1,+Infinity] // This page is way off-screen to the right } } } 

И, наконец, подключите этот PageTransformer до вашего ViewPager :

 mViewPager.setPageTransformer(true, new CustomPageTransformer()); 

Я тестировал его в существующем приложении, и он работает хорошо, пока макеты фрагментов имеют прозрачный фон.