Android - ViewPager Animation (стопка бумаги) - PullRequest
0 голосов
/ 29 июня 2018

У меня есть некоторые элементы для отображения, в настоящее время я использую просмотр списка с анимацией прокрутки. Но я хочу сделать ту же анимацию панели «Shazam Discover», я не знаю, нужно ли мне использовать ListView или другой виджет ... Любая идея ? Заранее спасибо ! Here is the animation

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Спасибо за эти две ссылки,

Я решил собственную проблему :), поэтому я выложу здесь решение

Чтобы воспроизвести ту же анимацию, описанную выше (например, стопку бумаги), я наконец-то использовал вертикальный видовой пейджер с анимацией PageTransformer

Итак, у меня есть:

  • ViewPager : содержит элементы для отображения
  • PagerAdapter : адаптер, который создает экземпляры каждого элемента
  • PageTransformer : анимация слайдов
  • A Фрагмент : содержит ViewPager

Анимация стопки бумаги

Первая трудность здесь состояла в том, чтобы создать анимацию стека бумаги, то есть сложить старые элементы позади текущего ... создать порядок "z-index" между каждым элементом, иначе старый элемент будет находиться спереди и ток сзади. (Имею ли я смысл?: P)

Поэтому я решил добавить к каждому представлению ViewPager тег со значением его положения в качестве значения и использовать его в PageTransformer для определения translationZ представления , Итак, первое представление элемента ViewPager , поэтому position = 0, имеет z-index = 0, второе z-index = 1 ... и, таким образом, создает стопку бумаги !!

Правильное «Уничтожение»

Вторая трудность заключалась в том, чтобы скрыть и показать предыдущий элемент в идеальный момент ... потому что по умолчанию ViewPager просто показывает 2 представления и вызывает destroyItem, когда загружается третий. Итак, мы видим уничтожение последнего представления ... в видео моего первого сообщения мы видим, что последнее представление удаляется, когда текущее представление проходит перед другими, так как это сделать?

Я решил создать ArrayList<View> в моем PagerAdapter и добавлять каждое представление при вызове функции instantiateItem. Я также создал Getter для получения ArrayList из моего Fragment . В моем Framgment я добавил addOnPageChangeListener в мой ViewPager . С помощью этого слушателя я могу определить, какой вид моего ViewPager отображается (с позицией и списком представлений ArrayList) и positionOffset, с помощью этих двух переменных я могу скрыть или показать предыдущие представления в идеальный момент. .

Код

Я уточнил свой код ниже, чтобы сделать общий

Фрагмент

public class MyFragment extends Fragment {

private ViewPager viewPager;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment, container, false);

    viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);

    final MyPagerAdapter pagerAdapter = new MyPagerAdapter(getActivity());
    viewPager.setAdapter(pagerAdapter);
    viewPager.setPageTransformer(true, new PaperStackTransformer());
    viewPager.setRotation(90); // Vertical viewpager
    viewPager.setOffscreenPageLimit(10); // To display more than 2 view (and 10 to avoid bugs...)

    final ArrayList<View> views = MyPagerAdapter.getViews();

    final float[] previousPositionOffset = new float[1];
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if (positionOffset > 0.9 || positionOffset < 0.1) return;

            float dif = previousPositionOffset[0] - positionOffset;

            // Change values (0.40 and 0.70) to conform to your PageViewer view
            if (positionOffset > 0.40 && positionOffset < 0.70 ){
                // at this moment current view hide the previous
                if (dif < 0) {
                    // If we scroll down we hide the previous view
                    int p = position - 2;
                    if (p >= 0 && views.get(p).getVisibility() == View.VISIBLE) {
                        views.get(p).setVisibility(View.INVISIBLE);
                    }
                }
                else if (dif > 0) {
                    // If we scroll up we show the previous view
                    int p = position - 2;
                    if (p >= 0 && views.get(p).getVisibility() == View.INVISIBLE) {
                        views.get(p).setVisibility(View.VISIBLE);
                    }
                }
            }
           previousPositionOffset[0] = positionOffset;
        }

        @Override
        public void onPageSelected(int position) {
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

    return rootView;
}

}

PagerAdapter

public class MyPagerAdapter extends PagerAdapter {

private ArrayList<View> views;

...

public ArrayList<View> getViews() {
    return views;
}

...

@Override
public Object instantiateItem(ViewGroup container, int position) {

    ...

    View view = inflater.inflate(R.layout.view, null, false);

    ...

    view.setTag(position); // To the "z-index" order on PageTransformer
    view.setRotation(-90f); // Vertical ViewPager
    ((ViewPager) container).addView(view); 

    views.add(view); // add the view to the list
    return view;
}

...

}

PageTransformer

public class PaperStackTransformer implements ViewPager.PageTransformer {

private static final float MIN_SCALE = 0.9f;

public void transformPage(View view, float position) {

    if (position < -1) { // [-Infinity,-1)
        view.setTranslationX(1150 * -position);

        float scaleFactor = MIN_SCALE
                + (1 - MIN_SCALE) * (1 - Math.abs(position));
        view.setScaleX(scaleFactor);
        view.setScaleY(scaleFactor);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) view.setTranslationZ((int) view.getTag()*1.0f);

    } else if (position <= 0) { // [-1,0]
        view.setAlpha(1 - position);

        view.setTranslationX(1150 * -position);

        float scaleFactor = MIN_SCALE
                + (1 - MIN_SCALE) * (1 - Math.abs(position));
        view.setScaleX(scaleFactor);
        view.setScaleY(scaleFactor);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) view.setTranslationZ((int) view.getTag()*1.0f);

    } else if (position <= 1) { // (0,1]
        view.setAlpha(1);
        view.setTranslationX(1);
        view.setScaleX(1);
        view.setScaleY(1);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) view.setTranslationZ((int) view.getTag()*1.0f);

    } else { // (1,+Infinity]
        view.setAlpha(1);
    }
}

}

Заключение

Так что просмотр списка не был решением, я надеюсь, что этот фрагмент поможет некоторым людям. анимация моей стопки бумаги: D

0 голосов
/ 29 июня 2018

Я нашел два места, где можно найти хорошие вещи.

  1. Github Лучший пользовательский интерфейс

  2. Кампоша Все, что нужно для хорошего пользовательского интерфейса

Надеюсь, что эти двое помогут вам;)

...