Giter Club home page Giter Club logo

blade-2's Introduction

Build Status Android Arsenal

logo

Android library for boilerplate destruction - "Just code what is worth coding"

  • Generates boilerplate code based on used annotations and lets you focus on what matters.
  • Generated code is fully traceable.
  • Everything is generated during compile time.
  • No reflection used!
  • Consists of modules.

Usage

This library is divided into several modules. Each module provides different annotation and support classes:

Special annotation:

@Arg

Annotation for generating newInstance() methods for your Fragment classes.

Without using this library you would have to write this:

public class MyFragment extends Fragment {

    private static final String EXTRA_TEXT = "arg_text";
    private static final String EXTRA_DATA = "arg_data";

    public static MyFragment newInstance(String text, MyData data) {
        MyFragment frag = new MyFragment();
        Bundle args = new Bundle();
        args.putString(EXTRA_TEXT, text);
        args.putParcelable(EXTRA_DATA, data);
        frag.setArguments(args);
        return frag;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        mText = getArguments().getString(EXTRA_TEXT);
        mData = (MyData) getArguments().getParcelable(EXTRA_DATA);
    }
}

But with this library you can write this:

public class MyFragment extends Fragment {

    @Arg 
    String mText;
    @Arg 
    MyData mData;
  
}

Class blade.F (= Fragment) is automatically generated for you. This class contains 1 method for each Fragmentclass with annotated arguments:

  • X newX(T1 arg1[, T2 arg2, ...]) - Creates new instance of class X.

e.g. for MyFragment class it contains method named newMyFragment with 2 parameters: String and MyData. So you can easily create new fragment by calling:

F.newMyFragment("some-string", new MyData());

And given values will be set to corresponding attributes annotated with @Arg at the beginning of onCreate(Bundle) method.

Class blade.F is not final so that you can extend it and add more methods.

@Extra

Annotation for generating newIntent() methods for your Activity or Service classes.

Without using this library you would have to write this:

public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    public static Intent newIntent(Contaxt context, String text, MyData data) {
        Intent intent = new Intent(context, MyActivity.class);
        intent.putExtra(EXTRA_TEXT, text);
        intent.putExtra(EXTRA_DATA, data);
        return intent;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        Bundle extras = getIntent().getExtras();
        mText = extras.getString(EXTRA_TEXT);
        mData = (MyData) extras.getParcelable(EXTRA_DATA);
    }
}

But with this library you can write this:

public class MyActivity extends Activity {

    @Extra 
    String mText;
    @Extra
    MyData mData;
  
}

Class blade.I (= Intent) is automatically generated for you. This class contains 2 methods for each Activity class with annotated arguments:

  • Intent forX(Context c, T1 extra1[, T2 extra2, ...]) - Creates new Intent which can be used for starting new activity. This lets you add additional flags to this intent.
  • void startX(Context c, T1 extra1[, T2 extra2, ...]) - Creates new Intent and starts new activity.

e.g. for MyActivity class it contains methods named forMyActivity and startMyActivity with 2 parameters: String and MyData. So you can easily start new Activity by calling:

I.startMyActivity(context, "some-string", new MyData());

And given values will be set to corresponding attributes annotated with @Extra at the beginning of onCreate(Bundle) method (in Service/IntentService at the beginning of onStartCommand(Intent, int, int)/onHandleIntent(Intent)).

Class blade.I is not final so that you can extend it and add more methods.

@State

Annotation for simplifying state management.

For each class containing attributes annotated with @State Blade will generate helper class named NameOfClass_Helper with 2 static methods for state management:

  • saveState(Bundle)
  • restoreState(Bundle)

Classes extending from Fragment, Activity or View are managed automatically, so you don't need to call saveState(Bundle) or restoreState(Bundle). But other classes has to call these 2 generated methods when needed.

Without using this library you would have to write this:

public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    private String mText;
    private MyData mData;
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(EXTRA_DATA, mData);
        outState.putString(EXTRA_TEXT, mText);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mData = savedInstanceState.getParcelable(EXTRA_DATA);
        mText = (MyData) savedInstanceState.getString(EXTRA_TEXT);
    }   
    
}

But with this library you can write this:

public class MyActivity extends Activity {

    @State 
    String mText;
    @State
    MyData mData;
  
}

@Presenter

Annotation for implementing MVP architecture.

mvp architecture

How to implement:

  1. Create an interface for your view by extending IView.

    public interface IMyView implements blade.mvp.IView {
        void show(String something);  
    }
  2. Create a Presenter that will interact with the view interface. You can either extend BasePresenter or implement IPresenter.

    public class MyPresenter extends blade.mvp.BasePresenter<IMyView, Data> {
    
        public void onUserDidSomething() {
            String s = // do something ...
            
            if (getView() != null) {
                getView().show(s);
            }
        }
        
        //...
    }
  3. Create an implementation for your view interface with presenter field annotated with @Presenter (can be more than one). @Presenter is supported only for android views and activities (not fragments).

    public class MyView extends android.view.View implements IMyView {
        
        @Presenter
        MyPresenter mPresenter;
        
        @Override
        void show(String something) { /* ... */ }
        
        // ...
    }
  4. Call setTag(data) method on your view implementation to set the @Presenter field.

  5. Every Activity class, that can contain View class with presenter, needs to be known to Blade. If this Activity class does not use presenter, you need to annotate this class with @Blade.

    @Blade
    public class MyActivity extends Activity {
        // ...
    }

How does it work?

Each time you call setTag(data) method on your view this happens:

  • Unique ID (per activity) is created from view class, presenter class and data.toString() combination (so provide custom implementation of toString()).
  • If presenter for this ID does not exists yet, then it is created via default constructor and create(data, boolean) is called with the data given as parameter to setTag(data) and boolean flag indicating if presenter was recreated from state.
  • @Presenter field is set with proper instance.
  • Presenter is connected to the view by calling bind(view).

If you call setTag(null) on view then:

  • Presenter is disconnected from the view by calling unbind().
  • @Presenter field is set to null.
  • Presenter still lives until containing Activity is finished. (so you can use it again if you set appropriate tag)

(Same applies for any number of @Presenter fields inside your view)

Presenter lifecycle

Presenter is independent of activity's lifecycle. It is created when needed and destroyed when activity finishes.

If you want to programmatically remove view and know that you won't need its presenters anymore (or simply want to destroy it), you can call removePresentersFor(view) static method on PresenterManager before removing view from layout.

Presenter state

As you surely know, activity can be killed in order to reclaim resources and then be restored back from state in the future.

Therefore Presenter needs to be able to restore its state too. For this purpose use @State annotation on fields that are needed.

public class MyPresenter extends blade.mvp.BasePresenter<IMyView, Data> {

    @State
    boolean mFlag;
    @State
    SomeData mData;
    
    //...
}

When presenter is recreated from state create(data, boolean) method has true as second parameter to indicate this.

@Blade

If you do not use any @Extra inside your class, but you want the library to generate methods in blade.I for this class, then just annotate the class with @Blade, like this:

@Blade
public class MyActivity extends Activity {
    // no attributes with @Extra
}

Same applies for @Arg.

Download

Gradle plugin:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        // Add Blade plugin
        classpath 'eu.f3rog.blade:plugin:2.1.0'
    }
}

apply plugin: 'com.android.application'
// Apply Blade plugin
apply plugin: 'blade'

And create blade.json file in application directory with Blade modules you need: (or download from sample app)

{
    debug: false,
    modules: [
        "arg",
        "extra",
        "state",
        "mvp"
    ]
}

If you do not provide blade.json file, all Blade modules will be used.

NOTE:

This library uses com.neenbedankt.android-apt plugin. You don't need to apply it explicitly.

blade-2's People

Contributors

frantisekgazo avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.