{"id":19260682,"url":"https://github.com/evant/simplefragment","last_synced_at":"2025-08-23T11:09:52.073Z","repository":{"id":29423957,"uuid":"32959725","full_name":"evant/simplefragment","owner":"evant","description":"A fragment-like abstraction for Android that is easier to use and understand","archived":false,"fork":false,"pushed_at":"2020-06-14T22:57:42.000Z","size":285,"stargazers_count":40,"open_issues_count":0,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-08-23T11:08:54.310Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"crayner/CKEditor","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/evant.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-27T00:40:12.000Z","updated_at":"2025-08-05T09:57:49.000Z","dependencies_parsed_at":"2022-06-26T11:31:01.242Z","dependency_job_id":null,"html_url":"https://github.com/evant/simplefragment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/evant/simplefragment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evant%2Fsimplefragment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evant%2Fsimplefragment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evant%2Fsimplefragment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evant%2Fsimplefragment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evant","download_url":"https://codeload.github.com/evant/simplefragment/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evant%2Fsimplefragment/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271746768,"owners_count":24813582,"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-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","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":[],"created_at":"2024-11-09T19:22:30.584Z","updated_at":"2025-08-23T11:09:52.050Z","avatar_url":"https://github.com/evant.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SimpleFragment\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/me.tatarka.simplefragment/simplefragment/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/me.tatarka.simplefragment/simplefragment)\n\nA fragment-like abstraction for Android that is easier to use and understand\n\nThe purpose of this library is to build a better foundation for working with the controller layer in Android-style MVC. If you have ever worked with Fragments, you know that they feel more complicated than they need to be AND sometimes have unexpected behavior. This is especially true when you try to nest them. SimpleFragment provides an api that is very similar to native fragments but is more powerful _and_ easier to understand.\n\n## Download\n```groovy\ncompile 'me.tatarka.simplefragment:simplefragment:0.1'\n```\nor if you are using AppCompat\n```groovy\ncompile 'me.tatarka.simplefragment:simplefragment-appcompat:0.1'\n```\n\n## Features\n- Survive orientation changes\n- First-class nesting\n- Immediately added to the view when they are created\n- Don't have to worry about `commitAllowingStateLoss()`\n- Fails fast if you attempt to add the same fragment twice\n- Many of the same features as native fragments: view paging, inflation from layouts, `startActivityForResult()`, back stack, dialogs\n\n## Usage\nThe most important thing to understand is how the lifecycle differs from native fragments. It is, in fact, very similar to setting `setRetainInstance(true)` in that it survives configuration changes. This makes things like api calls much easer to handle. However, you do have to be careful to only keep references any view or activity state between `onViewCreated()` and `onViewDestroyed()`.\n\n![SimpleFragment lifecycle](https://raw.githubusercontent.com/evant/simplefragment/master/images/lifecycle.png)\n\nHere an example of a SimpleFragment that gets a string from a network call and populates a `TextView`.\n```java\npublic class HelloWorldFragment extends SimpleFragment {\n  static final String STATE_HELLO_TEXT = \"STATE_HELLO_TEXT\";\n  String helloText;\n  TextView helloTextView;\n  \n  @Override\n  public void onCreate(Context context, @Nullable Bundle state) {\n    if (state != null) {\n      helloText = state.getString(STATE_HELLO_TEXT);\n    }\n  \n    if (helloText == null) {\n      Api.getInstance(context).getHelloWorld(new Api.Listener() {\n        @Override\n        public void onResult(String result) {\n          helloText = result;\n          if (helloTextView != null) {\n            helloTextView.setText(helloText);\n          }\n        }\n      });\n    }\n  }\n    \n  @Override\n  public void onSave(Bundle state) {\n    state.putString(STATE_HELLO_TEXT, helloText);\n  }\n  \n  @Override\n  public View onCreateView(final LayoutInflater inflater, final ViewGroup parent) {\n    return inflater.inflate(R.layout.hello_world, parent, false);\n  }\n  \n  @Override\n  public void onViewCreated(View view) {\n    helloTextView = (TextView) view.findViewById(R.id.text);\n    helloTextView.setText(helloText);\n  }\n  \n  @Override\n  public void onViewDestroyed(View view) {\n    helloTextView = null;\n  }\n}\n```\n\nThere are many ways to easily handle the view lifecycle part of this equation, like [Butter Knife](https://github.com/JakeWharton/butterknife), a custom view or view holder, or more recently, [data binding](https://developer.android.com/tools/data-binding/guide.html).\n\nIn order to use SimpleFragments in an Activity you should subclass `SimpleFragmentActivity` or `SimpleFragmentAppCompatActivity`. You can then either add the SimpleFragment in the layout\n```xml\n\u003cfragment\n    android:id=\"@+id/my_fragment\"\n    android:name=\"me.tatarka.simplefragment.sample.HelloWorldFragment\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:layout=\"@layout/hello_world\" /\u003e\n```\nor dynamically in code\n```java\npublic class MyActivity extends SimpleFragmentActivity {\n  @Override\n  protected void onCreate(Bundle state) {\n    getSimpleFragmentManager().findOrAdd(SimpleFragmentIntent.of(HelloWorldFragment.class), LayoutKey.of(R.id.my_fragment));\n  }\n}\n```\nNote that when dynamicaly creating fragments, that they will be saved and restored by the `SimpleFragementManager` so you should not add it again when restoring state (Use `findOrAdd()` to simplify this check). Luckily, you will get an immedatly exception if you accidently do this instead of having an extra fragment silently added.\n\n### Extras\nYou can pass extras to you `SimpleFragment` in a similar way to the way you do it in activities. Simply add them to the `SimpleFragmentIntent`\n```java\nSimpleFragmentIntent.of(MyFragment.class).putExtra(MyFragment.EXTRA_ARG, \"foo\");\n```\nand then access the intent in the fragment to obtain it's value.\n```java\npublic class MyFragment extends SimpleFragment {\n  static final String EXTRA_ARG = \"ARG\";\n  @Override\n  public void onCreate(Context context, @Nullable Bundle state) {\n    String arg = getIntent().getStringExtra(EXTRA_ARG);\n  }\n```\n\n### Nesting\nBoth `SimpleFragmentActivity` and `SimpleFragment` provide a `SimpleFragmentManager`. Unlike native fragments, you don't have to worry about werid inconsitencies in nested fragements like `startActivityForResult()` or the back stack not working.\n\n### Back Stack\nYou can push a new `SimpleFragment` on the back stack by using `push()` instead of `add()`. The back button will pop the fragment off, or you can do it in code with `pop()`. This will work correctly in nested fragments, where the back button will alwasy pop the last one globbaly added, and the `pop()` method will be scoped to the current fragment.\n\n### View Paging\nYou can subclass `SimpleFragmentPagerAdapter` to use fragments in a `ViewPager`.\n```java\nprivate static final List\u003cClass\u003c? extends SimpleFragment\u003e\u003e FRAGMENTS = Arrays.asList(\n        FragmentFromLayout.class,\n        FragmentWithBackStack.class,\n        FragmentDialogs.class,\n        FragmentActivityForResult.class\n);\n\nprivate class Adapter extends SimpleFragmentPagerAdapter {\n    public Adapter() {\n        super(MainActivity.this);\n    }\n  \n    @Override\n    public SimpleFragmentIntent getItem(int position) {\n        return SimpleFragmentIntent.of(FRAGMENTS.get(position));\n    }\n  \n    @Override\n    public int getCount() {\n        return FRAGMENTS.size();\n    }\n}\n```\n\nThe default implementation will properly handle adding and removing pages dynamcialy when you call `notifyDataSetChange()`. No more having to worry about overriding `getItemPosition()`.\n\nNote that fragments will still be completly destroyed when they are far off screen. You can always use `ViewPager.setOffscreenPageLimit()` to modify this limit.\n\n### Dialogs\nThere is a `SimpleDialogFragment` subclass you can use for dialogs.\n```java\npublic class MyDialogFragment extends SimpleDialogFragment {\n    @Override\n    public void onCreate(Context context, @Nullable Bundle state) {\n        // You must call super here.\n        super.onCreate(context, state);\n    }\n\n    @Override\n    public View onCreateView(final LayoutInflater inflater, final ViewGroup parent) {\n        return inflater.inflate(R.layout.fragment_dialog, parent, false);\n    }\n\n    @Override\n    public Dialog onCreateDialog(View contentView) {\n        // contentView will be the view created in onCreateView()\n        return new AlertDialog.Builder(contentView.getContext())\n                .setView(contentView)\n                .setPositiveButton(\"ok\", null)\n                .setNegativeButton(\"cancel\", null)\n                .create();\n    }\n}\n```\n\nShow it with\n```java\ngetSimpleFragmentManager().add(SimpelFragmentIntent.of(MyDialogFragment.class), DialogKey.of(\"my_dialog\")).show();\n```\n\nA good way to propigate events from the dialog (or any fragment) back up to it's parent is with `SimpleFragment.getParent()` which will return either the parent fragment or Activity depending on where it is nested. You can cast this to an interface to communicate back up to it.\n\n### Start Activity For Result\nNot much to say here, just use `startActivityForResult()` on the `SimpleFragment` instead of the activity and the result will be sent back down to your fragment. Works with nesting too!\n\n## License\n\n    Copyright 2015 Evan Tatarka\n    \n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n       http://www.apache.org/licenses/LICENSE-2.0\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevant%2Fsimplefragment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevant%2Fsimplefragment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevant%2Fsimplefragment/lists"}