Вертикальный смахивающий ViewPager со стеком карт - PullRequest
0 голосов
/ 03 июня 2019

Мне нужно реализовать вертикальный просмотрщик со стеком, как приложение Shazam. Я добиваюсь этого горизонтально, но не вертикально. Пожалуйста, помогите мне.Заранее спасибо.

Установить класс PageTransformer в Viewpager

viewPager.setPageTransformer(true,
CardStackLeftTransformer(view.context)) 

Класс PageTransformer

 class CardStackLeftTransformer(private val mContext: Context) : 
 ViewPager.PageTransformer {
 var mStackedScaleFactor: Float = 0.toFloat()
 var mShiftPixels: Float = 0.toFloat()

 init {
    init()
 }

 private fun init() {
    mStackedScaleFactor = 0.02f//(CURRENT_PAGE_SCALE - 
 TOP_STACKED_SCALE) / NUMBER_OF_VISIBLE_STACKCARDS;;// 0.02f;
    mShiftPixels = 
 30f//TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) 
 12, mContext.getResources().getDisplayMetrics());
 }

 override fun transformPage(view: View, position: Float) {
    val width = getWidth(view)

    /**
     * Scale all the pages from 0 to n
     */
    scaleAllPages(view, position)

    /**
     * Apply translation on X axis for shifting the cards and make 
    them a stack
     * Apply translation on Y axis for shifting the cards so that it 
     gives a hint of depth
     */
    if (position > 0) {
        view.translationX = -position * width

        view.translationY = position * mShiftPixels // shift the page 
       up with 30 pixels

    } else if (position == -1f)
    // Once the page goes to the left side
    {
        // translate x so that we can see the margin of the page as a 
        hint : 14 percent of the page
        view.translationX = width - width * TRANSLATE_X_FACTOR

        val scale = CURRENT_PAGE_SCALE + position * 
        mStackedScaleFactor

        view.scaleX = scale

        view.scaleY = scale

    } else if (position < 0 && position > -1) {
        val scale = CURRENT_PAGE_SCALE + position * 
        mStackedScaleFactor
        // apply translation x as 0 to display it on the screen
        view.translationX = 0f

        view.scaleX = scale

        view.scaleY = scale
    }
    /**
     * Apply translation when the page is translated from left to 
       right
     */
    /**
     * Apply translation on the page to show the hint of next page
     * 14 percent of the page translation
     */

    // We do not want to show all the cards in the stack
    // Show only 2 cards below the main visible card
    showOnlyFewCardsAndHideOthers(view, position, 
    NUMBER_OF_VISIBLE_STACKCARDS - 1)

}

/**
 * Scales all pages from position 0 to n (only pages with position 
   >=0)
 * Scale on X and Scale on Y will depend on the position of the card
 *
 * @param page
 * @param position
 */
private fun scaleAllPages(page: View, position: Float) {
    if (position >= 0) {
        val scale = CURRENT_PAGE_SCALE - position * 
        mStackedScaleFactor

        page.scaleX = scale

        page.scaleY = scale
    }
   }

/*
this method will be used for showing limited number of cards at a time 
in the stack
The number of cards shown will be determined by parameter - int number
 */
private fun showOnlyFewCardsAndHideOthers(page: View, position: Float, 
number: Int) {
    // handling alpha
    if (position > number) {
        page.alpha = 0f
    } else {
        page.alpha = 1f
    }
}

protected fun getWidth(page: View): Int {
    return page.width
}

companion object {
    private val NUMBER_OF_VISIBLE_STACKCARDS = 5
    val CURRENT_PAGE_SCALE = 0.91f
    val TRANSLATE_X_FACTOR = .90f
}

}

Если вы хотите получить полный код, просто скачайте отсюда: https://github.com/chethu/Stack-of-cards

enter image description here

enter image description here

1 Ответ

0 голосов
/ 03 июня 2019

Используйте этот настраиваемый и простой в использовании стек с возможностью просмотра.

dependencies {
    compile 'link.fls:swipestack:0.3.0'
}

Используйте этот xml в макете своих адаптеров

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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:clipChildren="false">

    <link.fls.swipestack.SwipeStack
        android:id="@+id/swipeStack"
        android:layout_width="320dp"
        android:layout_height="240dp"
        android:padding="32dp"/>

</FrameLayout>

Создайте адаптер, который содержит данные и создает представления для стека.

public class SwipeStackAdapter extends BaseAdapter {

    private List<String> mData;

    public SwipeStackAdapter(List<String> data) {
        this.mData = data;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public String getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        convertView = getLayoutInflater().inflate(R.layout.card, parent, false);
        TextView textViewCard = (TextView) convertView.findViewById(R.id.textViewCard);
        textViewCard.setText(mData.get(position));

        return convertView;
    }
}

Пример

SwipeStack swipeStack = (SwipeStack) findViewById(R.id.swipeStack);
swipeStack.setAdapter(new SwipeStackAdapter(mData));

Attibute ссылка с https://github.com/flschweiger/SwipeStack

...