From ec159ab17a0a4b3bc76da9f2f9df22023152034d Mon Sep 17 00:00:00 2001 From: rickrickrickyyy Date: Fri, 28 Jul 2017 08:10:07 +0800 Subject: [PATCH] + extras: DSL for navigating between activities #62 remove Parcelable add a case class to wrap array in Serializable add method to startActivityForResult use method overloading --- .../macroid/extras/UIActionsExtras.scala | 270 ++++-------------- 1 file changed, 54 insertions(+), 216 deletions(-) diff --git a/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala b/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala index e5cf221..35ccf40 100644 --- a/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala +++ b/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala @@ -4,7 +4,7 @@ import android.app.Activity import android.content.{Context, Intent} import android.os._ import android.widget.Toast -import macroid.{ContextWrapper, Ui} +import macroid.{ActivityContextWrapper, ContextWrapper, Ui} object UIActionsExtras { @@ -41,208 +41,12 @@ object UIActionsExtras { } } - private def readArray[A](source: Parcel, build: Int ⇒ Array[A], read: Parcel ⇒ A) = { - val N = source.readInt() - val array = build(N) - for { - i <- 0 until N - } array(i) = read(source) - array - } - - class Ints(val get: Array[Int]) extends Parcelable { - - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeInt) - } - } - - object Ints { - def apply(array: Int*) { - new Ints(array.toArray) - } - val CREATOR: Parcelable.Creator[Ints] = new Parcelable.Creator[Ints] { - - override def createFromParcel(source: Parcel): Ints = new Ints({ - source.createIntArray() - }) - - override def newArray(size: Int): Array[Ints] = new Array[Ints](size) - } - } - - - class Bytes(val get: Array[Byte]) extends Parcelable { - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeByte) - } - } - - object Bytes { - def apply(array: Byte*) { - new Bytes(array.toArray) - } - val CREATOR: Parcelable.Creator[Bytes] = new Parcelable.Creator[Bytes] { - - override def createFromParcel(source: Parcel): Bytes = new Bytes({ - readArray(source, N ⇒ new Array[Byte](N), _.readByte()) - }) - - override def newArray(size: Int): Array[Bytes] = new Array[Bytes](size) - } - } - - class Doubles(val get: Array[Double]) extends Parcelable { - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeDouble) - } - } - - object Doubles { - def apply(array: Double*) { - new Doubles(array.toArray) - } - val CREATOR: Parcelable.Creator[Doubles] = new Parcelable.Creator[Doubles] { - - override def createFromParcel(source: Parcel): Doubles = new Doubles({ - readArray(source, N ⇒ new Array[Double](N), _.readDouble()) - }) - - override def newArray(size: Int): Array[Doubles] = new Array[Doubles](size) - } - } - - class Floats(val get: Array[Float]) extends Parcelable { - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeFloat) - } - } - - object Floats { - def apply(array: Float*) { - new Floats(array.toArray) - } - - val CREATOR: Parcelable.Creator[Floats] = new Parcelable.Creator[Floats] { - - override def createFromParcel(source: Parcel): Floats = new Floats({ - readArray(source, N ⇒ new Array[Float](N), _.readFloat()) - }) - - override def newArray(size: Int): Array[Floats] = new Array[Floats](size) - } - } - - class Longs(val get: Array[Long]) extends Parcelable { - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeLong) - } - } - - object Longs { - def apply(array: Long*) { - new Longs(array.toArray) - } - - val CREATOR: Parcelable.Creator[Longs] = new Parcelable.Creator[Longs] { - - override def createFromParcel(source: Parcel): Longs = new Longs({ - readArray(source, N ⇒ new Array[Long](N), _.readLong()) - }) - - override def newArray(size: Int): Array[Longs] = new Array[Longs](size) - } - } - - class Booleans(val get: Array[Boolean]) extends Parcelable { - - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(c ⇒ dest.writeInt(if (c) 1 else 0)) - } - } - - object Booleans { - def apply(array: Boolean*) { - new Booleans(array.toArray) - } - val CREATOR: Parcelable.Creator[Booleans] = new Parcelable.Creator[Booleans] { - - override def createFromParcel(source: Parcel): Booleans = new Booleans({ - readArray(source, N ⇒ new Array[Boolean](N), _.readInt() != 0) - }) - - override def newArray(size: Int): Array[Booleans] = new Array[Booleans](size) - } - } - - class Chars(val get: Array[Char]) extends Parcelable { - // def this(array: Char*) { - // this(array.toArray) - // } - - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(c ⇒ dest.writeInt(c)) - } - } - - object Chars { - val CREATOR: Parcelable.Creator[Chars] = new Parcelable.Creator[Chars] { - - override def createFromParcel(source: Parcel): Chars = new Chars( - readArray(source, N ⇒ new Array[Char](N), _.readInt.toChar) - ) - - override def newArray(size: Int): Array[Chars] = new Array[Chars](size) - } - } - - class Strings(val get: Array[String]) extends Parcelable { - override def describeContents() = 0 - - override def writeToParcel(dest: Parcel, flags: Int) { - dest.writeInt(get.length) - get.foreach(dest.writeString) - } - } - - object Strings { - - def apply(array:String*) ={ - new Strings(array.toArray) - } - - val CREATOR: Parcelable.Creator[Strings] = new Parcelable.Creator[Strings] { - override def createFromParcel(source: Parcel): Strings = - new Strings(readArray(source, n ⇒ new Array[String](n), _.readString)) - - - override def newArray(size: Int): Array[Strings] = new Array[Strings](size) + + case class ArrayExtras[T](array: Array[T]) + + implicit class ArrayMethod[T](array: Array[T]) { + def toArrayExtras: ArrayExtras[T] = { + ArrayExtras[T](array) } } @@ -262,39 +66,73 @@ object UIActionsExtras { case v: Serializable ⇒ intent.putExtra(key, v) case v: Bundle ⇒ intent.putExtra(key, v) case v: Parcelable ⇒ intent.putExtra(key, v) - case v ⇒ throw new IllegalArgumentException(s"Please don't put ${v.getClass} into the extra") + case _: Array[_] ⇒ throw new IllegalArgumentException(s"Array is not supported,but you can wrap it in a case class : ArrayExtras(Array(1,2,3))") + case v ⇒ throw new IllegalArgumentException(s"class: ${v.getClass} is not supported") } } } - - /** - * example: goto(classOf[TuningActivity], i ⇒ i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), "ID" -> 1) + + /** + * * * @param cls class of the activity - * @param configFn extra config steps(add flags) * @param extra the extra key value pair * @param context context - * @return Ui action that can navigate to the class of the Activity + * @return intent that can navigate to the class of the Activity */ - def goto(cls: Class[_ <: Activity], configFn: Intent ⇒ Unit, extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { + def intentFor(cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ContextWrapper): Intent = { val intent = new Intent(context.getOriginal, cls) - extra.foreach(elem ⇒ elem._2.putExtra(intent, elem._1)) - configFn(intent) + extra.foreach({ + case (key, value) ⇒ value.pushInto(intent, key) + }) + intent + } + + /** + * example: goto(intentFor(classOf[TuningActivity], "ID" -> 1, Array("some","array").toArrayExtras)) + * + * @param intent x + * @param context context + * @return Ui action that can navigate to the class of the Activity + */ + def goto(intent: Intent)(implicit context: ContextWrapper): Ui[Unit] = { Ui(context.getOriginal.startActivity(intent)) } + /** + * example: goto(classOf[TuningActivity], "ID" -> 1, Array("some","array").toArrayExtras) + * + * @param cls class of the activity + * @param extra the extra key value pair + * @param context context + * @return Ui action that can navigate to the class of the Activity + */ + def goto(cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { + goto(intentFor(cls, extra: _*)) + } /** * example: goto(classOf[TuningActivity], i ⇒ i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), "ID" -> 1) * * @param cls class of the activity * @param extra the extra key value pair + * @param modified a function that return a modified version of the intent * @param context context * @return Ui action that can navigate to the class of the Activity */ - def goto(cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { - val intent = new Intent(context.getOriginal, cls) - extra.foreach(elem ⇒ elem._2.putExtra(intent, elem._1)) - Ui(context.getOriginal.startActivity(intent)) + def goto(cls: Class[_ <: Activity], modified: Intent => Intent, extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { + goto(modified(intentFor(cls, extra: _*))) + } + + def request(requestCode: Int, intent: Intent)(implicit context: ActivityContextWrapper): Ui[Unit] = { + Ui(context.getOriginal.startActivityForResult(intent, requestCode)) + } + + def request(requestCode: Int, cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ActivityContextWrapper): Ui[Unit] = { + request(requestCode, intentFor(cls, extra: _*)) + } + + def request(requestCode: Int, modified: Intent => Intent, cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ActivityContextWrapper): Ui[Unit] = { + request(requestCode, modified(intentFor(cls, extra: _*))) } }