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
- Scala, Android y Eclipse
- Android studio dalvik vm no puede encontrar la clase
- Uso conveniente de Android XmlResourceParser?
- Dependencia no resuelta en sbt-android-plugin 0.6.0-SNAPSHOT?
- Dependencia no resuelta: com.hanhuy.sbt # android-sdk-plugin; 1.3.19: no encontrado
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
- Android, scala y eclipse = mezcla inestable
- Cómo orientar Android con Scala 2.8 Trunk builds
- ¿Hay una manera de determinar si es posible llamar a un dialog.dismiss () sin vacío try-catch bloque?
- Scala en Android: java.lang.NoSuchMethodError: java.lang.String.isEmpty
- Uso del proyecto Scala con Gradle para Android
- ¿Hay una manera de combinar dos o más archivos .dex en un archivo .dex utilizando Scala?
- Con ProGuard, ¿cuál es el impacto en la estrategia de pruebas?
- Groovy, Scala, Clojure, etc scripts en Android
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)) }
- ¿En qué plataformas móviles el "push token" no es permanente?
- NotificationManager se bloquea sólo en el dispositivo