【问题标题】:Monodroid ViewPagerMonodroid ViewPager
【发布时间】:2012-03-09 09:39:06
【问题描述】:

ViewPager 是否可供 monodroid 开发人员使用?我看过很多类似这样的 Android 教程:http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html

我可以这样做并将 ViewPager 声明为代码,例如:

using Android.Support.V4.Widget;

namespace ViewPagerTest
{
    [Activity(Label = "ViewPager", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity
    {
        int count = 1;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            ViewPager pager = new ViewPager( this );

            SetContentView(Resource.Layout.Main);

        }
    }
}

但在教程中他使用了这样的 xml 代码:

<android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

哪个 Monodroid 似乎不喜欢.. 有什么我缺少的输入吗?

【问题讨论】:

  • 如何获取 ViewPager 类?你在用什么库?
  • 使用 Android.Support.V4.Widget
  • 问题是,你是如何从 C#/Mono 获得这个类的?是否有您正在使用的包装器,因为没有 C# 版本的 Android.Support 命名空间

标签: android xamarin.android executable-jar


【解决方案1】:

不能直接回答您的问题...

但有人将单独的 ViewPager 移植到 MonoDroid:https://github.com/Cheesebaron/MonoDroid.HorizontalPager

然后我添加了一个基于 http://buildmobile.com/how-to-build-an-android-pager-component/#fbid=TnZmgHdBfhF 的简单页面指示器

// 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);
    }
}

有一天我会在 GitHub 上得到一个示例项目!

【讨论】:

  • 虽然这不能回答我的问题,但它还是可以的。 Monodroid 似乎还不支持 ViewPager 导致这样的解决方案。我也在使用这个,但是它是在 apache 许可下的。这对我即将投放市场的应用程序有何影响?
  • 我认为 Apache 相当宽松 - en.wikipedia.org/wiki/Apache_License
  • 我完全 100% 推荐 CheeseBaron 的 Horizo​​ntalPager。我目前正在使用 MonoCross,它仍然不支持 Fragments,而且我现在太投入了,无法回头。非常感谢 Stuart 的建议(以及 CheeseBaron!)。
  • 您有没有发布过一个同时使用 Pager 和 Indicator 的示例?
【解决方案2】:

即使这已经回答了:

支持包可以实现。

我刚刚在this Java example 之后实现了它。

您可以将那里编写的任何内容转移到 C# 代码中,只需注意几件事:

  • 还必须使用注释掉的东西
  • 不要调用类 PagerAdapter
  • 当作者写super.anything()使用base.Anything()
  • 在实例化片段时,请确保将包名全部小写。

希望这对任何人都有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多