yarolegovich / DiscreteScrollView

A scrollable list of items that centers the current element and provides easy-to-use APIs for cool item animations.
5.78k stars 783 forks source link

Show Semi image item on the LEFT and RIGHT side. #140

Open ronakmob opened 6 years ago

ronakmob commented 6 years ago

Hi,

I appreciate for the wonderful library. But I couldn't find a way to show semi item images for the LEFT and RIGHT items and center should remain same (Full View).

I would be thankful for the guidance.

Thank you,

LorenzoDD96 commented 5 years ago

i have the same problem, i've choice this library for carousel and i can't do this?

pwillmann commented 5 years ago

Like this?

gallery_transformer

This transformer should do:

class GalleryTransformer : DiscreteScrollItemTransformer {

    private var pivotX: Pivot? = null
    private var pivotY: Pivot? = null

    private var minScale: Float = 0.toFloat()
    private var maxMinDiffScale: Float = 0.toFloat()

    private var minAlpha: Float = 0.toFloat()
    private var maxMinDiffAlpha: Float = 0.toFloat()

    private var maxElevation: Float = -1f
    private var minElevation: Float = -1f

    private var overlapDistance: Float = 0.toFloat()
    private var interpolator: Interpolator = AccelerateInterpolator(1.2f)

    init {
        pivotX = Pivot.X.CENTER.create()
        pivotY = Pivot.Y.CENTER.create()
        minScale = 0.8f
        maxMinDiffScale = 1f - minScale
        minAlpha = 0.6f
        maxMinDiffAlpha = 1f - minAlpha

    }

    override fun transformItem(item: View, position: Float) {
        pivotX!!.setOn(item)
        pivotY!!.setOn(item)
        val closenessToCenter = 1f - Math.abs(position)
        val scale = minScale + maxMinDiffScale * closenessToCenter
        val alpha = minAlpha + maxMinDiffAlpha * closenessToCenter
        item.scaleX = scale
        item.scaleY = scale
        item.alpha = alpha

        if (overlapDistance > 0) {
            item.translationX = getTranslationForOverlapping(item, position)
        }

        val elevation = minElevation + maxElevation * closenessToCenter
        if (elevation >= 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            item.elevation = elevation
        }
    }

    private fun getTranslationForOverlapping(item: View, position: Float): Float {
        val maxTranslation = getMaxTranslation(item)
        val interpolatedPosition = interpolator.getInterpolation(Math.abs(position))
        val translation = maxTranslation * interpolatedPosition

        return translation * getTranslationDirection(position)
    }

    private fun getMaxTranslation(item: View): Float {
        val gapBetweenItems = (item.layoutParams as ViewGroup.MarginLayoutParams).leftMargin + (item.layoutParams as ViewGroup.MarginLayoutParams).rightMargin
        val widthDiffBetweenMinAndMaxScale = item.width * maxMinDiffScale
        return gapBetweenItems + widthDiffBetweenMinAndMaxScale + overlapDistance
    }

    /**
     * Views left of the Centered Item have a negative position but must be translated to the right (positive translation),
     * Views right of the center Item have a position position and must be translated to the left (negative translation)
     */
    private fun getTranslationDirection(position: Float): Float {
        return sign(position) * -1f
    }

    class Builder {

        private val transformer: GalleryTransformer = GalleryTransformer()
        private var maxScale: Float = 0.toFloat()

        init {
            maxScale = 1f
        }

        fun setMinScale(scale: Float): Builder {
            transformer.minScale = scale
            return this
        }

        fun setMaxScale(scale: Float): Builder {
            maxScale = scale
            return this
        }

        fun setPivotX(pivotX: Pivot.X): Builder {
            return setPivotX(pivotX.create())
        }

        fun setPivotX(pivot: Pivot): Builder {
            assertAxis(pivot, Pivot.AXIS_X)
            transformer.pivotX = pivot
            return this
        }

        fun setPivotY(pivotY: Pivot.Y): Builder {
            return setPivotY(pivotY.create())
        }

        fun setPivotY(pivot: Pivot): Builder {
            assertAxis(pivot, Pivot.AXIS_Y)
            transformer.pivotY = pivot
            return this
        }

        fun setOverlapDistance(@Px distance: Int): Builder {
            transformer.overlapDistance = distance.toFloat()
            return this
        }

        fun setElevation(@Px maxElevation: Int, @Px minElevation: Int): Builder {
            transformer.maxElevation = maxElevation.toFloat()
            transformer.minElevation = minElevation.toFloat()
            return this
        }

        fun setElevation(@Px maxElevation: Int): Builder {
            transformer.maxElevation = maxElevation.toFloat()
            transformer.minElevation = 0.toFloat()
            return this
        }

        fun build(): GalleryTransformer {
            transformer.maxMinDiffScale = maxScale - transformer.minScale
            return transformer
        }

        private fun assertAxis(pivot: Pivot, @Pivot.Axis axis: Int) {
            if (pivot.axis != axis) {
                throw IllegalArgumentException("You passed a Pivot for wrong axis.")
            }
        }
    }
}

Shown configuration for the sample app is this one:

 itemPicker.setItemTransformer(new GalleryTransformer.Builder()
                .setMinScale(0.85f)
                .setElevation(dpToPx(10), dpToPx(4))
                .setOverlapDistance(dpToPx(8))
                .build());
walid-ashik commented 5 years ago

if you want to set a semi item visible in left and right side then do what @pwillmann mentioned above and just add .setOverlapDistance(0) if you want to show a side of imageview. view.setItemTransformer(new GalleryTransformer.Builder() .setMinScale(0.85f) .setElevation(dpToPx(10), dpToPx(4)) .setOverlapDistance(0) .build());

pontachandazo commented 5 years ago

In addition to...if the width of scrolled itemview is too big, that's not working !! Be Care!!