Fundición dinámica implícita de Scala

Quisiera crear un ayudante de Scala Views para Android

Usando esta combinación de rasgo y clase

class ScalaView(view: View) { def onClick(action: View => Any) = view.setOnClickListener(new OnClickListener { def onClick(view: View) { action(view) } }) } trait ScalaViewTrait { implicit def view2ScalaView(view: View) = new ScalaView(view) } 

Soy capaz de escribir onClick () como así

 class MainActivity extends Activity with ScalaViewTrait { //.... val textView = new TextView(this) textView.onClick(v => v.asInstanceOf[TextView] setText ("asdas")) } 

Mi preocupación es que quiero evitar el casting v a TextView

v siempre será TextView si se aplica a TextView LinearLayout si se aplica a LinearLayout y así sucesivamente.

¿Existe alguna manera de que v se muestre dinámico a cualquier vista que se aplique?

Acabo de empezar con Scala y necesito tu ayuda con esto.

ACTUALIZAR

Resuelto vea mi respuesta a continuación

El problema aquí es que dada la API de Android, simplemente no es posible que tenga seguridad de tipo completo y la conveniencia de definir una acción que sólo funciona en la subclase relevante de View .

Su enfoque sacrifica la seguridad del tipo, y los sacrificios de drexin (algunos) conveniencia. Al igual que usted, estaría dispuesto a renunciar a la seguridad de tipo en esta situación, ya que es razonable esperar un buen comportamiento de la biblioteca de Android, pero me encapsular el desagrado un poco diferente.

Primero definiría un wrapper para OnClickListener siguiente manera:

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

Y luego olvidar que OnClickListener existe (o al menos nunca utilizarlo en cualquier otro lugar en mi código). Ahora todas las cosas que no son de tipo seguro están agrupadas en un lugar, y mi clase ScalaView está limpia, por ejemplo:

 class ScalaView[T <: View](view: T) { def onClick(action: T => Any) = view.setOnClickListener(MyOnClickListener(action)) } 

Es probable que se encuentre en otros lugares donde necesite este tipo de envoltorio, y este enfoque le permite mantener todos los feos moldes, etc. cuidadosamente contenidos en un lugar, en lugar de dispersos por todo el código.

Me las arreglé para hacerlo. Aquí es cómo

 trait ScalaViewTrait { implicit def view2ScalaView[T <: View](view: T) = new ScalaView[T](view) } class ScalaView[T <: View](view: T) { def onClick(action: T => Any) = view.setOnClickListener(new OnClickListener { def onClick(view: View) { action(view.asInstanceOf[T]) } }) } 

Y ahora puedo escribir enClick como esto

 textView.onClick(v => v.setText("asdsa")) 

v es en realidad un TextView cuando onClick se aplica a un TextView

PD. Tal vez voy a escribir un montón de ayudantes y publicarlos en GitHub. <3 Scala

Usted podría en lugar de lanzar simplemente el partido del patrón en él:

 // ... textView.onClick { case v: TextView => v.setText("foobar") case v => log.error("Expected TextView got %s.".format(v.getClass)) } 
  • Cómo excluir archivos R * .class de una compilación proguard
  • Modo correcto de usar YouTube.Builder
  • Android, Scala y Proguard
  • No se puede encontrar el método en la actividad
  • Error al ejecutar 'sbt start-device'
  • Alternativas a java en android
  • Scala + Android: ¿Alguien construye y depura con éxito en Eclipse?
  • ¿Qué lenguajes de programación puedo usar en Android Dalvik?
  • Problema: "Extracción" de JSON usando ascensor-json en una aplicación Android (Scala)
  • Plugin scala-android
  • Android (en Scala): StackOverflowError depende de cuándo iniciar un hilo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.