The problem is that, given the Android API, it is simply impossible to ensure complete type safety and the convenience of defining an action that only works in the corresponding View subclass.
Your approach sacrifices type safety and Drexin victims (some). Like you, I would be willing to give up type safety in this situation, as it is reasonable to expect good behavior in the Android library, but I would encapsulate the troubles a little differently.
First, I would define a wrapper for OnClickListener as follows:
case class MyOnClickListener[V <: View](action: V => Any) extends OnClickListener { def onClick(view: View) = try action(view.asInstanceOf[V]) catch { case e: ClassCastException => throw new RuntimeException("This should never happen!", e) } }
And then forget that OnClickListener exists (or at least never uses it anywhere in my code). Now all unsafe things are gathered in one place, and the ScalaView class ScalaView clean, for example:
class ScalaView[T <: View](view: T) { def onClick(action: T => Any) = view.setOnClickListener(MyOnClickListener(action)) }
You will probably come across other places where you need such a shell, and this approach allows you to store all ugly throws, etc., carefully kept in one place, and not scattered throughout your code.
source share