【问题标题】:Android runtime 9-patch under XamarinXamarin 下的 Android 运行时 9-patch
【发布时间】:2014-04-02 00:08:49
【问题描述】:

可以在 Xamarin/Android 中在运行时创建 9-patch 吗?

这与 this questionthis question 相同,但在 Xamarin 下工作。对那里给出的答案的天真翻译会产生扭曲的九个补丁。

在下图中,原始图像位于左上角——以下代码正确地对其没有任何作用。其余的应该是 9 个补丁。似乎正在发生的事情是左上角被拉伸,而不是应该的中心。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Graphics;
using Android.Graphics.Drawables;
using Java.IO;
using Android.Content.Res;
using System.IO;
using System.Drawing;

namespace Android9PatchFail
{
  public class ImageCanvas : View
  {
    public ImageCanvas (Context context) :
      base(context)
    {
      Initialize();
    }
    public ImageCanvas (Context context, IAttributeSet attrs) :
      base(context, attrs)
    {
      Initialize();
    }
    public ImageCanvas (Context context, IAttributeSet attrs, int defStyle) :
      base(context, attrs, defStyle)
    {
      Initialize();
    }
    void Initialize () {
      this.SetBackgroundColor(Android.Graphics.Color.White);
    }
    public Bitmap ImageBitmap {
      get {
        AssetManager manager = this.Resources.Assets;
        Stream stream = manager.Open("buttonb.png");
        Bitmap r = BitmapFactory.DecodeStream(stream);
        return r;
      }
    }
    protected override void OnDraw (Canvas canvas) {
      base.OnDraw(canvas);
      Bitmap bitmap = this.ImageBitmap;
      Paint paint = new Paint();
      //      canvas.DrawBitmap(bitmap, 20, 20, paint);
      float bitmapWidth = bitmap.Width;
      float bitmapHeight = bitmap.Height;
//      this.DrawScaledImage(canvas, bitmap, 20, 50, new Size(100, 100));
      Random rand = new Random();

      double growthFactor = 0.5; rand.NextDouble();
        int top = 4; // 4 12 18 14 did give output with growth of 0.174.
        int left = 12;
        int bottom = 18;
        int right = 14;
        System.Diagnostics.Debug.WriteLine("Growth is " + growthFactor);
        System.Diagnostics.Debug.WriteLine("Insets are " + top + " " + left + " " + bottom + " " + right);
        for (int i = 0; i < 9; i++) {
          int row = i / 3;
          int column = i % 3;

          int width = (int) ((1 + column*growthFactor) * bitmapWidth);
          float x = 20;
          switch (column) {
            case 1: x = 200; break;
            case 2: x = 450; break;
            default: break;
          }
          float y = 40 + 160 * row;
          int height = (int) ((1 + row*growthFactor) * bitmapHeight);
          Size size = new Size(width, height);
          //        this.DrawScaledImage(canvas, bitmap, x, y, size);
          this.DrawNinePatchBitmap(canvas, bitmap, x, y, top, left, bottom, right, size);
          //        this.DrawNinePatchBitmap(canvas, bitmap, 200, 100, 1, 1, 5, 5, new SizeF(2 * bitmapWidth, 2 * bitmapHeight));
        }
    }
    public void DrawScaledImage (Canvas canvas, Bitmap bitmapToStretch, float x, float y, Size requestedSize) {
      Android.Graphics.Bitmap b = Android.Graphics.Bitmap.CreateScaledBitmap(bitmapToStretch, requestedSize.Width, requestedSize.Height, false);
      canvas.DrawBitmap(b, x, y, null);
    }

    public void DrawNinePatchBitmap (Canvas canvas, Android.Graphics.Bitmap bitmapToStretch, float x, float y, int top, int left, int right, int bottom, SizeF requestedSize)
    {
      RectF rect = new RectF(x, y, x+requestedSize.Width, y+requestedSize.Height);
//      System.Diagnostics.Debug.WriteLine("Rect is " + x + "  " + y + "  " + requestedSize.Width + "  " + requestedSize.Height);
      NinePatch npBitmap = CreateNinePatch(bitmapToStretch, top, left, bottom, right);
      npBitmap.Draw(canvas, rect);
    }

    private NinePatch CreateNinePatch(Android.Graphics.Bitmap bitmap, int top, int left, int bottom, int right) {
      MemoryStream buffer = GetMemoryStream(top, left, bottom, right);
      NinePatch patch = new NinePatch(bitmap, buffer.ToArray(), "blah");
      return patch;
    }

    private MemoryStream GetMemoryStream(int top, int left, int bottom, int right) {
      //Docs check the NinePatchChunkFile
      MemoryStream buffer = new MemoryStream(new byte[84]);
      using (BinaryWriter writer = new BinaryWriter(buffer)) {
        //was translated
        writer.Write(new byte[] { 0x01 });
        //divx size
        writer.Write(new byte[] { 0x02 });
        //divy size
        writer.Write(new byte[] { 0x02 });
        //color size
        writer.Write(new byte[] { 0x09 });

        //skip
        writer.Write(0);
        writer.Write(0);

        //padding
        writer.Write(0);
        writer.Write(0);
        writer.Write(0);
        writer.Write(0);
        //writer.Write(left);
        //writer.Write(right);
        //writer.Write(top);
        //writer.Write(bottom);

        //skip 4 bytes
        writer.Write(0);

        //offsets
        writer.Write(left);
        writer.Write(right);
        writer.Write(top);
        writer.Write(bottom);
        //No color
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
        writer.Write(0x00000001);
      }

      return buffer;
    }
  }
}

【问题讨论】:

  • 您是否尝试过转换此要点的来源? gist.github.com/briangriffey/4391807
  • @WilliamJockusch - 如果您可以针对您的具体案例提供有关您的问题的更多信息,这将有助于更多的人为您提供更好的答案,而不仅仅是重定向到我猜的前两个帖子。
  • 你试过 XobotOS 吗?
  • 天真的翻译应该适用于 Xamarin。但是,到现在为止,我一直在使用 Xamarin 进行开发大约一年,并且经常发生某些实现不正确或缺失的情况。您也应该在Xamarin Forum 上试试运气,但很可能您实际上在 Xamarin Android 中发现了一个错误。无论如何,我会在their bug tracker 上报告详细问题。

标签: android xamarin.android xamarin nine-patch


【解决方案1】:

XobotOS 是 Android 4.0 源代码的半自动移植版,来自 Java to C#。使用改进版本移植了自动化部件 Sharpen 可以编译更高级的 Java 构造和支持 泛型。

您可以按照@kanzure 的回答表单this 问题的指示尝试使用this

【讨论】:

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