Skip to content
Snippets Groups Projects
Select Git revision
  • c61e5444d44413f019aa10c5acf0d8cacbd08f9e
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • release/201811
  • release/201808
  • wip/patches_poly_2017/cedryk_doucet/abderahmane_bouziane
  • releases/beta1
  • android/release_464
  • android/release_463
  • android/release_462
  • android/release_461
  • android/release_460
  • android/release_459
  • android/release_458
  • android/release_457
  • android/release_456
  • android/release_455
  • android/release_454
  • android/release_453
  • android/release_452
  • android/release_451
  • android/release_450
  • android/release_449
  • android/release_448
  • android/release_447
  • android/release_446
  • android/release_445
38 results

ServiceEvent.java

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ParallaxScrollView.java 12.10 KiB
    package org.sflphone.views.parallaxscrollview;
    
    import org.sflphone.R;
    import org.sflphone.views.parallaxscrollview.ObservableScrollView.ScrollCallbacks;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.ScrollView;
    
    /**
     * A custom ScrollView that can accept a scroll listener.
     */
    public class ParallaxScrollView extends ViewGroup
    {
        private static final int DEFAULT_CHILD_GRAVITY = Gravity.CENTER_HORIZONTAL;
    
        private static final String TAG = "ParallaxScrollView";
    
        private static float PARALLAX_OFFSET_DEFAULT = 0.2f;
    
        /**
         * By how much should the background move to the foreground
         */
        private float mParallaxOffset = PARALLAX_OFFSET_DEFAULT;
    
        private View mBackground;
        private ObservableScrollView mScrollView;
        private final ScrollCallbacks mScrollCallbacks = new ScrollCallbacks()
        {
            @Override
            public void onScrollChanged(int l, int t, int oldl, int oldt)
            {
                requestLayout();
            }
        };
    
        // Layout stuff
    
        private int mBackgroundRight;
        private int mBackgroundBottom;
        /**
         * Height of the Foreground ScrollView Content
         */
        private int mScrollContentHeight = 0;
        /**
         * Height of the ScrollView, should be the same as this view
         */
        private int mScrollViewHeight = 0;
        /**
         * The multipler by how much to move the background to the foreground
         */
        private float mScrollDiff = 0f;
    
        public ParallaxScrollView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
    
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                    R.styleable.ParallaxScrollView, 0, 0);
    
            try
            {
                setParallaxOffset(a.getFloat(R.styleable.ParallaxScrollView_parallexOffset,
                        PARALLAX_OFFSET_DEFAULT));
            }
            catch (Exception e)
            {
            }
            finally
            {
                a.recycle();
            }
        }
    
        public ParallaxScrollView(Context context, AttributeSet attrs)
        {
            this(context, attrs, 0);
        }
    
        public ParallaxScrollView(Context context)
        {
            this(context, null);
        }
    
        @Override
        public void addView(View child)
        {
            if (getChildCount() > 1)
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
    
            super.addView(child);
        }
    
        @Override
        public void addView(View child, int index)
        {
            if (getChildCount() > 1)
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            super.addView(child, index);
        }
    
        @Override
        public void addView(View child, int index, android.view.ViewGroup.LayoutParams params)
        {
            if (getChildCount() > 1)
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            super.addView(child, index, params);
        }
    
        @Override
        public void addView(View child, int width, int height)
        {
            if (getChildCount() > 1)
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            super.addView(child, width, height);
        }
    
        @Override
        public void addView(View child, android.view.ViewGroup.LayoutParams params)
        {
            if (getChildCount() > 1)
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            super.addView(child, params);
        }
    
        /**
         * Set the offset
         * 
         * @param offset
         *            a number greater than 0.0
         */
        public void setParallaxOffset(float offset)
        {
            // Make sure we only get to .05 of a floating number
            offset = (float) Math.rint(offset * 100) / 100;
            if (offset > 0.0)
                mParallaxOffset = offset;
            else
                mParallaxOffset = PARALLAX_OFFSET_DEFAULT;
    
            requestLayout();
        }
    
        /**
         * Get the current offset
         * 
         * @return
         */
        public float getParallaxOffset()
        {
            return mParallaxOffset;
        }
    
        /**
         * Sort the views out after they have been inflated from a layout
         */
        @Override
        protected void onFinishInflate()
        {
            super.onFinishInflate();
    
            if (getChildCount() > 2)
            {
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            }
            organiseViews();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            if (mScrollView != null)
            {
                measureChild(mScrollView, MeasureSpec.makeMeasureSpec(
                        MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
                                MeasureSpec.AT_MOST));
    
                mScrollContentHeight = mScrollView.getChildAt(0).getMeasuredHeight();
                mScrollViewHeight = mScrollView.getMeasuredHeight();
    
            }
            if (mBackground != null)
            {
                int minHeight = 0;
                minHeight = (int) (mScrollViewHeight + mParallaxOffset
                        * (mScrollContentHeight - mScrollViewHeight));
                minHeight = Math.max(minHeight, MeasureSpec.getSize(heightMeasureSpec));
    
                measureChild(mBackground, MeasureSpec.makeMeasureSpec(
                        MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(minHeight, MeasureSpec.EXACTLY));
    
                mBackgroundRight = getLeft() + mBackground.getMeasuredWidth();
                mBackgroundBottom = getTop() + mBackground.getMeasuredHeight();
    
                mScrollDiff = (float) (mBackground.getMeasuredHeight() - mScrollViewHeight)
                        / (float) (mScrollContentHeight - mScrollViewHeight);
            }
    
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom)
        {
            final int parentLeft = getPaddingLeft();
            final int parentRight = right - left - getPaddingRight();
            final int parentTop = getPaddingTop();
            final int parentBottom = bottom - top - getPaddingBottom();
            if (mScrollView != null && mScrollView.getVisibility() != GONE)
            {
                final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mScrollView
                        .getLayoutParams();
    
                final int width = mScrollView.getMeasuredWidth();
                final int height = mScrollView.getMeasuredHeight();
    
                int childLeft;
                int childTop;
    
                int gravity = lp.gravity;
                if (gravity == -1)
                {
                    gravity = DEFAULT_CHILD_GRAVITY;
                }
    
                final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
    
                switch (horizontalGravity)
                {
                    case Gravity.LEFT:
                        childLeft = parentLeft + lp.leftMargin;
                        break;
                    case Gravity.CENTER_HORIZONTAL:
                        childLeft = parentLeft + (parentRight - parentLeft - width) / 2 + lp.leftMargin
                                - lp.rightMargin;
                        break;
                    case Gravity.RIGHT:
                        childLeft = parentRight - width - lp.rightMargin;
                        break;
                    default:
                        childLeft = parentLeft + lp.leftMargin;
                }
    
                switch (verticalGravity)
                {
                    case Gravity.TOP:
                        childTop = parentTop + lp.topMargin;
                        break;
                    case Gravity.CENTER_VERTICAL:
                        childTop = parentTop + (parentBottom - parentTop - height) / 2 + lp.topMargin
                                - lp.bottomMargin;
                        break;
                    case Gravity.BOTTOM:
                        childTop = parentBottom - height - lp.bottomMargin;
                        break;
                    default:
                        childTop = parentTop + lp.topMargin;
                }
    
                mScrollView.layout(childLeft, childTop, childLeft + width, childTop + height);
    
            }
    
            if (mBackground != null)
            {
                final int scrollYCenterOffset = mScrollView.getScrollY();
                final int offset = (int) (scrollYCenterOffset * mScrollDiff);
                // Log.d(TAG, "Layout Scroll Y: " + scrollYCenterOffset +
                // " ScrollDiff: " + mScrollDiff
                // + " Background Offset:" + offset);
                mBackground.layout(getLeft(), offset, mBackgroundRight, offset + mBackgroundBottom);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public LayoutParams generateLayoutParams(AttributeSet attrs)
        {
            return new FrameLayout.LayoutParams(getContext(), attrs);
        }
    
        @Override
        protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p)
        {
            return new FrameLayout.LayoutParams(p);
        }
    
        @Override
        protected LayoutParams generateDefaultLayoutParams()
        {
            return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                    Gravity.CENTER_HORIZONTAL);
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        protected boolean checkLayoutParams(ViewGroup.LayoutParams p)
        {
            return p instanceof FrameLayout.LayoutParams;
        }
    
        /**
         * Take the direct children and sort them
         */
        private void organiseViews()
        {
            if (getChildCount() <= 0) return;
    
            if (getChildCount() == 1)
            {
                // Get the only child
                final View forground = getChildAt(0);
                organiseBackgroundView(null);
                organiseForgroundView(forground);
            }
            else if (getChildCount() == 2)
            {
                final View background = getChildAt(0);
                final View foreground = getChildAt(1);
    
                organiseBackgroundView(background);
                organiseForgroundView(foreground);
            }
            else
            {
                throw new IllegalStateException("ParallaxScrollView can host only two direct children");
            }
        }
    
        private void organiseBackgroundView(final View background)
        {
            mBackground = background;
        }
    
        private void organiseForgroundView(final View forground)
        {
            final int insertPos = getChildCount() - 1;
    
            // See if its a observable scroll view?
            if (forground instanceof ObservableScrollView)
            {
                // Attach the callback to it.
                mScrollView = (ObservableScrollView) forground;
            }
            else if (forground instanceof ViewGroup && !(forground instanceof ScrollView))
            {
                // See if it is a view group but not a scroll view and wrap it
                // with an observable ScrollView
                mScrollView = new ObservableScrollView(getContext(), null);
                removeView(forground);
                mScrollView.addView(forground);
                addView(mScrollView, insertPos);
            }
            else if (forground instanceof ScrollView)
            {
                final View child;
                if (((ScrollView) forground).getChildCount() > 0)
                    child = ((ScrollView) forground).getChildAt(0);
                else
                    child = null;
    
                mScrollView = new ObservableScrollView(getContext(), null);
                removeView(forground);
                if (child != null) mScrollView.addView(child);
                addView(mScrollView, insertPos);
            }
            else if (forground instanceof View)
            {
                mScrollView = new ObservableScrollView(getContext(), null);
                removeView(forground);
                mScrollView.addView(forground);
                addView(mScrollView, insertPos);
    
            }
            if (mScrollView != null)
            {
                mScrollView.setLayoutParams(forground.getLayoutParams());
                mScrollView.setCallbacks(mScrollCallbacks);
                mScrollView.setFillViewport(true);
            }
        }
    
    }