Skip to content

Commit

Permalink
Resolve merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrovgs committed Dec 23, 2017
2 parents b16ac50 + 22abd0d commit dfdbdcf
Show file tree
Hide file tree
Showing 11 changed files with 465 additions and 6 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Renderers [![Build Status](https://travis-ci.org/pedrovgs/Renderers.svg?branch=m

**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`` method supporting differential updated transparently.**

With this library you can improve your RecyclerView/Adapter/ViewHolder code. The one we sometimes we copy and paste again and again :smiley:. Using this library you wont need to create any new class extending from ``RecyclerViewAdapter``.
With 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``.

Create 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!

Expand All @@ -15,9 +15,9 @@ Screenshots
Usage
-----

To use Renderers Android library and get your you only have to follow three steps:
To use Renderers Android library you only have to follow three steps:

* 1. Create your ``Renderer`` class or classes extending ``Renderer<T>``. Inside your ``Renderer`` classes you will have to implement some methods to inflate the layout you want to render and implement the rendering algorithm.
* 1. Create your ``Renderer`` class or classes extending ``Renderer<T>``. Inside your ``Renderer`` classes. You will have to implement some methods to inflate the layout you want to render and implement the rendering algorithm.

```java
public class VideoRenderer extends Renderer<Video> {
Expand Down Expand Up @@ -65,7 +65,7 @@ public class VideoRenderer extends Renderer<Video> {

You 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.

* 2. **If you have just on type of item in your list/grid**, instantiate a ``RendererBuilder`` with a ``Renderer`` instance and you are ready to go:
* 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:

```java
Renderer<Video> renderer = new LikeVideoRenderer();
Expand Down Expand Up @@ -98,7 +98,7 @@ private void initListView() {
}
```

**Remember if you are going to use ``RecyclerView`` instead of ``ListView`` you'll have to use ``RVRendererAdapter`` instead of ``RendererAdapter``.**
**Remember, if you are going to use ``RecyclerView`` instead of ``ListView`` you'll have to use ``RVRendererAdapter`` instead of ``RendererAdapter``.**

* 4. **Diff updates:**

Expand All @@ -110,6 +110,8 @@ adapter.diffUpdate(newList)

This 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.

***This library can also be used to show views inside a ``ViewPager``. Take a look at ``VPRendererAdapter`` :smiley:***

Usage
-----

Expand Down
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-slate
1 change: 1 addition & 0 deletions renderers/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.9.5"
testCompile 'org.robolectric:robolectric:2.4'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pedrogomez.renderers;

import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.pedrogomez.renderers.exception.NullRendererBuiltException;

import java.util.Collection;

/**
* PagerAdapter extension created to work RendererBuilders and Renderer instances. Other
* adapters have to use this one to show information into ViewPager widgets.
* <p>
* This class is the heart of this library. It's used to avoid the library users declare a new
* renderer each time they have to show information into a ViewPager.
* <p>
* VPRendererAdapter has to be constructed with a RendererBuilder to provide Renderer to
* VPRendererAdapter and one AdapteeCollection to provide the elements to render.
*
* @author Jc Miñarro.
*/
public class VPRendererAdapter<T> extends PagerAdapter {

private final RendererBuilder<T> rendererBuilder;
private AdapteeCollection<T> collection;

public VPRendererAdapter(RendererBuilder<T> rendererBuilder) {
this(rendererBuilder, new ListAdapteeCollection<T>());
}

public VPRendererAdapter(RendererBuilder<T> rendererBuilder, AdapteeCollection<T> collection) {
this.rendererBuilder = rendererBuilder;
this.collection = collection;
}

/**
* Main method of VPRendererAdapter. This method has the responsibility of update the
* RendererBuilder values and create or recycle a new Renderer. Once the renderer has been
* obtained the RendereBuilder will call the render method in the renderer and will return the
* Renderer root view to the ViewPager.
*
* If RendererBuilder returns a null Renderer this method will throw a
* NullRendererBuiltException.
*
* @param parent The containing View in which the page will be shown.
* @param position to render.
* @return view rendered.
*/
@Override public Object instantiateItem(ViewGroup parent, int position) {
T content = getItem(position);
rendererBuilder.withContent(content);
rendererBuilder.withParent(parent);
rendererBuilder.withLayoutInflater(LayoutInflater.from(parent.getContext()));
Renderer<T> renderer = rendererBuilder.build();
if (renderer == null) {
throw new NullRendererBuiltException("RendererBuilder have to return a not null Renderer");
}
updateRendererExtraValues(content, renderer, position);
renderer.render();
View view = renderer.getRootView();
parent.addView(view);
return view;
}

/**
* Remove a view for the given position. The adapter is responsible
* for removing the view from its container.
*
* @param container The containing View from which the view will be removed.
* @param position The view position to be removed.
* @param object The same object that was returned by
* {@link #instantiateItem(ViewGroup, int)}.
*/
@Override public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}

@Override public boolean isViewFromObject(View view, Object o) {
return view == o;
}

@Override public int getCount() {
return collection.size();
}

public T getItem(int position) {
return collection.get(position);
}

/**
* Add an element to the AdapteeCollection.
*
* @param element to add.
* @return if the element has been added.
*/
public boolean add(T element) {
return collection.add(element);
}

/**
* Remove an element from the AdapteeCollection.
*
* @param element to remove.
* @return if the element has been removed.
*/
public boolean remove(Object element) {
return collection.remove(element);
}

/**
* Add a Collection of elements to the AdapteeCollection.
*
* @param elements to add.
*/
public void addAll(Collection<? extends T> elements) {
collection.addAll(elements);
}

/**
* Remove a Collection of elements to the AdapteeCollection.
*
* @param elements to remove.
* @return if the elements have been removed.
*/
public boolean removeAll(Collection<?> elements) {
return collection.removeAll(elements);
}

/**
* Remove all elements inside the AdapteeCollection.
*/
public void clear() {
collection.clear();
}

/**
* Allows the client code to access the AdapteeCollection from subtypes of RendererAdapter.
*
* @return collection used in the adapter as the adaptee class.
*/
protected AdapteeCollection<T> getCollection() {
return collection;
}

public void setCollection(AdapteeCollection<T> collection) {
if (collection == null) {
throw new IllegalArgumentException("The AdapteeCollection configured can't be null");
}

this.collection = collection;
}

/**
* Empty implementation created to allow the client code to extend this class without override
* getView method.
*
* This method is called before render the Renderer and can be used in RendererAdapter extension
* to add extra info to the renderer created like the position in the ListView/RecyclerView.
*
* @param content to be rendered.
* @param renderer to be used to paint the content.
* @param position of the content.
*/
protected void updateRendererExtraValues(T content, Renderer<T> renderer, int position) {
//Empty implementation
}
}
Loading

0 comments on commit dfdbdcf

Please sign in to comment.