BundleArgs
Let your IDE create your bundles/intents for you. This library is:
- reflection free
- typesafe
- fast
- very small - just the annotation interfaces are added to your akp (4 methods, 6 fields)
- supports any class:
Activities
,Fragments
and any other class => use one processor for all your needs - support save/restore to save changes of the arguments in an
Activities
onSaveInstanceState
function and restore them again from thesavedInstanceState
if desired - creates nice helper functions if appropriate
How to add it to your project - Gradle (via JitPack.io)
- add jitpack to your project's
build.gradle
:
repositories {
maven { url "https://jitpack.io" }
}
- add the compile statement to your module's
build.gradle
and apply the apt plugin:
dependencies {
compile 'com.github.MFlisar.BundleArgs:bundleargs-annotation:1.6'
annotationProcessor 'com.github.MFlisar.BundleArgs:bundleargs-processor:1.6'
}
Usage - Definitions
Here's a simple example that demonstrates the use in ANY class that needs a Bundle
argument:
@BundleBuilder
public class Test
{
@Arg
Long id;
@Arg
String value;
@Arg @Nullable
String optionalValue;
// define a constructor with Bundle args and the processor will create a build method that directly creates an object of this class
public Test(Bundle args)
{
TestBundleBuilder.inject(args, this);
}
}
And this is how you define it in an activity:
@BundleBuilder(
generatePersist = true /* if desired, generates a persist method to save current state into a bundle */
)
public class MyActivity extends Activity
{
@Arg
String stringArg;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
MyActivityBundleBuilder.inject(getIntent().getExtras(), this);
// ALTERNATIVELY: if desired, a persist method is generated that must be called in onSaveInstanceState
// if this is enabled, following will either read the arguments OR the last values from the savedInstanceState
MyActivityBundleBuilder.inject(savedInstanceState != null ? savedInstanceState : getIntent().getExtras(), this);
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
// Optionally: this will save all fields into the state, so that you can inject current values when activity is restored
MyActivityBundleBuilder.persist(outState, this);
}
}
Usage - Builder
- If you have defined the default costructor with a bundle as args in it, you can directly create a class like this:
Test test = new TestBundleBuilder()
.id(1L)
.value("Test")
.optionalValue("optionalValue")
.create();
- You can always just create a
Bundle
with the builder like following:
Bundle bundle = new TestBundleBuilder()
.id(1L)
.value("Test")
.optionalValue("optionalValue")
.build();
- You can always just create an
Intent
with the builder like following (if the annotated class is anActivity
or if the boolean flagalwaysAddIntentBuilder
of theBundleBuilder
is set to true:
Intent intent = new TestBundleBuilder()
.id(1L)
.value("Test")
.optionalValue("optionalValue")
.buildIntent(context);
- If the annotated class extends
Activity
, following method will be added to start the activity directly;
new MyActivityBundleBuilder()
.stringArg("Test")
.startActivity(context);
- If the annotated class extends
Fragment
(support, android x or default), following method will be added to create the fragment direclty with arguments already set:
MyFragment fragment = new MyFragmentBundleBuilder()
.stringArg("Test")
.createFragment();
- if the enable
useConstructorForMandatoryArgs
in the@BundleBuilder
annotation, the generated builder will force you to set mandatory fields via the constructor like following:
Bundle b = new TestBundleBuilder(1L, "Test") // you MUST supply mandatory fields
.optionalValue("optionalValue") // optional fields can be set via builder functions
.build();
Customisation
@BundleBuilder
You can define some setup variables like following (each one is optional):
@BundleBuilder(useConstructorForMandatoryArgs = true, setterPrefix = "with", generateGetters = false, generateIntentBuilder = false)
boolean useConstructorForMandatoryArgs()
: default:false
... if true, all mandatory fields will be part of the constructor, otherwise all mandatory fields need to be set with the builder styleString setterPrefix()
: default""
... if not empty, all setters for the builder will be prefixed with this String. I.e. the fieldcustomField
will be settable via a functionbuilder.withCustomField(...)
if thesetterPrefix == "with"
...boolean generateGetters()
: default:false
... defines, if the builder offers getter functions for each field to retrieve fields from a bundle directlyboolean generateIntentBuilder()
: default:false
... defines, if thebuildIntent
method is generated for non activity classes as wellboolean isKotlinClass()
: default:false
... define if the annotated class is a kotlin class or notboolean generatePersist()
: default:false
... define if you want to generate a simply persist method to write all current values to the provided bundle
@Arg
@Arg(value = "", optional = false)
String name()
: default:""
... if set, the builder setter will get the custom name instead of the one derived from the field nameboolean optional()
: default:false
... if true, fields are optional, if not, they must be set via constructor or via setter
Demo
For an example with activities, check out the demo: Demo
Credits
This project is generally based on https://github.com/emilsjolander/IntentBuilder but was improved and restructured heavily in the meantime.
TODO
- conductor/fragment/class demo?
- ???