Last active
April 12, 2020 23:23
-
-
Save zhanghai/931dec58a7cfef8d19a137adf917b8b3 to your computer and use it in GitHub Desktop.
ParcelableArgs and ParcelableState
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 Hai Zhang <[email protected]> | |
* All Rights Reserved. | |
*/ | |
package com.example.yourapplication | |
import android.app.Activity | |
import android.content.Intent | |
import android.os.Bundle | |
import android.os.Parcelable | |
import androidx.annotation.MainThread | |
import androidx.fragment.app.Fragment | |
import kotlin.reflect.KClass | |
interface ParcelableArgs : Parcelable | |
fun <Args : ParcelableArgs> Bundle.putArgs(args: Args, argsClass: KClass<Args>): Bundle { | |
putParcelable(argsClass.java.name, args) | |
return this | |
} | |
inline fun <reified Args : ParcelableArgs> Bundle.putArgs(args: Args) = putArgs(args, Args::class) | |
fun <Args : ParcelableArgs> Args.toBundle(argsClass: KClass<Args>): Bundle = | |
Bundle().apply { putArgs(this@toBundle, argsClass) } | |
inline fun <reified Args : ParcelableArgs> Args.toBundle(): Bundle = toBundle(Args::class) | |
fun <F: Fragment, Args: ParcelableArgs> F.putArgs(args: Args, argsClass: KClass<Args>): F { | |
val arguments = arguments | |
if (arguments != null) { | |
arguments.putArgs(args, argsClass) | |
} else { | |
this.arguments = args.toBundle(argsClass) | |
} | |
return this | |
} | |
inline fun <F: Fragment, reified Args: ParcelableArgs> F.putArgs(args: Args): F = | |
putArgs(args, Args::class) | |
fun <Args: ParcelableArgs> Intent.putArgs(args: Args, argsClass: KClass<Args>): Intent = | |
putExtra(argsClass.java.name, args) | |
inline fun <reified Args: ParcelableArgs> Intent.putArgs(args: Args) = putArgs(args, Args::class) | |
fun <Args : ParcelableArgs> Bundle.getArgs(argsClass: KClass<Args>): Args { | |
classLoader = argsClass.java.classLoader | |
return getParcelable(argsClass.java.name, argsClass)!! | |
} | |
inline fun <reified Args : ParcelableArgs> Bundle.getArgs() = getArgs(Args::class) | |
@MainThread | |
inline fun <reified Args : ParcelableArgs> Activity.args() = BundleArgsLazy(Args::class) { | |
intent.extras ?: throw IllegalStateException("Activity $this has null intent extras") | |
} | |
@MainThread | |
inline fun <reified Args : ParcelableArgs> Fragment.args() = BundleArgsLazy(Args::class) { | |
arguments ?: throw IllegalStateException("Fragment $this has null arguments") | |
} | |
class BundleArgsLazy<Args : ParcelableArgs>( | |
private val argsClass: KClass<Args>, | |
private val argumentsProducer: () -> Bundle | |
) : Lazy<Args> { | |
private var cached: Args? = null | |
override val value: Args | |
get() { | |
var args = cached | |
if (args == null) { | |
args = argumentsProducer().getArgs(argsClass) | |
cached = args | |
} | |
return args | |
} | |
override fun isInitialized() = cached != null | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 Hai Zhang <[email protected]> | |
* All Rights Reserved. | |
*/ | |
package com.example.yourapplication | |
import android.os.Bundle | |
import android.os.Parcelable | |
import kotlin.reflect.KClass | |
interface ParcelableState : Parcelable | |
fun <State : ParcelableState> Bundle.putState(state: State) = | |
putParcelable(state.javaClass.name, state) | |
fun <State : ParcelableState> Bundle.getState(stateClass: KClass<State>): State { | |
classLoader = stateClass.java.classLoader | |
return getParcelable(stateClass.java.name, stateClass)!! | |
} | |
inline fun <reified State : ParcelableState> Bundle.getState() = getState(State::class) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 Hai Zhang <[email protected]> | |
* All Rights Reserved. | |
*/ | |
package com.example.yourapplication | |
import android.content.Intent | |
import android.os.Bundle | |
import androidx.appcompat.app.AppCompatActivity | |
import androidx.fragment.app.Fragment | |
import androidx.fragment.app.add | |
import androidx.fragment.app.commit | |
import kotlinx.android.parcel.Parcelize | |
class SampleActivity : AppCompatActivity() { | |
private val args by args<Args>() | |
fun addSampleFragment() { | |
supportFragmentManager.commit { | |
add<SampleFragment>(android.R.id.content, null, SampleFragment.Args(0, null, Bundle()).toBundle()) | |
} | |
} | |
@Parcelize | |
data class Args( | |
val intArgument: Int, | |
val nullableStringArgument: String?, | |
val parcelableArgument: Bundle | |
) : ParcelableArgs | |
} | |
class SampleFragment : Fragment() { | |
private val args by args<Args>() | |
fun startSampleActivity() { | |
startActivity( | |
Intent(requireContext(), SampleActivity::class.java).putArgs(SampleActivity.Args(0, null, Bundle())) | |
) | |
} | |
override fun onActivityCreated(savedInstanceState: Bundle?) { | |
val state = savedInstanceState?.getState<State>() | |
val intValue = state?.intState ?: args.intArgument | |
} | |
override fun onSaveInstanceState(outState: Bundle) { | |
super.onSaveInstanceState(outState) | |
outState.putState(State(false)) | |
} | |
@Parcelize | |
data class Args( | |
val intArgument: Int, | |
val nullableStringArgument: String?, | |
val parcelableArgument: Bundle | |
) : ParcelableArgs | |
@Parcelize | |
private data class State( | |
val intState: Int | |
) : ParcelableState | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment