{"id":29703409,"url":"https://github.com/thedumbtechguy/folio","last_synced_at":"2025-07-23T13:39:52.217Z","repository":{"id":149738205,"uuid":"52721497","full_name":"thedumbtechguy/Folio","owner":"thedumbtechguy","description":"A Page based navigation framework for Android with a simplified lifecycle and easy transition animations.","archived":false,"fork":false,"pushed_at":"2016-05-19T17:53:22.000Z","size":1323,"stargazers_count":37,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2023-10-20T23:27:09.824Z","etag":null,"topics":["android","fragments","java","lifecycle","navigation","navigation-framework","page"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thedumbtechguy.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-02-28T13:03:52.000Z","updated_at":"2023-10-20T23:27:10.299Z","dependencies_parsed_at":null,"dependency_job_id":"f76aae73-cf12-4200-86f2-78fac48b588c","html_url":"https://github.com/thedumbtechguy/Folio","commit_stats":null,"previous_names":[],"tags_count":1,"template":null,"template_full_name":null,"purl":"pkg:github/thedumbtechguy/Folio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thedumbtechguy%2FFolio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thedumbtechguy%2FFolio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thedumbtechguy%2FFolio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thedumbtechguy%2FFolio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thedumbtechguy","download_url":"https://codeload.github.com/thedumbtechguy/Folio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thedumbtechguy%2FFolio/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266689848,"owners_count":23969146,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","fragments","java","lifecycle","navigation","navigation-framework","page"],"created_at":"2025-07-23T13:39:51.464Z","updated_at":"2025-07-23T13:39:52.192Z","avatar_url":"https://github.com/thedumbtechguy.png","language":"Java","readme":"# Folio\n\nFolio is a Page based navigation framework for Android with a simplified lifecycle and easy transition animations.\nIt's intended to fulfil a similar role to fragments while looking more like Activities.\n\n[![Download](https://api.bintray.com/packages/frostymarvelous/maven/folio/images/download.svg) ](https://bintray.com/frostymarvelous/maven/folio/_latestVersion)\n\n## Users\n\nApps using Folio in production \n\n[![Umaplay](assets/uma_logo.png)](https://play.google.com/store/apps/details?id=com.umaplay.android)\n\n\n### Current Version: 1.0.0\n\nFolio follows [Semantic Versioning](http://semver.org/).\n\n[![](https://www.bintray.com/docs/images/bintray_badge_color.png)](https://bintray.com/frostymarvelous/maven/folio/view?source=watch)\n\n## Installation\n\n#### Gradle\nFolio is available on jcenter.\n\n```gradle\ncompile 'com.umaplay.oss:folio:1.0.0'\n```\n\n#### Manual Installation\nDownload the [aar artifact](artifacts/folio-1.0.0.aar) from the [artifacts](artifacts/) directory\nand copy it into the libs directory of your app module.\n\nSpecify `libs` as a repository in your root gradle file.\n```groovy\n    allprojects {\n        repositories {\n            ...\n            flatDir { dirs 'libs' }\n        }\n    }\n``` \n   \nSpecify Fluxxan as dependency in your app's gradle file.\n```groovy\n    dependencies {\n        compile fileTree(dir: 'libs', include: ['*.jar'])\n        compile(name: 'folio-1.0.0', ext: 'aar')\n        ...\n    }\n```\n\n## Introduction\nA Folio app is composed of simple Pages. If you are familiar with Activities, then you'll be right at home using Folio.\nThe lifecycle is simple and similar to that of Activities.\n\nFolio is composed of the\n\n1. Host\n2. PageManager\n3. Page\n4. PageFactory\n\n#### How it works\n\nPages are hosted inside of an `Activity`, `Fragment` or even another `Page`.\nA `PageManager` handles the lifecycle of the pages and ensures everything remains consistent.\nThe Host is responsible for notifying the `PageManager` of lifecycle changes and also, can respond to changes in the Stack.\n\n### Host\n\nThe Host can be an `Activity`, `Fragment` or even another `Page`. The Host must call the respective lifecycle methods on `PageManager`.\n\n```java\n    PageManager.onStart\n    PageManager.onResume\n    PageManager.onPause\n    PageManager.onStop\n    PageManager.onDestroy\n    PageManager.onSaveInstanceState\n```     \n\nFolio provides a `PagedActivity` which handles the heavy lifting of notifying the `PageManager` of lifecycle changes, handling on `Activity.onBackPressed` and responding when the Stack is empty.\n\n```java\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        \n        //create and set our manager which we can retrieve later using getPageManager()\n        setPageManager(new PageManager((ViewGroup) findViewById(R.id.container), this, App.getRefWatcher(), savedInstanceState));\n\n        //if instance state is null, then this is our first launch, let's navigate to the main page\n        //the page manager automatically restores the stack from the savedInstanceState\n        if (savedInstanceState == null) {\n            getPageManager().goTo(new RedPage.RedPageFactory());\n        }\n    }\n```\n\n### PageManager\n\nThe `PageManager` manages all pages. A Host can have as many instances as is feasible and Each Page can have a `NestedPageManager` for free (the library handles it's lifecycle for you).\nEach manager requires a container which is simply a `ViewGroup` (`FrameLayout` works great), a `PageStackDelegate` which is notified when the stack is empty and importantly, an instance of `com.squareup.leakcanary.RefWatcher` to help catch memory leaks.\nWe enforce the use of the RefManager because a memory leak can bring the entire application to it's knees very quickly.\n\nWhen navigating to a page, you can provide a `PageAnimatorFactory` which animates the addition and removal of Pages. By default, Pages are not animated.\nFolio includes `AnimatorUtils` which can help you create simple translation and fade animators. But you are free to create your own.\n\nYou can add `StackChangedListener`s to listen to changes in the stack and react accordingly. For example, to update an actionbar (if you choose to manage it in the host).\n\n### Page\n\nA Page is a self contained \"screen\" in a Folio application with a simple lifecyle and state preservation. Pages are modelled after activities and therefore easy to use.\n\n##### Lifecycle\n\nThe lifecycle is simple and easy to understand. It's been detailed in the diagram below. Click to view large size.\n\n[![Folio Page Lifecycle](assets/lifecycle_small.png)](assets/lifecycle.png)\n\n##### Context\n\nYou can get a context instance by calling `getContext()` between `onViewMounted` and `onViewUnmounted`. Doing so outside of this will throw an `IllegalStateException`.\n\n#### NestedPageManager\n\nA Page can get a cheap PageManager by calling `getNestedPageManager(ViewGroup)`. \nThe `NestedPageManager` is considered cheap because it is handled by the framework internally and you don't have to worry about the lifecycle or state handling.\n\nThis makes creating a Master/Detail view very easy to implement.\n\n\n#### Caveat\n\nBecause the Page lifecycle is independent of the Host's, using the context for libraries that rely on the Lifecycle to clean up resources can lead to increased memory usage e.g. Glide.\nYou wil need to find a way to bypass it. Refer to this [gist](https://gist.github.com/frostymarvelous/c5c1dbaa11ce3b0c8329d529ed01ae95) for an implementation that supports Glide.\n\n\n### PageFactory\n\n`PageFactory` handles the creation of Pages and storing of some information related to the Page. The provided `BasePageFactory` provide an implementation that handles all the heavy lifting.\n\n#### Factory Guidelines \n\nThe `PageFactory` and `PageAnimatorFactory` must be serializable.\n \n1. Ensure that any properties are serializable.\n2. If nested, make sure it is a static class.\n3. Do not use an anonymous class\n\nIf the Factory cannot be serialized, the app will crash.\n\n\n### Contributing\n\nThank you for taking the time to contribute.\nBut before you do, please read our [contribution guidelines](CONTRIBUTING.md). They are simple, we promise.\n\n\n### Todo\n  - Writing Tests\n\n\t\n### License\nMIT\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthedumbtechguy%2Ffolio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthedumbtechguy%2Ffolio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthedumbtechguy%2Ffolio/lists"}