macroid icon indicating copy to clipboard operation
macroid copied to clipboard

DSL for navigating between activities

Open stanch opened this issue 10 years ago • 5 comments

See https://groups.google.com/forum/#!topic/macroid/BFDlv0Kmohc

stanch avatar Apr 30 '15 22:04 stanch

Hi

implicit class IntentVisitor(value: Any) {
    def visit(intent: Intent, key: String): Unit = {
      value match {
        case v: Short => intent.putExtra(key, v)
        case v: Int => intent.putExtra(key, v)
        case v: Byte => intent.putExtra(key, v)
        case v: Double => intent.putExtra(key, v)
        case v: Float => intent.putExtra(key, v)
        case v: Long => intent.putExtra(key, v)
        case v: String => intent.putExtra(key, v)
        case v: Boolean => intent.putExtra(key, v)
        case v: Char => intent.putExtra(key, v)
        case v: CharSequence => intent.putExtra(key, v)
        case v: Serializable => intent.putExtra(key, v)
        case v: Bundle => intent.putExtra(key, v)
        case v: Parcelable => intent.putExtra(key, v)
        case v: Any => throw new IllegalArgumentException(s"Please don't put ${v.getClass} into the extra")   }
    }
  }

  private def startActivity(cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = {
    val intent = new Intent(context.getOriginal, cls)
    extra.foreach(elem => elem._2.visit(intent, elem._1))
    Ui(context.getOriginal.startActivity(intent))
  }

  private def startActivityForResult(cls: Class[_ <: Activity], extra: (String, Any)*)(requestCode: Int = 0)(implicit context: ActivityContextWrapper): Ui[Unit] = {
    val intent = new Intent(context.getOriginal, cls)
    extra.foreach(elem => elem._2.visit(intent, elem._1))
    Ui(context.getOriginal.startActivityForResult(intent, requestCode))
  }

rickrickrickyyy avatar Jul 18 '17 15:07 rickrickrickyyy

I think that the problem is that the array is not covered by the pattern matcher. IMHO this question is not related with the issue or even macroid, it seems related with the Scala language. Please, ask the same question in stackoverflow. I'll delete the comment in some days to keep the issue clearer.

fedefernandez avatar Jul 24 '17 12:07 fedefernandez

If you change the above method startActivity to public and rename it to "goto" you can use this code to navigate into an activity like this

<~ On.Click(goto(classOf[SomeActivity],"EXTRA"->id))

rickrickrickyyy avatar Jul 25 '17 02:07 rickrickrickyyy

The problem is that your match is not exhaustive. You should cover all the cases for List because of the Intent class has one method for every type of the list. For me, the code could be a little bit tricky but you can create classes for every type for containing the list. Something like that:

case class Strings(array: String*) 
case class Ints(array: Int*)
....

Then you can use it at the beginning of your match:

 def visit(intent: Intent, key: String): Unit = {
      value match {
       case v: Ints => intent.putExtra(key, v.array)
       case v: Strings => intent.putExtra(key, v.array)
       ....
       case v: Short => intent.putExtra(key, v)
       case v: Int => intent.putExtra(key, v)
        ....
        }
    }
  }

I don't have tried the code, it´s only a proof of concept. Maybe it´s not the better solution, but you can investigate around that. If you want to contribute, you can create a PR to macroid-extras in the UIActionsExtras class

Thanks!

javipacheco avatar Jul 25 '17 08:07 javipacheco

I have just created a PR. Could you review it and give me some feedback?

Thanks

rickrickrickyyy avatar Jul 27 '17 05:07 rickrickrickyyy