Code Monkey home page Code Monkey logo

paginize's Introduction

Android Arsenal

Paginize

The embryo of this project existed before I knew anything about Fragment, at that time, I was planning refactor of an old project, which was started by myself, that project consisted of only a few Activities, but lots of features were planned to be added to it, I felt the need for a more extensible & easier solution for managing the user interfaces & business logics, each user interface with an Activity is overkill to me and it is definitely not the choice.

I created a basic concept that each user interface be modeld as a Page, and Pages will be pushed onto or popped out from a stack, states of the Page will persist as long as it is kept in the stack, simple and straightforward.

After developing & using Paginize for some time, I learned that there was an offical framework called Fragment from the Support Library(I didn't know much about offical support from Google at that time, including this Support Library, sorry for my being so naive...), I thought, damnit I must have reinvented a useless wheel. I spent some time learning Fragment, and trying to use it in a demo project, but at the end I just didn't buy the idea behind it:

  1. Fragments have to be explicitly saved to the backstack.
  2. Each Fragment supports creating its own option menus but no easy way to remove the menus.
  3. No intuitive way to handle BACK press on a per-Fragment basis.
  4. No global setting for Fragment transition animation
  5. Too many life cycle methods, Yes, I counted, there are 29 onXXX methods. Do we really need ALL of them?
  6. Hard-to-understand APIs, the FragmentTransaction object has methods like add, addToBackstack, replace, show, hide, attach and detach, the methods alone are good and I can easily guess what they do, but why methods like show and hide exist in a Transaction object? it is weird, the feeling is that it gives me too many options, and I find it hard to make a choice.

You may argue that it is not difficult to solve all these problems and learn how to use it, but I hate it when I have to keep looking for all kinds of workaround, that's not neat and the code would be ugly.

Fragment is good and it is versatile, but for me it is too heavy, not flexible at all and there are quite a few restrictions. Paginize turned out to be a useful wheel for myself, and maybe hopefully for you. Since this is the README for Paginize, I will not talk much about inflexibilties & restrictions of Fragment, but if you have ever used Fragment, I believe you already have a collection of them.

Paginize is a light-weight framework for Android, which eases development of Android applications with complex UI structures. Paginize makes use of Java annotations to inject layouts and views, layouts and Pages can be inherited, the layout inheritance feature is just like the frameset tag in HTML, and this makes code reuse much easier.

Note

The project is still NOT stable, APIs may change(but not significantly).

Demo

  1. Create a layout file(res/layout/page_header.xml) for HeaderPage:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:background="#ffe6e6e6">

    <TextView
        android:id="@+id/tv_back"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_gravity="center"
        android:gravity="center"
        android:paddingLeft="10dip"
        android:paddingRight="10dip"
        android:text="Back"
        />

    <TextView
        android:id="@+id/tv_title"
        style="@style/top_bar_title_center"
        android:layout_marginLeft="72dip"
        android:layout_marginRight="72dip"
        android:singleLine="true"
        android:text="Title" />

</RelativeLayout>
  1. Create the HeaderPage, this page will be inherited by other pages that need a header(title bar) with a BACK button and a title:
@PageLayout(R.layout.page_header)
public abstract class HeaderPage extends Page implements View.OnClickListener {
    @InjectView(value = R.id.tv_back, listenerTypes = {View.OnClickListener.class}) 
    private TextView mTvBack;

    @InjectView(R.id.tv_title) 
    private TextView mTvTitle;

    public HeaderPage(PageActivity pageActivity) {
        super(pageActivity);
    }

    protected void setBackButtonVisibility(int visibility) {
        mTvBack.setVisibility(visibility);
    }

    protected void enableBackButton(boolean enable) {
        mTvBack.setEnabled(enable);
    }

    protected void setBackButtonText(String text) {
        mTvBack.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
        mTvBack.setText(text);
    }

    protected void setTitleText(String text) {
        mTvTitle.setText(text);
    }

    protected void onBackButtonClicked() {
        hide(true, true);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_back:
                onBackButtonClicked();
            break;
        }
    }
}
  1. Create another layout(page_test.xml) for TestPage, let's say this test page contains only one TextView:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:padding="10dip"
    />
  1. Create the TestPage:
// here we inherit the layout from HeaderPage, and of course 
// the logics for handling the BACK button press
@InheritPageLayout(R.layout.page_test)
public class TestPage extends HeaderPage {
    @InjectView(R.id.tv_content)
    private TextView mTvContent;

    public TestPage(PageActivity pageActivity) {
        super(pageActivity);

        mTvContent.setText("Hello Paginize!");
    }
}

After the steps above, TestPage is a page that contains a titlebar with a BACK button on the top-left corner and a TextView as the content at the center.

  1. Create an Activity that extends PageActivity, and show the TestPage:
@InjectPageAnimator(SlidePageAnimator.class)
public class MainActivity extends PageActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new TestPage(this).show(null, true);
    }
}

That's all for using Paginize to make a one screen application. Here you may find that it is sort of more hassle than just use Activity, but Paginize is only useful when you use it to make more complicated applications, you see the advantages of it when you use it to structure a real application.

You have already seen the usages of @PageLayout, @InheritPageLayout and a few other annotations, and some framework code, you may want to explore and find more from the demo project.

Proguard rules

To prevent annotated classes and fields from being stripped away, the following rules must be put in proguard-project.txt.

-keep public class net.neevek.android.lib.paginize.**
-keep @net.neevek.android.lib.paginize.annotation.ListenerMarker class ** { *; }
-keepclassmembers,allowobfuscation class ** {
  @net.neevek.android.lib.paginize.annotation.** <fields>;
}

Under MIT license

Copyright (c) 2014 - 2015 neevek <[email protected]>
See the file license.txt for copying permission.

paginize's People

Contributors

neevek avatar

Watchers

James Cloos avatar  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.