[mono-android] How to implement ViewPager from compatibility package .jar

Stuart Lodge me at slodge.com
Sun Feb 12 16:15:36 UTC 2012


My latest code actually looks a lot like that  - its easy enough to just
play with the code inside Draw to achieve what you want.

Hope that helps

Stuart

// original credit to: //
https://github.com/brucejcooper/Android-Examples/blob/master/PagingScrollerExample/src/com/eightbitcloud/pagingscroller/PageIndicator.java

    public class HorizontalPagerIndicator : View
    {
        private HorizontalPager _pager;
        private Paint _textPaint;
        private Paint _inactiveDotPaint;
        private Paint _dotPaint;
        private Paint _dotBackgroundPaint;
        private int _textHeight;
        private int _ascent;
        private int _cellSize;
        private float _displayDensity;

        public HorizontalPagerIndicator(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            InitPaints(context);
        }


        public HorizontalPagerIndicator(Context context)
            : base(context)
        {
            InitPaints(context);
        }

        private void InitPaints(Context context)
        {
            _displayDensity = context.Resources.DisplayMetrics.Density;

            _textPaint = new Paint {AntiAlias = true, TextSize =
DeviceIndependentToPixels(14), Color = Color.Black};

            _inactiveDotPaint = new Paint { AntiAlias = true, Color =
Color.Gray };
            _dotPaint = new Paint {AntiAlias = true, Color = Color.White};
            _dotBackgroundPaint = new Paint { AntiAlias = true, Color
= Color.Cyan };

            _ascent = -(int)_textPaint.Ascent();
            _textHeight = (int)(_ascent + _textPaint.Descent());
            _cellSize = DeviceIndependentToPixels(_textHeight + 6);
        }


        public HorizontalPager Pager
        {
            get { return _pager; }
            set
            {

                if (_pager != null)
                {
                    _pager.ScreenChanged -= PagerOnScreenChanged;
                }
                _pager = value;
                if (_pager != null)
                {
                    _pager.ScreenChanged += PagerOnScreenChanged;
                }
                UpdatePageCount();
            }
        }

        private void PagerOnScreenChanged(object sender, EventArgs eventArgs)
        {
            Invalidate();
        }

        public void UpdatePageCount()
        {
            RequestLayout();
            Invalidate();
        }

        private int NumPages
        {
            get
            {
                return _pager == null ? 1 : _pager.ChildCount;
            }
        }

        private int ActivePage
        {
            get
            {
                return _pager == null ? 0 : _pager.CurrentScreen;
            }
        }

        protected override void OnMeasure(int widthMeasureSpec, int
heightMeasureSpec)
        {
            SetMeasuredDimension(MeasureWidth(widthMeasureSpec),
MeasureHeight(heightMeasureSpec));
        }

        private int MeasureWidth(int measureSpec)
        {
            var result = 0;
            var specMode = MeasureSpec.GetMode(measureSpec);
            var specSize = MeasureSpec.GetSize(measureSpec);

            if (specMode == MeasureSpecMode.Exactly)
            {
                // We were told how big to be
                result = specSize;
            }
            else
            {
                result = NumPages * _cellSize;
                if (specMode == MeasureSpecMode.AtMost)
                {
                    // Respect AT_MOST value if that was what is called for by
                    // measureSpec
                    result = Math.Min(result, specSize);
                }
            }
            return result;
        }

        private int MeasureHeight(int measureSpec)
        {
            var result = 0;
            var specMode = MeasureSpec.GetMode(measureSpec);
            var specSize = MeasureSpec.GetSize(measureSpec);


            if (specMode == MeasureSpecMode.Exactly)
            {
                // We were told how big to be
                result = specSize;
            }
            else
            {
                result = _cellSize;
                if (specMode == MeasureSpecMode.AtMost)
                {
                    // Respect AT_MOST value if that was what is called for by
                    // measureSpec
                    result = Math.Min(result, specSize);
                }
            }
            return result;
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);

            var numPages = NumPages;
            var activePageIndex = ActivePage;

            var x = (canvas.Width - numPages * _cellSize)/2;

            //var smallBorder = _cellSize/4;
            //var slightlySmallerBorder = smallBorder - 1;
            var emptyDotSize = _cellSize/4;
            var dotOffset = (_cellSize - emptyDotSize) / 2;
            for (var i = 0; i < numPages; i++, x += _cellSize)
            {
                if (i == activePageIndex)
                {
                    //var txt = (i +
1).ToString(System.Globalization.CultureInfo.CurrentUICulture);
                    //var bounds = new Rect();
                    //_textPaint.GetTextBounds(txt, 0, txt.Length, bounds);
                    //var oval = new RectF(x + smallBorder,
smallBorder, x + _cellSize - smallBorder, _cellSize - smallBorder);
                    var oval = new RectF(x + dotOffset, dotOffset, x +
dotOffset + emptyDotSize, dotOffset + emptyDotSize);
                    var oval1 = new RectF(x + dotOffset - 1, dotOffset
- 1, x + dotOffset + emptyDotSize + 1, dotOffset + emptyDotSize + 1);
                    canvas.DrawOval(oval1, _dotBackgroundPaint);
                    canvas.DrawOval(oval, _dotPaint);
                    //canvas.DrawText(txt, x + (_cellSize -
bounds.Width()) / 2, (_cellSize - _textHeight) / 2 + _ascent,
_textPaint);
                }
                else
                {
                    var oval = new RectF(x + dotOffset, dotOffset, x +
dotOffset + emptyDotSize, dotOffset + emptyDotSize);
                    canvas.DrawOval(oval, _inactiveDotPaint);
                }
            }
        }

        private int DeviceIndependentToPixels(int dpi)
        {
            return (int)Math.Round((float)dpi * _displayDensity);
        }
    }




2012/2/12 Gerry High <ghigh at hightg.com>

> Stuart,
>
> Have you made any more changes to this code?  Also, do you have a photo of
> how this looks?  I'm thinking of adding a pager control to my app--I use a
> UIPagerController in my iPhone version and am looking for something like
> the UIPagerControl (
> http://books.google.com/books?id=lFe0EwHUREEC&pg=PA125&lpg=PA125&dq=uipagercontrol&source=bl&ots=-SNjmXH5Z3&sig=Aa0tUicP1yWkcJ0cA8i8STg6_3w&hl=en&sa=X&ei=2yA3T8WzA8mEsALg-fSiAg&ved=0CC8Q6AEwAg#v=onepage&q=uipagercontrol&f=false
> )
>
> Thanks,
> Gerry
>
>
> *
> *
>
> On Feb 4, 2012, at 2:33 PM, Stuart Lodge wrote:
>
> If it helps I've also just ported a Page Indicator from the Java sample on
> this blog:
> http://buildmobile.com/how-to-build-an-android-pager-component/#fbid=TnZmgHdBfhF (license
> unclear?)
>
> Still some sizing issues to sort out - and it would be nice to make it
> more "animated" - but it basically works
>
> Stuart
>
> using System;using Android.Content;using Android.Graphics;using Android.Util;using Android.Views;
>  namespace SocialStorm.Android.Controls
> {
>     public class HorizontalPagerIndicator : View
>     {
>         private HorizontalPager _pager;
>         private Paint _textPaint;
>         private Paint _dotPaint;
>         private int _textHeight;
>         private int _ascent;
>         private int _cellSize;
>
>         public HorizontalPagerIndicator(Context context, IAttributeSet attrs)
>             : base(context, attrs)
>         {
>             InitPaints();
>         }
>
>
>         public HorizontalPagerIndicator(Context context)
>             : base(context)
>         {
>             InitPaints();
>         }
>
>         private void InitPaints()
>         {
>             _textPaint = new Paint {AntiAlias = true, TextSize = 10, Color = Color.Black};
>
>             _dotPaint = new Paint {AntiAlias = true, Color = Color.Gray};
>
>             _ascent = -(int)_textPaint.Ascent();
>             _textHeight = (int)(_ascent + _textPaint.Descent());
>             _cellSize = _textHeight + 6;
>         }
>
>
>         public HorizontalPager Pager
>         {
>             get { return _pager; }
>             set
>             {
>
>                 if (_pager != null)
>                 {
>                     _pager.ScreenChanged -= PagerOnScreenChanged;
>                 }
>                 _pager = value;
>                 if (_pager != null)
>                 {
>                     _pager.ScreenChanged += PagerOnScreenChanged;
>                 }
>                 UpdatePageCount();
>             }
>         }
>
>         private void PagerOnScreenChanged(object sender, EventArgs eventArgs)
>         {
>             Invalidate();
>         }
>
>         public void UpdatePageCount()
>         {
>             RequestLayout();
>             Invalidate();
>         }
>
>         private int NumPages
>         {
>             get
>             {
>                 return _pager == null ? 1 : _pager.ChildCount;
>             }
>         }
>
>         private int ActivePage
>         {
>             get
>             {
>                 return _pager == null ? 0 : _pager.CurrentScreen;
>             }
>         }
>
>
>         protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
>         {
>             SetMeasuredDimension(MeasureWidth(widthMeasureSpec), MeasureHeight(heightMeasureSpec));
>         }
>
>         private int MeasureWidth(int measureSpec)
>         {
>             var result = 0;
>             var specMode = MeasureSpec.GetMode(measureSpec);
>             var specSize = MeasureSpec.GetSize(measureSpec);
>
>             if (specMode == MeasureSpecMode.Exactly)
>             {
>                 // We were told how big to be
>                 result = specSize;
>             }
>             else
>             {
>                 result = NumPages * _cellSize;
>                 if (specMode == MeasureSpecMode.AtMost)
>                 {
>                     // Respect AT_MOST value if that was what is called for by
>                     // measureSpec
>                     result = Math.Min(result, specSize);
>                 }
>             }
>             return result;
>         }
>
>         private int MeasureHeight(int measureSpec)
>         {
>             var result = 0;
>             var specMode = MeasureSpec.GetMode(measureSpec);
>             var specSize = MeasureSpec.GetSize(measureSpec);
>
>
>             if (specMode == MeasureSpecMode.Exactly)
>             {
>                 // We were told how big to be
>                 result = specSize;
>             }
>             else
>             {
>                 result = _cellSize;
>                 if (specMode == MeasureSpecMode.AtMost)
>                 {
>                     // Respect AT_MOST value if that was what is called for by
>                     // measureSpec
>                     result = Math.Min(result, specSize);
>                 }
>             }
>             return result;
>         }
>
>         protected override void OnDraw(Canvas canvas)
>         {
>             base.OnDraw(canvas);
>
>             var count = NumPages;
>             var current = ActivePage;
>
>             int x = 0;
>             for (int i = 0; i < count; i++, x += _cellSize)
>             {
>                 if (i == current)
>                 {
>                     String txt = (i + 1).ToString();
>                     var bounds = new Rect();
>                     _textPaint.GetTextBounds(txt, 0, txt.Length, bounds);
>                     var oval = new RectF(x + 1, 1, x + _cellSize - 2, _cellSize - 2);
>                     canvas.DrawOval(oval, _dotPaint);
>                     canvas.DrawText(txt, x + (_cellSize - bounds.Width()) / 2, (_cellSize - _textHeight) / 2 + _ascent, _textPaint);
>                 }
>                 else
>                 {
>                     const int dotSize = 5;
>                     var dotOffset = (_cellSize - dotSize) / 2;
>                     var oval = new RectF(x + dotOffset, dotOffset, x + dotOffset + dotSize, dotOffset + dotSize);
>                     canvas.DrawOval(oval, _dotPaint);
>                 }
>             }
>         }
>
>     }
> }
>
>
> On 25 January 2012 21:20, Tomasz Cielecki <tomasz at ostebaronen.dk> wrote:
>
>> Do what you want as long as it does not violate the License :)
>>
>> On Wed, Jan 25, 2012 at 8:47 PM, Miljenko Cvjetko
>> <mcvjetko at holisticware.net> wrote:
>> > Hi
>> >
>> > On 2012.01.25 14:12, Tomasz Cielecki wrote:
>> >
>> > I have made a port of a Horizontal Pager which can be found
>> > here: https://github.com/Cheesebaron/MonoDroid.HorizontalPager
>> >
>> > Great job!
>> > Thanks.
>> >
>> > may I put it together as VS item template?
>> > ... and publish it of course ...
>> >
>> > regards
>> >
>> > mel
>> >
>> >
>> > It works in a similar manner. This is an entirely C# implementation.
>> >
>> > On Jan 25, 2012 12:52 PM, "Stuart Lodge" <me at slodge.com> wrote:
>> >>
>> >> I don't suppose anyone has already done this and would like to share
>> the
>> >> source (just asking in case)
>> >>
>> >> If not, then I'll have a go... as I'd quite like to use the ViewPager
>> in
>> >> this app.
>> >>
>> >> On 23 January 2012 21:24, Jonathan Pryor <jonp at xamarin.com> wrote:
>> >>>
>> >>> On Jan 21, 2012, at 7:36 AM, k0ng wrote:
>> >>> > I want to use ViewPager  as demo in this website
>> >>> >
>> >>> >
>> http://geekyouup.blogspot.com/2011/07/viewpager-example-from-paug.html
>> >>>
>> >>> Right now, it won't be easy, as you need to manually bind the Java
>> types.
>> >>>
>> >>> In a future release, we'll be providing a tool to simplify the binding
>> >>> process.
>> >>>
>> >>> If you really want to hand-bind them now, see:
>> >>>
>> >>>        The base Java class:
>> >>>
>> https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Adder.java
>> >>>        The C# glue code for inheritance:
>> >>>
>> https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs
>> >>>
>> >>>  - Jon
>> >>>
>> >>> _______________________________________________
>> >>> Monodroid mailing list
>> >>> Monodroid at lists.ximian.com
>> >>>
>> >>> UNSUBSCRIBE INFORMATION:
>> >>> http://lists.ximian.com/mailman/listinfo/monodroid
>> >>>
>> >>
>> >>
>> >> _______________________________________________
>> >> Monodroid mailing list
>> >> Monodroid at lists.ximian.com
>> >>
>> >> UNSUBSCRIBE INFORMATION:
>> >> http://lists.ximian.com/mailman/listinfo/monodroid
>> >>
>> >
>> >
>> > _______________________________________________
>> > Monodroid mailing list
>> > Monodroid at lists.ximian.com
>> >
>> > UNSUBSCRIBE INFORMATION:
>> > http://lists.ximian.com/mailman/listinfo/monodroid
>> >
>> >
>> >
>> > --
>> > Miljenko Cvjetko dipl.ing. ET
>> >       Direktor/CEO
>> >       Projektant rješenja/Solution Architect
>> >       Razvojni programer/Senior developer
>> >       Voditelj projekta/Project Manager
>> >
>> > IX južna obala 13
>> > Kajzerica Zagreb
>> > T: 385 1 7775555
>> > M: 385 91 557 447 3
>> > F: 385 1 7779556
>> > e: mcvjetko at holisticware.net
>> > w: http://www.holisticware.net
>>
>>
>>
>> --
>> Med Venlig Hilsen / With Best Regards
>> Tomasz Cielecki
>> http://ostebaronen.dk
>> _______________________________________________
>> Monodroid mailing list
>> Monodroid at lists.ximian.com
>>
>> UNSUBSCRIBE INFORMATION:
>> http://lists.ximian.com/mailman/listinfo/monodroid
>>
>
> _______________________________________________
> Monodroid mailing list
> Monodroid at lists.ximian.com
>
> UNSUBSCRIBE INFORMATION:
> http://lists.ximian.com/mailman/listinfo/monodroid
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/monodroid/attachments/20120212/55cadd44/attachment-0001.html>


More information about the Monodroid mailing list