{"id":13639015,"url":"https://github.com/pedrovgs/Renderers","last_synced_at":"2025-04-19T21:35:21.946Z","repository":{"id":14572377,"uuid":"17288475","full_name":"pedrovgs/Renderers","owner":"pedrovgs","description":"Renderers is an Android library created to avoid all the boilerplate needed to use a RecyclerView/ListView with adapters.","archived":false,"fork":false,"pushed_at":"2021-09-29T19:28:42.000Z","size":11086,"stargazers_count":1198,"open_issues_count":2,"forks_count":171,"subscribers_count":59,"default_branch":"master","last_synced_at":"2025-04-07T23:07:11.146Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedrovgs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["pedrovgs"]}},"created_at":"2014-02-28T14:27:41.000Z","updated_at":"2025-01-07T06:12:49.000Z","dependencies_parsed_at":"2022-09-19T02:43:37.964Z","dependency_job_id":null,"html_url":"https://github.com/pedrovgs/Renderers","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrovgs%2FRenderers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrovgs%2FRenderers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrovgs%2FRenderers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrovgs%2FRenderers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedrovgs","download_url":"https://codeload.github.com/pedrovgs/Renderers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249811186,"owners_count":21328756,"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","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-08-02T01:00:56.738Z","updated_at":"2025-04-19T21:35:21.677Z","avatar_url":"https://github.com/pedrovgs.png","language":"Java","funding_links":["https://github.com/sponsors/pedrovgs"],"categories":["etc","RecyclerView","Libs"],"sub_categories":["\u003cA NAME=\"Adapter\"\u003e\u003c/A\u003eAdapter"],"readme":"Renderers [![Build Status](https://travis-ci.org/pedrovgs/Renderers.svg?branch=master)](https://travis-ci.org/pedrovgs/Renderers) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.pedrovgs/renderers/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.pedrovgs/renderers)\n=========\n\n**Renderers is an Android library created to avoid all the RecyclerView/Adapter boilerplate** needed to create a list/grid   of data in your app and all the spaghetti code that developers used to create following the ``ViewHolder`` classic implementation. **As performance is also important for us, we've added a new ``diffUpdate`` and a ``RVListRendererAdapter`` method supporting differential updated transparently in the main thread and a background thred respectively.**\n\nWith this library you can improve your RecyclerView/Adapter/ViewHolder code. The one sometimes we copy and paste again and again :smiley:. Using this library you won't need to create any new class extending from ``RecyclerViewAdapter``.\n\nCreate your ``Renderer`` classes and declare the mapping between the object to render and the ``Renderer``. The ``Renderer`` will use the model information to draw your user interface. You can reuse them in all your RecyclerView and ListView implementations easily. That's it!\n\nScreenshots\n-----------\n\n![Demo Screenshot][1]\n\nUsage\n-----\n\nTo use Renderers Android library you only have to follow three steps:\n\n* 1. Create your ``Renderer`` class or classes extending ``Renderer\u003cT\u003e``. Inside your ``Renderer`` classes. You will have to implement some methods to inflate the layout you want to render and implement the rendering algorithm.\n\n```java\npublic class VideoRenderer extends Renderer\u003cVideo\u003e {\n\n       @BindView(R.id.iv_thumbnail)\n       ImageView thumbnail;\n       @BindView(R.id.tv_title)\n       TextView title;\n       @BindView(R.id.iv_marker)\n       ImageView marker;\n       @BindView(R.id.tv_label)\n       TextView label;\n\n       @Override\n       protected View inflate(LayoutInflater inflater, ViewGroup parent) {\n           View inflatedView = inflater.inflate(R.layout.video_renderer, parent, false);\n           ButterKnife.bind(this, inflatedView);\n           return inflatedView;\n       }\n\n       @Override\n       protected void render() {\n           Video video = getContent();\n           renderThumbnail(video);\n           renderTitle(video);\n           renderMarker(video);\n           renderLabel();\n       }\n\n       @OnClick(R.id.iv_thumbnail)\n       void onVideoClicked() {\n           Video video = getContent();\n           Log.d(\"Renderer\", \"Clicked: \" + video.getTitle());\n       }\n\n       private void renderThumbnail(Video video) {\n           Picasso.with(context).load(video.getResourceThumbnail()).placeholder(R.drawable.placeholder).into(thumbnail);\n       }\n\n       private void renderTitle(Video video) {\n           this.title.setText(video.getTitle());\n       }\n}\n```\n\nYou can use [Jake Wharton's][2] [Butterknife][3] library to avoid findViewById calls inside your Renderers if you want. But the usage of third party libraries is not mandatory.\n\n* 2. **If you have just one type of item in your list**, instantiate a ``RendererBuilder`` with a ``Renderer`` instance and you are ready to go:\n\n```java\nRenderer\u003cVideo\u003e renderer = new LikeVideoRenderer();\nRendererBuilder\u003cVideo\u003e rendererBuilder = new RendererBuilder\u003cVideo\u003e(renderer);\n```\n\n**If you need to render different objects** into your list/grid you can use ``RendererBuilder.bind`` fluent API and that's it:\n\n```java\nRendererBuilder\u003cVideo\u003e rendererBuilder = new RendererBuilder\u003cVideo\u003e()\n         .bind(VideoHeader.class, new VideoHeaderRenderer())\n         .bind(Video.class, new LikeVideoRenderer());\n```\n\n* 3. Initialize your ``ListView`` or ``RecyclerView`` with your ``RendererBuilder`` and an optional ``List`` inside your Activity or Fragment. **You should provide a list of items to configure your ``RendererAdapter`` or ``RVRendererAdapter``.**\n\n```java\nprivate void initListView() {\n    adapter = new RendererAdapter\u003cVideo\u003e(rendererBuilder, list);\n    listView.setAdapter(adapter);\n}\n```\n\nor\n\n```java\nprivate void initListView() {\n    adapter = new RVRendererAdapter\u003cVideo\u003e(rendererBuilder, list);\n    recyclerView.setAdapter(adapter);\n}\n```\n\n**Remember, if you are going to use ``RecyclerView`` instead of ``ListView`` you'll have to use ``RVRendererAdapter`` instead of ``RendererAdapter``.**\n\n* 4. **Diff updates:**\n\n***If the ``RecyclerView`` performance is crucial in your application* remember you can use ``diffUpdate`` method in your ``RVRendererAdapter`` instance to update just the items changed in your adapter and not the whole list/grid.***\n\n```java\nadapter.diffUpdate(newList)\n```\n\nThis method provides a ready to use diff update for our adapter based on the implementation of the standard ``equals`` and ``hashCode`` methods from the ``Object`` Java class. The classes associated to your renderers will have to implement ``equals`` and ``hashCode`` methods properly. Your ``hashCode`` implementation can be based on the item ID if you have one. You can use your ``hashCode`` implementation as an identifier of the object you want to represent graphically. We know this implementation is not perfect, but is the best we can do wihtout adding a new interface you have to implement to the library breaking all your existing code. Here you can review the [DiffUtil.Callback implementation](https://github.com/pedrovgs/Renderers/blob/master/renderers/src/main/java/com/pedrogomez/renderers/DiffCallback.java) used in this library. If you can't follow this implementation you can always use [a different approach](https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00) combined with your already implemented renderers.\n\nAlso, `RVListRendererAdapter` provides a way to perform diff updates in a background thread transparently. When using `RVListRendererAdapter` you'll have a default `DiffUtil.ItemCallback` implementation (https://developer.android.com/reference/android/support/v7/util/DiffUtil.ItemCallback)) based on referencial equality for `areItemsTheSame` method and structural equality for `areContentsTheSame` method. You also have constructors on this class to provide your own implementation for `DiffUtil.ItemCallback`. You can even configure the threads used to perform the calculations through `AsynDifferConfig` class (https://developer.android.com/reference/android/support/v7/recyclerview/extensions/AsyncDifferConfig).\n\n\n\n***This library can also be used to show views inside a ``ViewPager``. Take a look at ``VPRendererAdapter`` :smiley:***\n\nUsage\n-----\n\nAdd this dependency to your ``build.gradle``:\n\n```groovy\ndependencies{\n    implementation 'com.github.pedrovgs:renderers:4.1.0'\n}\n```\n\nComplex binding\n---------------\n\nIf your renderers binding is complex and it's not based on different classes but in properties of these classes, you can also extend ``RendererBuilder`` and override ``getPrototypeClass`` to customize your binding as follows:\n\n```java\npublic class VideoRendererBuilder extends RendererBuilder\u003cVideo\u003e {\n\n  public VideoRendererBuilder() {\n    List\u003cRenderer\u003cVideo\u003e\u003e prototypes = getVideoRendererPrototypes();\n    setPrototypes(prototypes);\n  }\n\n  /**\n   * Method to declare Video-VideoRenderer mapping.\n   * Favorite videos will be rendered using FavoriteVideoRenderer.\n   * Live videos will be rendered using LiveVideoRenderer.\n   * Liked videos will be rendered using LikeVideoRenderer.\n   *\n   * @param content used to map object-renderers.\n   * @return VideoRenderer subtype class.\n   */\n  @Override\n  protected Class getPrototypeClass(Video content) {\n    Class prototypeClass;\n    if (content.isFavorite()) {\n      prototypeClass = FavoriteVideoRenderer.class;\n    } else if (content.isLive()) {\n      prototypeClass = LiveVideoRenderer.class;\n    } else {\n      prototypeClass = LikeVideoRenderer.class;\n    }\n    return prototypeClass;\n  }\n\n  /**\n   * Create a list of prototypes to configure RendererBuilder.\n   * The list of Renderer\u003cVideo\u003e that contains all the possible renderers that our RendererBuilder\n   * is going to use.\n   *\n   * @return Renderer\u003cVideo\u003e prototypes for RendererBuilder.\n   */\n  private List\u003cRenderer\u003cVideo\u003e\u003e getVideoRendererPrototypes() {\n    List\u003cRenderer\u003cVideo\u003e\u003e prototypes = new LinkedList\u003cRenderer\u003cVideo\u003e\u003e();\n    LikeVideoRenderer likeVideoRenderer = new LikeVideoRenderer();\n    prototypes.add(likeVideoRenderer);\n\n    FavoriteVideoRenderer favoriteVideoRenderer = new FavoriteVideoRenderer();\n    prototypes.add(favoriteVideoRenderer);\n\n    LiveVideoRenderer liveVideoRenderer = new LiveVideoRenderer();\n    prototypes.add(liveVideoRenderer);\n\n    return prototypes;\n  }\n}\n```\n\n\nReferences\n----------\n\nYou can find implementation details in these talks:\n\n[Software Design Patterns on Android Video][4]\n\n[Software Design Patterns on Android Slides][5]\n\nDeveloped By\n------------\n\n* Pedro Vicente Gómez Sánchez - \u003cpedrovicente.gomez@gmail.com\u003e\n\n\u003ca href=\"https://twitter.com/pedro_g_s\"\u003e\n  \u003cimg alt=\"Follow me on Twitter\" src=\"https://image.freepik.com/iconos-gratis/twitter-logo_318-40209.jpg\" height=\"60\" width=\"60\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"https://es.linkedin.com/in/pedrovgs\"\u003e\n  \u003cimg alt=\"Add me to Linkedin\" src=\"https://image.freepik.com/iconos-gratis/boton-del-logotipo-linkedin_318-84979.png\" height=\"60\" width=\"60\"/\u003e\n\u003c/a\u003e\n\nLicense\n-------\n\n    Copyright 2016 Pedro Vicente Gómez Sánchez\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\n\n[1]: http://raw.github.com/pedrovgs/Renderers/master/art/Screenshot_demo_1.png\n[2]: https://github.com/JakeWharton\n[3]: https://github.com/JakeWharton/butterknife\n[4]: http://media.fib.upc.edu/fibtv/streamingmedia/view/2/930\n[5]: http://www.slideshare.net/PedroVicenteGmezSnch/software-design-patterns-on-android\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrovgs%2FRenderers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrovgs%2FRenderers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrovgs%2FRenderers/lists"}