注意:是的,我知道在Android中还有其他的按钮处理方法,但这只是一个例子来说明我的问题( actuall按钮要复杂得多)。因此,请不要回答在提供其他解决方案按钮在安卓,我正在寻找一个解决方案与PaintCode.
多年来,我一直使用PaintCode来绘制自定义按钮,它的工作原理非常出色。我也想对android做同样的事情,并有以下问题:
这在iOS上运行得很好,但是在安卓系统上,radius是20个像素而不是点,从而产生了一个远到小的半径(现在是高分辨率设备)。
或者在一般情况下,使用PaintCode生成的绘图方法绘制PaintCode时,我在PaintCode中绘制的所有绘图都是小的。
它会使生成的绘图代码没有考虑到设备的规模(就像在iOS上那样)。

查看https://www.paintcodeapp.com/documentation/android部分,“缩放”PaintCode建议在安卓系统中使用密度度量来执行缩放。这确实有效,但使生成的绘图模糊,我想这是因为我们绘制的分辨率较低,因为缩放。所以这不是一个可行的解决方案。
class Button1 @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : Button(context, attrs, defStyleAttr) {
var frame = RectF()
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
val displayDensity = resources.displayMetrics.density
canvas?.scale(displayDensity, displayDensity)
frame.set(0f,0f,width.toFloat()/displayDensity,height.toFloat()/displayDensity)
StyleKitName.drawButton1(canvas, frame)
}
}有解决这个问题的建议吗?这是PaintCode中的一个bug吗?
发布于 2017-09-27 20:25:32
我是开发商。很抱歉给你这么长的答案。
TLDR:自己处理缩放,例如你的方式。切换视图的layerType到软件,以避免模糊的结果规模。
首先,我完全理解这种混淆,对于iOS来说,它只是起作用,而在安卓系统中,你必须摆弄一些尺度。如果它能正常工作,那就更有意义了--我很喜欢它,其他的PaintCode用户也会这么做。但这不是窃听器。问题在于UIKit和android.graphic之间的区别。
在UIKit中,以点为单位来测量距离。这意味着,如果你画一个直径40点的圆圈,那么在不同的iOS设备上,它的尺寸应该会更小一些。PaintCode采用了这个惯例和你在PaintCode的用户界面中看到的所有数字,比如形状、笔划宽度或半径的位置--所有的东西都是在点上的。PaintCode生成的绘图代码不仅与分辨率无关(即可以调整大小/缩放,保持清晰度),而且与显示密度无关(在视网膜显示、常规显示和视网膜高清显示上呈现大致相同的大小)。代码没有什么特别之处。看起来是这样的:
NSBezierPath* rectanglePath = [NSBezierPath bezierPathWithRect: NSMakeRect(0, 0, 100, 50)];
[NSColor.grayColor setFill];
[rectanglePath fill];因此显示缩放是由UIKit处理的。此外,隐式尺度也取决于上下文。如果在drawRect: UIView子类中调用绘图代码,则会获得显示密度,但如果要在自定义UIImage中绘图,则会获取该图像的密度。魔术。
然后我们增加了对Android的支持。android.graphic中的所有度量都以像素表示。Android不具备任何UIKit的“显示密度”魔法。此外,也没有一种很好的方法来找出在绘图代码范围内的密度。你需要获得相关的资源。所以我们可以将它作为参数添加到所有的绘图方法中。但是,如果您不打算将绘图发布到显示,而是创建一个图像(您要发送给您的朋友或其他什么)呢?那么你不需要显示密度,而是图像密度。好的,如果添加一个参数,我们不应该添加资源,而是密度本身作为一个浮点,并在每个绘图方法中生成缩放。如果你不关心密度呢?如果你所关心的是你的画填充了一些矩形,并且有了最好的分辨率,那该怎么办?事实上,我认为情况通常是这样的。在我看来,拥有这么多不同的显示分辨率和显示密度,使得“一个物理尺寸的元素适合所有人”的方法相当小。因此,在大多数情况下,密度参数是无关的。我们决定将如何处理规模的决定留给用户。
现在是的模糊性的缩放绘图。这是UIKit和android.graphics的另一个不同之处。所有开发人员都应该明白,当涉及到用多个对象呈现大场景时,CoreGraphics不是很快。如果您是编程性能敏感的应用程序,您可能应该考虑使用SpriteKit或金属。这样做的好处是,您在CoreGraphics中所能做的事情并没有受到限制,而且您几乎总是能够得到非常准确的结果。缩放就是一个这样的例子。你可以使用巨大的规模,结果仍然是脆的。如果您想要更多的HW加速,使用不同的API并自己处理这些限制(比如您可以在GPU中安装多大的纹理)。
安卓走了另一条路。他们的android.graphic api可以在两种模式下工作--没有HW加速(他们称之为软件)或HW加速(他们称之为硬件)。它仍然是相同的API,但是其中一种硬件模式有一些重要的限制。这包括比例,模糊(因此阴影),一些混合模式和更多。https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
他们决定,如果目标API级别为>= 14,每个视图都将默认使用硬件模式。当然,您可以关闭它,并且神奇地您的缩放按钮将是漂亮和锐利的。
我们提到您需要在我们的文档页面“层类型”https://www.paintcodeapp.com/documentation/android部分中关闭硬件加速,而且它也在Android文档https://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling中。
发布于 2017-09-27 15:40:07
我记得有一个类似的问题,在与PaintCode支持人员交谈之后,我们想出了一个将DP转换为PX的函数。因此,比如说,在Android系统中,考虑到不同的显示密度,这20个点将被转换成“任何”像素。
长话短说,这是PaintCode支持答案的总结:
安卓在其绘图API中不支持独立于设备的像素,这是iOS和安卓行为不同的原因。使用UIKit时,输入的坐标以点为单位,因此它负责显示密度本身。在Android中生成位图时,需要考虑显示密度。
这是我创建的函数:
private static PointF convertDPtoPX(float widthDP, float heightDP) {
Context context = getAppContext();
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
float widthPX = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, widthDP, metrics);
float heightPX = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, heightDP, metrics);
return new PointF(widthPX, heightPX);
}下面是一个如何调用它的示例:
Bitmap myButton = StyleKit.imageOfMyButton(convertDPtoPX(widthDP, heightDP));当然,在本例中,由于项目的具体情况,我使用的是myButton (StyleKit.imageOfMyButton)位图。您需要调整示例以满足您的需要。
例如,您可以将该radius作为PaintCode中的外部参数,使每个平台负责提供其价值。比如:
// In Android, convert 20DP to 20PX based on the above function.
// In iOS, just pass 20.
StyleKitName.drawButton1(canvas, frame, radius)我希望这能帮到你。
https://stackoverflow.com/questions/46451186
复制相似问题