无法在Android中设置自定义imageview的图像资源
我根据在和中学到的经验创建了一个自定义视图项目。 在我的项目中,我不仅尝试在视图上绘制,还尝试在自定义的无法在Android中设置自定义imageview的图像资源,android,android-imageview,android-canvas,android-custom-view,android-paint,Android,Android Imageview,Android Canvas,Android Custom View,Android Paint,我根据在和中学到的经验创建了一个自定义视图项目。 在我的项目中,我不仅尝试在视图上绘制,还尝试在自定义的ImageView上绘制。因此,我创建了一个定制的ImageView,并完成了上述官方代码实验室中的所有步骤。 这是我的自定义ImageView类: // Stroke width for the the paint. private const val STROKE_WIDTH = 12f class MyImageView @JvmOverloads constructor( c
ImageView
上绘制。因此,我创建了一个定制的ImageView
,并完成了上述官方代码实验室中的所有步骤。
这是我的自定义ImageView
类:
// Stroke width for the the paint.
private const val STROKE_WIDTH = 12f
class MyImageView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
private var path = Path()
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
private lateinit var extraCanvas : Canvas
private lateinit var extraBitmap : Bitmap
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop
private var currentX = 0f
private var currentY = 0f
private var motionTouchEventX = 0f
private var motionTouchEventY = 0f
// Set up the paint with which to draw.
private val paint = Paint().apply {
color = drawColor
// Smooths out edges of what is drawn without affecting shape.
isAntiAlias = true
// Dithering affects how colors with higher-precision than the device are down-sampled.
isDither = true
style = Paint.Style.STROKE // default: FILL
strokeJoin = Paint.Join.ROUND // default: MITER
strokeCap = Paint.Cap.ROUND // default: BUTT
strokeWidth = STROKE_WIDTH // default: Hairline-width (really thin)
}
init{
init()
}
private fun init(){
setOnTouchListener(OnTouchListener { _, event ->
event?.let {
motionTouchEventX = it.x
motionTouchEventY = it.y
when(it.action){
MotionEvent.ACTION_DOWN -> touchStart()
MotionEvent.ACTION_MOVE -> touchMove()
MotionEvent.ACTION_UP -> touchUp()
}
return@OnTouchListener true
}
false
})
}
override fun onDraw(canvas: Canvas?) {
canvas?.drawBitmap(extraBitmap, 0f, 0f, null)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (::extraBitmap.isInitialized) extraBitmap.recycle()
extraBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
extraCanvas = Canvas(extraBitmap)
}
private fun touchStart() {
path.reset()
path.moveTo(motionTouchEventX, motionTouchEventY)
currentX = motionTouchEventX
currentY = motionTouchEventY
}
private fun touchMove() {
val dx = Math.abs(motionTouchEventX - currentX)
val dy = Math.abs(motionTouchEventY - currentY)
if (dx >= touchTolerance || dy >= touchTolerance) {
// QuadTo() adds a quadratic bezier from the last point,
// approaching control point (x1,y1), and ending at (x2,y2).
path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
currentX = motionTouchEventX
currentY = motionTouchEventY
// Draw the path in the extra bitmap to save it.
extraCanvas.drawPath(path, paint)
}
// Invalidate() is inside the touchMove() under ACTION_MOVE because there are many other
// types of motion events passed into this listener, and we don't want to invalidate the
// view for those.
invalidate()
}
private fun touchUp() {
// Reset the path so it doesn't get drawn again.
path.reset()
}
}
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.myImageView.setImageResource(R.drawable.ic_launcher_foreground)
}
}
这就是我的MainActivity
的XML布局
(在codelab中没有人,他们只是以编程方式使用自定义视图):
我的问题是:没有显示我要绘制的图像资源。
绘图部分的工作方式与codelabs中的类似。但是我只想用于测试的R.drawable.ic_launcher_前台drawable没有显示在屏幕上。为什么?
我希望有人能帮忙。在自定义视图中,画布仅用于绘制extraBitmap
,它由extraCanvas
更新,因此MyImageView
仅处理extraBitmap
的绘制
setImageResource
属于ImageView
类,该类在内部处理资源到可绘制的转换,并在其onDraw()内的画布上绘制
但是onDraw
被自定义视图覆盖,该视图不处理所接收位图的绘制,因此解决方案是调用super.onDraw
,如下所示:
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
// ^^^^^^^^^^^^^^^^ add this to execute imageview's onDraw for image handling
canvas?.drawBitmap(extraBitmap, 0f, 0f, null)
}
或者,您可以覆盖设置ImageResource
并通过设置ImageResource
方法将代码添加到画布中我的ImageView的onDraw
中,以绘制接收到的资源。您也可以使用setBackgroundResource(…)
<
因此,您的主要活动如下所示:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.myImageView.setBackgroundResource(R.drawable.ic_launcher_foreground)
}
}
使用purple
draw color在绘制一点并使用ic_launcher_前台
作为背景图像后,结果如下:
别忘了,正如@Pavneet_Singh所建议的:
对重写的onDraw方法调用super(如
super.onDraw(帆布)
谢谢:)它解决了我的问题。顺便说一句,这是一个很好的解释。谢谢你,我很高兴能帮上忙。快乐编码!
binding.myImageView.setBackgroundResource(R.drawable.ic_launcher_foreground)
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.myImageView.setBackgroundResource(R.drawable.ic_launcher_foreground)
}
}