newList) {
121 | asyncListDiffer.submitList(newList);
122 | }
123 |
124 | /**
125 | * Empty implementation created to allow the client code to extend this class without override
126 | * getView method.
127 | *
128 | * This method is called before render the Renderer and can be used in RendererAdapter extension
129 | * to add extra info to the renderer created like the position in the ListView/RecyclerView.
130 | *
131 | * @param content to be rendered.
132 | * @param renderer to be used to paint the content.
133 | * @param position of the content.
134 | */
135 | @SuppressWarnings("UnusedParameters")
136 | protected void updateRendererExtraValues(T content, Renderer renderer, int position) {
137 | }
138 | }
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/Renderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers;
17 |
18 | import android.content.Context;
19 | import android.support.annotation.Nullable;
20 | import android.view.LayoutInflater;
21 | import android.view.View;
22 | import android.view.ViewGroup;
23 |
24 | import com.pedrogomez.renderers.exception.NotInflateViewException;
25 |
26 | import java.util.List;
27 |
28 | /**
29 | * Core class in this library. Base class created to work as a root ViewHolder in the classic
30 | * ListView / Adapter implementation. This entity will be extended by other Renderer classes in
31 | * order to show items into the screen.
32 | *
33 | * A Renderer have to encapsulate the presentation logic for ech row of your ListView/RecyclerView.
34 | *
35 | * Every Renderer have inside the view is rendering and the content is using to get the info.
36 | *
37 | * If you used to use RecyclerView extensions of this class are going to replace ViewHolder
38 | * implementations.
39 | *
40 | * @author Pedro Vicente Gómez Sánchez.
41 | */
42 | @SuppressWarnings("UnusedParameters")
43 | public abstract class Renderer implements Cloneable {
44 |
45 | private View rootView;
46 | private T content;
47 | private Context context;
48 | private int position;
49 |
50 | /**
51 | * Method called when the renderer is going to be created. This method has the responsibility of
52 | * inflate the xml layout using the layoutInflater and the parent ViewGroup and call setUpView and
53 | * hookListeners methods.
54 | *
55 | * @param content to render. If you are using Renderers with RecyclerView widget the content will
56 | * be null in this method.
57 | * @param layoutInflater used to inflate the view.
58 | * @param parent used to inflate the view.
59 | */
60 | public void onCreate(@Nullable T content, LayoutInflater layoutInflater, ViewGroup parent) {
61 | this.content = content;
62 | context = parent.getContext();
63 | rootView = inflate(layoutInflater, parent);
64 | if (rootView == null) {
65 | throw new NotInflateViewException("Renderer instances have to return a not null view in inflateView method");
66 | }
67 | setUpView(rootView);
68 | hookListeners(rootView);
69 | }
70 |
71 | /**
72 | * Method called when the Renderer has been recycled. This method has the responsibility of
73 | * update the content stored in the renderer.
74 | *
75 | * @param content to render.
76 | */
77 | public void onRecycle(T content) {
78 | this.content = content;
79 | }
80 |
81 | /**
82 | * Method to access the root view rendered in the Renderer.
83 | *
84 | * @return top view in the view hierarchy of one Renderer.
85 | */
86 | public View getRootView() {
87 | return rootView;
88 | }
89 |
90 | /**
91 | * Method to access to the current Renderer Context.
92 | *
93 | * @return the context associated to the root view.
94 | */
95 | protected Context getContext() {
96 | return context;
97 | }
98 |
99 | /**
100 | * @return the content stored in the Renderer.
101 | */
102 | protected final T getContent() {
103 | return content;
104 | }
105 |
106 | /**
107 | * Configures the content stored in the Renderer.
108 | *
109 | * @param content associated to the Renderer instance.
110 | */
111 | public void setContent(T content) {
112 | this.content = content;
113 | }
114 |
115 | /**
116 | * Stores the position of the item in the Adapter.
117 | *
118 | * @param position
119 | */
120 | public void setPosition(int position) {
121 | this.position = position;
122 | }
123 | /**
124 | * @returns the position of the item
125 | */
126 | protected final int getPosition() {
127 | return this.position;
128 | }
129 |
130 | /**
131 | * Inflate renderer layout. The view inflated can't be null. If this method returns a null view a
132 | * NotInflateViewException will be thrown.
133 | *
134 | *
135 | * @param inflater LayoutInflater service to inflate.
136 | * @param parent view group associated to the current Renderer instance.
137 | * @return View with the inflated layout.
138 | */
139 | protected abstract View inflate(LayoutInflater inflater, ViewGroup parent);
140 |
141 | /**
142 | * Map all the widgets from the rootView to Renderer members.
143 | *
144 | * @param rootView inflated using previously.
145 | */
146 | protected void setUpView(View rootView) { }
147 |
148 | /**
149 | * Set all the listeners to members mapped in setUpView method.
150 | *
151 | * @param rootView inflated using previously.
152 | */
153 | protected void hookListeners(View rootView) { }
154 |
155 | /**
156 | * @see RendererAdapter#onViewAttachedToWindow(RendererViewHolder)
157 | */
158 | public void onAttached() { }
159 |
160 | /**
161 | * @see RendererAdapter#onViewDetachedFromWindow(RendererViewHolder)
162 | */
163 | public void onDetached() { }
164 |
165 | /**
166 | * @see RendererAdapter#onViewRecycled(RendererViewHolder)
167 | */
168 | public void onRecycled() { }
169 |
170 | /**
171 | * Method where the presentation logic algorithm have to be declared or implemented.
172 | *
173 | * @param payloads Extra payloads for fine-grain rendering.
174 | */
175 | public abstract void render(List payloads);
176 |
177 | /**
178 | * Create a clone of the Renderer. This method is the base of the prototype mechanism implemented
179 | * to avoid create new objects from RendererBuilder. Pay an special attention implementing clone
180 | * method in Renderer subtypes.
181 | *
182 | * @return a copy of the current renderer.
183 | */
184 | Renderer copy() {
185 | try {
186 | //noinspection unchecked
187 | return (Renderer) clone();
188 | } catch (CloneNotSupportedException e) {
189 | throw new RuntimeException("All your renderers should be cloneable.");
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/RendererAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers;
17 |
18 | import android.support.annotation.Nullable;
19 | import android.support.v7.widget.RecyclerView;
20 | import android.support.v7.widget.RecyclerView.Adapter;
21 | import android.view.LayoutInflater;
22 | import android.view.ViewGroup;
23 |
24 | import com.pedrogomez.renderers.exception.NullRendererBuiltException;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Collection;
28 | import java.util.Collections;
29 | import java.util.List;
30 |
31 | /**
32 | * RecyclerView.Adapter extension created to work RendererBuilders and Renderer instances. Other
33 | * adapters have to use this one to show information into RecyclerView widgets.
34 | *
35 | * This class is the heart of this library. It's used to avoid the library users declare a new
36 | * renderer each time they have to show information into a RecyclerView.
37 | *
38 | * RendererAdapter has to be constructed with a LayoutInflater to inflate views, one
39 | * RendererBuilder to provide Renderer to RendererAdapter and one Collection to
40 | * provide the elements to render.
41 | *
42 | * @author Pedro Vicente Gómez Sánchez.
43 | */
44 | public class RendererAdapter extends RecyclerView.Adapter {
45 |
46 | private final RendererBuilder rendererBuilder;
47 | private final List collection;
48 |
49 | public RendererAdapter(RendererBuilder rendererBuilder) {
50 | this(rendererBuilder, new ArrayList(10));
51 | }
52 |
53 | public RendererAdapter(RendererBuilder rendererBuilder, List collection) {
54 | this.rendererBuilder = rendererBuilder;
55 | this.collection = collection;
56 | }
57 |
58 | public RendererAdapter into(RecyclerView recyclerView) {
59 | recyclerView.setAdapter(this);
60 | return this;
61 | }
62 |
63 | @Override
64 | public int getItemCount() {
65 | return collection.size();
66 | }
67 |
68 | public T getItem(int position) {
69 | return collection.get(position);
70 | }
71 |
72 | @Override
73 | public long getItemId(int position) {
74 | return position;
75 | }
76 |
77 | /**
78 | * Indicate to the RecyclerView the type of Renderer used to one position using a numeric value.
79 | *
80 | * @param position to analyze.
81 | * @return the id associated to the Renderer used to render the content given a position.
82 | */
83 | @Override
84 | public int getItemViewType(int position) {
85 | T content = getItem(position);
86 | return rendererBuilder.getItemViewType(content);
87 | }
88 |
89 | /**
90 | * One of the two main methods in this class. Creates a RendererViewHolder instance with a
91 | * Renderer inside ready to be used. The RendererBuilder to create a RendererViewHolder using the
92 | * information given as parameter.
93 | *
94 | * @param viewGroup used to create the ViewHolder.
95 | * @param viewType associated to the renderer.
96 | * @return ViewHolder extension with the Renderer it has to use inside.
97 | */
98 | @Override
99 | public RendererViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
100 | rendererBuilder.withParent(viewGroup);
101 | rendererBuilder.withLayoutInflater(LayoutInflater.from(viewGroup.getContext()));
102 | rendererBuilder.withViewType(viewType);
103 | RendererViewHolder viewHolder = rendererBuilder.buildRendererViewHolder();
104 | if (viewHolder == null) {
105 | throw new NullRendererBuiltException("RendererBuilder have to return a not null viewHolder");
106 | }
107 | return viewHolder;
108 | }
109 |
110 | /**
111 | * Given a RendererViewHolder passed as argument and a position renders the view using the
112 | * Renderer previously stored into the RendererViewHolder.
113 | *
114 | * @param viewHolder with a Renderer class inside.
115 | * @param position to render.
116 | */
117 | @Override
118 | public void onBindViewHolder(RendererViewHolder viewHolder, int position) {
119 | onBindViewHolder(viewHolder, position, Collections.emptyList());
120 | }
121 |
122 | @Override
123 | public void onBindViewHolder(RendererViewHolder viewHolder, int position, List payloads) {
124 | T content = getItem(position);
125 | Renderer renderer = viewHolder.getRenderer();
126 | if (renderer == null) {
127 | throw new NullRendererBuiltException("RendererBuilder have to return a not null renderer");
128 | }
129 | renderer.setContent(content);
130 | renderer.setPosition(position);
131 | updateRendererExtraValues(content, renderer, position);
132 | renderer.render(payloads);
133 | }
134 |
135 | @Override public void onViewAttachedToWindow(RendererViewHolder viewHolder) {
136 | super.onViewAttachedToWindow(viewHolder);
137 | Renderer renderer = viewHolder.getRenderer();
138 | renderer.onAttached();
139 | }
140 |
141 | @Override public void onViewDetachedFromWindow(RendererViewHolder viewHolder) {
142 | Renderer renderer = viewHolder.getRenderer();
143 | renderer.onDetached();
144 | super.onViewDetachedFromWindow(viewHolder);
145 | }
146 |
147 | @Override public void onViewRecycled(RendererViewHolder viewHolder) {
148 | Renderer renderer = viewHolder.getRenderer();
149 | renderer.onRecycled();
150 | super.onViewRecycled(viewHolder);
151 | }
152 |
153 | /**
154 | * @see List#add(Object)
155 | */
156 | public boolean add(Object element) {
157 | return collection.add((T) element);
158 | }
159 |
160 | /**
161 | * @see List#add(Object)
162 | * @see RecyclerView.Adapter#notifyItemInserted(int)
163 | */
164 | public boolean addAndNotify(Object element) {
165 | boolean result = add(element);
166 | notifyItemInserted(collection.size());
167 | return result;
168 | }
169 |
170 | /**
171 | * Convenient add method that also supports negative index to specify
172 | * that the addition should be done at the end of the list.
173 | *
174 | * @see List#add(int, Object)
175 | */
176 | public void add(int index, Object element) {
177 | if (index < 0) {
178 | add(element);
179 | } else {
180 | collection.add(index, (T) element);
181 | }
182 | }
183 |
184 | /**
185 | * Convenient add method that also supports negative index to specify
186 | * that the addition should be done at the end of the list.
187 | *
188 | * @see List#add(int, Object)
189 | * @see RecyclerView.Adapter#notifyItemInserted(int)
190 | */
191 | public void addAndNotify(int index, Object element) {
192 | add(index, element);
193 | if (index < 0) {
194 | index = collection.size();
195 | }
196 | notifyItemInserted(index);
197 | }
198 |
199 | /**
200 | * @see List#set(int, Object)
201 | */
202 | public T update(int index, Object element) {
203 | return collection.set(index, (T) element);
204 | }
205 |
206 | /**
207 | * @see List#set(int, Object)
208 | * @see RecyclerView.Adapter#notifyItemChanged(int)
209 | */
210 | public T updateAndNotify(int index, Object element) {
211 | return updateAndNotify(index, element, null);
212 | }
213 |
214 | /**
215 | * @see List#set(int, Object)
216 | * @see RecyclerView.Adapter#notifyItemChanged(int, Object)
217 | */
218 | public T updateAndNotify(int index, Object element, @Nullable Object payload) {
219 | T set = update(index, element);
220 | notifyItemChanged(index, payload);
221 | return set;
222 | }
223 |
224 | /**
225 | * @see RendererAdapter#removeAt(int)
226 | * @see RendererAdapter#add(int, Object)
227 | */
228 | public void move(int currentPosition, int newPosition, Object element) {
229 | removeAt(currentPosition);
230 | add(newPosition, element);
231 | }
232 |
233 | /**
234 | * @see RendererAdapter#move(int, int, Object)
235 | * @see RecyclerView.Adapter#notifyItemMoved(int, int)
236 | */
237 | public void moveAndNotify(int currentPosition, int newPosition, Object element) {
238 | move(currentPosition, newPosition, element);
239 | notifyItemMoved(currentPosition, newPosition);
240 | }
241 |
242 | /**
243 | * @see List#remove(Object)
244 | */
245 | public boolean remove(Object element) {
246 | return collection.remove(element);
247 | }
248 |
249 | /**
250 | * @see List#remove(int)
251 | * @see RecyclerView.Adapter#notifyItemRemoved(int)
252 | */
253 | public Object removeAndNotify(Object element) {
254 | int indexOf = collection.indexOf(element);
255 | return removeAtAndNotify(indexOf);
256 | }
257 |
258 | /**
259 | * @see List#remove(int)
260 | */
261 | public T removeAt(int location) {
262 | return collection.remove(location);
263 | }
264 |
265 | /**
266 | * @see List#remove(int)
267 | * @see RecyclerView.Adapter#notifyItemRemoved(int)
268 | */
269 | public Object removeAtAndNotify(int indexOf) {
270 | Object remove = removeAt(indexOf);
271 | notifyItemRemoved(indexOf);
272 | return remove;
273 | }
274 |
275 | /**
276 | * @see List#addAll(Collection)
277 | */
278 | public boolean addAll(Collection elements) {
279 | return collection.addAll(elements);
280 | }
281 |
282 | /**
283 | * @see List#addAll(int, Collection)
284 | */
285 | public boolean addAll(int index, Collection elements) {
286 | return collection.addAll(index, elements);
287 | }
288 |
289 | /**
290 | * @see List#addAll(Collection)
291 | * @see RecyclerView.Adapter#notifyItemRangeInserted(int, int)
292 | */
293 | public boolean addAllAndNotify(Collection elements) {
294 | int size = collection.size();
295 | boolean result = addAll(elements);
296 | notifyItemRangeInserted(size, elements.size());
297 | return result;
298 | }
299 |
300 | /**
301 | * @see List#addAll(int, Collection)
302 | * @see RecyclerView.Adapter#notifyItemRangeInserted(int, int)
303 | */
304 | public boolean addAllAndNotify(int index, Collection elements) {
305 | boolean result = addAll(index, elements);
306 | notifyItemRangeInserted(index, elements.size());
307 | return result;
308 | }
309 |
310 | /**
311 | * @see List#removeAll(Collection)
312 | */
313 | public boolean removeAll(Collection> elements) {
314 | return collection.removeAll(elements);
315 | }
316 |
317 | /**
318 | * @see List#removeAll(Collection)
319 | * @see Adapter#notifyDataSetChanged()
320 | */
321 | public boolean removeAllAndNotify(Collection> elements) {
322 | boolean result = removeAll(elements);
323 | notifyDataSetChanged();
324 | return result;
325 | }
326 |
327 | /**
328 | * @see List#clear()
329 | */
330 | public void clear() {
331 | collection.clear();
332 | }
333 |
334 | /**
335 | * @see List#clear()
336 | * @see Adapter#notifyDataSetChanged()
337 | */
338 | public void clearAndNotify() {
339 | clear();
340 | notifyDataSetChanged();
341 | }
342 |
343 | /**
344 | * @see List#indexOf(Object)
345 | */
346 | public int indexOf(Object object) {
347 | return collection.indexOf(object);
348 | }
349 |
350 | /**
351 | * @see List#contains(Object)
352 | */
353 | public boolean contains(Object object) {
354 | return collection.contains(object);
355 | }
356 |
357 | /**
358 | * @see List#containsAll(Collection)
359 | */
360 | public boolean containsAll(Collection object) {
361 | return collection.containsAll(object);
362 | }
363 |
364 | /**
365 | * Allows the client code to access the List from subtypes of RendererAdapter.
366 | *
367 | * @return list used in the adapter.
368 | */
369 | public List getCollection() {
370 | return collection;
371 | }
372 |
373 | /**
374 | * Empty implementation created to allow the client code to extend this class without override
375 | * getView method.
376 | *
377 | * This method is called before render the Renderer and can be used in RendererAdapter extension
378 | * to add extra info to the renderer created like the position in the ListView/RecyclerView.
379 | *
380 | * @param content to be rendered.
381 | * @param renderer to be used to paint the content.
382 | * @param position of the content.
383 | */
384 | @SuppressWarnings("UnusedParameters")
385 | protected void updateRendererExtraValues(T content, Renderer renderer, int position) { }
386 | }
387 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/RendererBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers;
17 |
18 | import android.support.v4.util.ArrayMap;
19 | import android.support.v7.util.DiffUtil;
20 | import android.util.SparseArray;
21 | import android.view.LayoutInflater;
22 | import android.view.ViewGroup;
23 |
24 | import com.pedrogomez.renderers.exception.NeedsPrototypesException;
25 | import com.pedrogomez.renderers.exception.NullContentException;
26 | import com.pedrogomez.renderers.exception.NullLayoutInflaterException;
27 | import com.pedrogomez.renderers.exception.NullParentException;
28 | import com.pedrogomez.renderers.exception.NullPrototypeClassException;
29 | import com.pedrogomez.renderers.exception.PrototypeNotFoundException;
30 |
31 | import java.util.ArrayList;
32 | import java.util.Collections;
33 | import java.util.LinkedList;
34 | import java.util.List;
35 | import java.util.Map;
36 |
37 | /**
38 | * Class created to work as builder for Renderer objects. This class provides methods to create a
39 | * Renderer instances using a fluent API.
40 | *
41 | * The library users have to extends RendererBuilder and create a new one with prototypes. The
42 | * RendererBuilder implementation will have to declare the mapping between objects from the
43 | * List and Renderer instances passed to the prototypes collection.
44 | *
45 | * This class is not going to implement the view recycling if is used with the RecyclerView widget
46 | * because RecyclerView class already implements the view recycling for us.
47 | *
48 | * @author Pedro Vicente Gómez Sánchez
49 | */
50 | @SuppressWarnings({"deprecation", "unused"})
51 | public class RendererBuilder {
52 |
53 | private ViewGroup parent;
54 | private LayoutInflater layoutInflater;
55 | private Integer viewType;
56 |
57 | protected List prototypes;
58 | protected final Map, Class extends Renderer>> binding;
59 | protected final SparseArray> typeBindings = new SparseArray<>(0);
60 |
61 | /**
62 | * Initializes a RendererBuilder with an empty prototypes collection. Using this constructor some
63 | * binding configuration is needed.
64 | *
65 | * @deprecated Use {@link #create()} or {@link #create(Renderer)} for builder-like creation
66 | */
67 | @Deprecated
68 | public RendererBuilder() {
69 | this(new LinkedList());
70 | }
71 |
72 | /**
73 | * Initializes a RendererBuilder with just one prototype. Using this constructor the prototype
74 | * used will be always the same and the additional binding configuration wont be needed.
75 | *
76 | * @deprecated Use {@link #create()} or {@link #create(Renderer)} for builder-like creation
77 | */
78 | @Deprecated
79 | public RendererBuilder(Renderer renderer) {
80 | this(Collections.singletonList(renderer));
81 | }
82 |
83 | /**
84 | * Initializes a RendererBuilder with a list of prototypes. Using this constructor some
85 | * binding configuration is needed.
86 | *
87 | * @deprecated Use {@link #create()} or {@link #create(Renderer)} for builder-like creation
88 | */
89 | @Deprecated
90 | public RendererBuilder(List prototypes) {
91 | if (prototypes == null) {
92 | throw new NeedsPrototypesException("RendererBuilder has to be created with a non null collection of"
93 | + "Collection(1);
97 | }
98 |
99 | /**
100 | * Initializes a RendererBuilder without Renderers. Using this constructor some
101 | * binding configuration is needed.
102 | */
103 | public static ExtendedRendererBuilder create() {
104 | return new Builder<>(new RendererBuilder());
105 | }
106 |
107 | /**
108 | * Initializes a RendererBuilder with just one prototype. Using this constructor the prototype
109 | * used will be always the same for any type added.
110 | */
111 | public static SimpleRendererBuilder create(Renderer renderer) {
112 | return new Builder<>(new RendererBuilder<>(renderer));
113 | }
114 |
115 | /**
116 | * Get access to the prototypes collection used to create one RendererBuilder.
117 | *
118 | * @return prototypes list.
119 | */
120 | public final List getPrototypes() {
121 | return prototypes;
122 | }
123 |
124 | /**
125 | * Configure prototypes used as Renderer instances.
126 | *
127 | * @param prototypes to use by the builder in order to create Renderer instances.
128 | * @return the current RendererBuilder instance.
129 | */
130 | public RendererBuilder withPrototypes(List prototypes) {
131 | if (prototypes == null) {
132 | throw new NeedsPrototypesException("RendererBuilder has to be created with a non null collection of"
133 | + "List to provide new or recycled Renderer instances");
134 | }
135 | this.prototypes.addAll(prototypes);
136 | return this;
137 | }
138 |
139 |
140 | RendererBuilder withParent(ViewGroup parent) {
141 | this.parent = parent;
142 | return this;
143 | }
144 |
145 | RendererBuilder withLayoutInflater(LayoutInflater layoutInflater) {
146 | this.layoutInflater = layoutInflater;
147 | return this;
148 | }
149 |
150 | RendererBuilder withViewType(Integer viewType) {
151 | this.viewType = viewType;
152 | return this;
153 | }
154 |
155 | /**
156 | * Main method of this class related to RecyclerView widget. This method is the responsible of
157 | * create a new Renderer instance with all the needed information to implement the rendering.
158 | * This method will validate all the attributes passed in the builder constructor and will create
159 | * a RendererViewHolder instance.
160 | *
161 | * This method is used with RecyclerView because the view recycling mechanism is implemented out
162 | * of this class and we only have to return new RendererViewHolder instances.
163 | *
164 | * @return ready to use RendererViewHolder instance.
165 | */
166 | protected RendererViewHolder buildRendererViewHolder() {
167 | validateAttributesToCreateANewRendererViewHolder();
168 |
169 | Renderer renderer = getPrototypeByIndex(viewType).copy();
170 | renderer.onCreate(null, layoutInflater, parent);
171 | return new RendererViewHolder(renderer);
172 | }
173 |
174 | /**
175 | * Gets one prototype using the prototype index which is equals to the view type. This method
176 | * has to be implemented because prototypes member is declared with Collection and that interface
177 | * doesn't allow the client code to get one element by index.
178 | *
179 | * @param prototypeIndex used to search.
180 | * @return prototype renderer.
181 | */
182 | protected Renderer getPrototypeByIndex(int prototypeIndex) {
183 | return prototypes.get(prototypeIndex);
184 | }
185 |
186 | private static void validatePrototypeClass(Class prototypeClass) {
187 | if (prototypeClass == null) {
188 | throw new NullPrototypeClassException("Your getPrototypeClass method implementation can't return a null class");
189 | }
190 | }
191 |
192 | /**
193 | * Return the item view type used by the adapter to implement recycle mechanism.
194 | *
195 | * @param content to be rendered.
196 | * @return an integer that represents the renderer inside the adapter.
197 | */
198 | int getItemViewType(T content) {
199 | Class prototypeClass = getPrototypeClass(content);
200 | validatePrototypeClass(prototypeClass);
201 | return getItemViewType(prototypeClass);
202 | }
203 |
204 | /**
205 | * Return the Renderer class associated to the prototype.
206 | *
207 | * @param prototypeClass used to search the renderer in the prototypes collection.
208 | * @return the prototype index associated to the prototypeClass.
209 | */
210 | private int getItemViewType(Class prototypeClass) {
211 | int itemViewType = -1;
212 | for (int i = 0, prototypesSize = prototypes.size(); i < prototypesSize; i++) {
213 | Renderer renderer = prototypes.get(i);
214 | if (renderer.getClass().equals(prototypeClass)) {
215 | itemViewType = i;
216 | break;
217 | }
218 | }
219 | if (itemViewType == -1) {
220 | throw new PrototypeNotFoundException("Review your RendererBuilder implementation, you are returning one"
221 | + " prototype class not found in prototypes collection");
222 | }
223 | return itemViewType;
224 | }
225 |
226 | /**
227 | * Throws one RendererException if the viewType, layoutInflater or parent are null.
228 | */
229 | private void validateAttributesToCreateANewRendererViewHolder() {
230 | if (viewType == null) {
231 | throw new NullContentException("RendererBuilder needs a view type to create a RendererViewHolder");
232 | }
233 | if (layoutInflater == null) {
234 | throw new NullLayoutInflaterException("RendererBuilder needs a LayoutInflater to create a RendererViewHolder");
235 | }
236 | if (parent == null) {
237 | throw new NullParentException("RendererBuilder needs a parent to create a RendererViewHolder");
238 | }
239 | }
240 |
241 | /**
242 | * Method to be implemented by the RendererBuilder subtypes. In this method the library user will
243 | * define the mapping between content and renderer class.
244 | *
245 | * @param content used to map object to Renderers.
246 | * @return the class associated to the renderer.
247 | */
248 | protected Class getPrototypeClass(T content) {
249 | if (typeBindings.size() != 0 && content instanceof RendererContent) {
250 | RendererContent rendererContent = (RendererContent) content;
251 | Class extends Renderer> renderer = typeBindings.get(rendererContent.getType());
252 | if (renderer != null) {
253 | return renderer;
254 | }
255 | }
256 |
257 | if (prototypes.size() == 1) {
258 | return prototypes.get(0).getClass();
259 | }
260 |
261 | Class> aClass = content.getClass();
262 | //noinspection SSBasedInspection
263 | for (Map.Entry, Class extends Renderer>> entry : binding.entrySet()) {
264 | if (entry.getKey().isAssignableFrom(aClass)) {
265 | return entry.getValue();
266 | }
267 | }
268 |
269 | throw new PrototypeNotFoundException("No prototype was found for the class " + aClass.getSimpleName());
270 | }
271 |
272 | /*******************************************************************
273 | * Step builder pattern http://www.svlada.com/step-builder-pattern *
274 | *******************************************************************/
275 |
276 | public interface BaseRendererBuilder {
277 | RendererBuilder getRendererBuilder();
278 | }
279 |
280 | public interface SimpleRendererBuilder extends BaseRendererBuilder {
281 | RendererAdapter build();
282 |
283 | RendererAdapter buildWith(List collection);
284 | }
285 |
286 | public interface BindedExtendedRendererBuilder extends ExtendedRendererBuilder {
287 | RendererAdapter build();
288 |
289 | RendererAdapter buildWith(List collection);
290 |
291 | AsyncRendererAdapter build(DiffUtil.ItemCallback listDiffer);
292 | }
293 |
294 | public interface ExtendedRendererBuilder extends BaseRendererBuilder {
295 | BindedExtendedRendererBuilder bind(Class extends Type> clx, Renderer prototype);
296 |
297 | BindedExtendedRendererBuilder bind(int type, Renderer> prototype);
298 | }
299 |
300 | public static class Builder implements SimpleRendererBuilder, BindedExtendedRendererBuilder {
301 |
302 | protected final RendererBuilder rendererBuilder;
303 |
304 | public Builder(RendererBuilder rendererBuilder) {
305 | this.rendererBuilder = rendererBuilder;
306 | }
307 |
308 | @Override public RendererAdapter build() {
309 | return buildWith(new ArrayList(10));
310 | }
311 |
312 | @Override public RendererAdapter buildWith(List collection) {
313 | return new RendererAdapter<>(rendererBuilder, collection);
314 | }
315 |
316 | @Override public RendererBuilder getRendererBuilder() {
317 | return rendererBuilder;
318 | }
319 |
320 | @Override public AsyncRendererAdapter build(DiffUtil.ItemCallback listDiffer) {
321 | return new AsyncRendererAdapter<>(rendererBuilder, listDiffer);
322 | }
323 |
324 | /**
325 | * Given a class configures the binding between a class and a Renderer class.
326 | *
327 | * @param clx to bind.
328 | * @param prototype used as Renderer.
329 | * @return the current RendererBuilder instance.
330 | */
331 | @Override public BindedExtendedRendererBuilder bind(Class clx, Renderer prototype) {
332 | if (clx == null || prototype == null) {
333 | throw new IllegalArgumentException("The binding RecyclerView binding can't be configured using null "
334 | + "instances");
335 | }
336 | if (clx.equals(Object.class)) {
337 | throw new IllegalArgumentException("Making a bind to the Object class means that every item will be mapped "
338 | + "to the specified Renderer and thus all other bindings are invalidated. Please use the standard "
339 | + "constructor for that");
340 | }
341 | rendererBuilder.prototypes.add(prototype);
342 | rendererBuilder.binding.put(clx, prototype.getClass());
343 |
344 | return this;
345 | }
346 |
347 | /**
348 | * Binds a custom type to a given {@link Renderer}.
349 | *
350 | * @param type Integer type.
351 | * @param prototype used as Renderer.
352 | */
353 | @Override public BindedExtendedRendererBuilder bind(int type, Renderer prototype) {
354 | if (prototype == null) {
355 | throw new IllegalArgumentException("The binding RecyclerView binding can't be configured using null "
356 | + "instances");
357 | }
358 | rendererBuilder.typeBindings.put(type, prototype.getClass());
359 | rendererBuilder.prototypes.add(prototype);
360 |
361 | return this;
362 | }
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/RendererContent.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | /**
4 | * Wrapper to use with {@link RendererBuilder} for type or class bindings.
5 | *
6 | * @author alberto.ballano
7 | */
8 | @SuppressWarnings("unused")
9 | public class RendererContent {
10 |
11 | private T item;
12 | private int type = -1;
13 |
14 | /**
15 | * @param item Content of the wrapper.
16 | * @param type The type within the list.
17 | */
18 | public RendererContent(T item, int type) {
19 | this.item = item;
20 | this.type = type;
21 | }
22 |
23 | public T getItem() {
24 | return item;
25 | }
26 |
27 | public void setItem(T item) {
28 | this.item = item;
29 | }
30 |
31 | public int getType() {
32 | return type;
33 | }
34 |
35 | @Override
36 | public boolean equals(Object o) {
37 | if (this == o) return true;
38 | if (!(o instanceof RendererContent)) return false;
39 |
40 | RendererContent> content = (RendererContent>) o;
41 |
42 | return type == content.type && (item != null ? item.equals(content.item) : content.item == null);
43 | }
44 |
45 | @Override
46 | public int hashCode() {
47 | int result = item != null ? item.hashCode() : 0;
48 | result = 31 * result + type;
49 | return result;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/RendererViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers;
17 |
18 | import android.support.v7.widget.RecyclerView;
19 |
20 | /**
21 | * RecyclerView.ViewHolder extension created to be able to use Renderer classes in RecyclerView
22 | * widgets. This class will be completely hidden to the library clients.
23 | */
24 | public class RendererViewHolder extends RecyclerView.ViewHolder {
25 |
26 | private final Renderer renderer;
27 |
28 | public RendererViewHolder(Renderer renderer) {
29 | super(renderer.getRootView());
30 | this.renderer = renderer;
31 | }
32 |
33 | public Renderer getRenderer() {
34 | return renderer;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/SerializableRendererContent.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Wrapper to use with {@link RendererBuilder} for type or class bindings that implements the serializable interface.
7 | *
8 | * @author angelo.marchesin
9 | */
10 | @SuppressWarnings("unused")
11 | public class SerializableRendererContent extends RendererContent implements Serializable {
12 |
13 | /**
14 | * @param item Content of the wrapper.
15 | * @param type The type within the list.
16 | */
17 | public SerializableRendererContent(T item, int type) {
18 | super(item, type);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/ViewRenderer.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Generic renderer to easily wrap Views for being used in the adapter.
12 | *
13 | * @param The type of the content used by the view.
14 | * @param The View type.
15 | * @author alberto.ballano
16 | */
17 | @SuppressWarnings("unused")
18 | public class ViewRenderer extends Renderer {
19 | private final InflateFunction initFunc;
20 | private final RenderFunction renderFunc;
21 | private U view;
22 |
23 | /**
24 | * @param initFunc Function for the inflate process.
25 | * @param renderFunc Function for the render process.
26 | */
27 | public ViewRenderer(InflateFunction initFunc, RenderFunction renderFunc) {
28 | this.initFunc = initFunc;
29 | this.renderFunc = renderFunc;
30 | }
31 |
32 | @Override
33 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
34 | return initFunc.inflate(parent.getContext());
35 | }
36 |
37 | @Override
38 | public void render(List payloads) {
39 | //noinspection unchecked
40 | renderFunc.render(getContent(), (U) getRootView());
41 | }
42 |
43 | /** Inflate function interface */
44 | public interface InflateFunction {
45 | /** Called when the inflation is taking place. Should return the inflated view. */
46 | V inflate(Context context);
47 | }
48 |
49 | /** Render function interface */
50 | public interface RenderFunction {
51 | /** Called when the render is taking place. Should setup the view. */
52 | void render(W w, X x);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NeedsPrototypesException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when a RendererBuilder be created or configured without any
20 | * prototype. A RendererBuilder implementation needs prototypes to create or recycle new Renderer
21 | * instances.
22 | *
23 | * @author Pedro Vicente Gómez Sánchez.
24 | */
25 | public class NeedsPrototypesException extends RendererException {
26 |
27 | public NeedsPrototypesException(String detailMessage) {
28 | super(detailMessage);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NotInflateViewException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when any renderer is not inflating a view. All Renderer instances
20 | * have to inflate a view and return it in inflateView method.
21 | *
22 | * @author Pedro Vicente Gómez Sánchez.
23 | */
24 | public class NotInflateViewException extends RendererException {
25 |
26 | public NotInflateViewException(String detailMessage) {
27 | super(detailMessage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NullContentException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when a RendererBuilder is created without content.
20 | * RendererBuilder needs a content to create Renderer instances.
21 | *
22 | * @author Pedro Vicente Gómez Sánchez.
23 | */
24 | public class NullContentException extends RendererException {
25 |
26 | public NullContentException(String detailMessage) {
27 | super(detailMessage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NullLayoutInflaterException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when a RendererBuilder is created without a LayoutInflater
20 | * instance. RendererBuilder needs one LayoutInflater to pass it as parameter to Renderer instances
21 | * in order to be able to inflate the view associated to the Renderer.
22 | *
23 | * @author Pedro Vicente Gómez Sánchez.
24 | */
25 | public class NullLayoutInflaterException extends RendererException {
26 |
27 | public NullLayoutInflaterException(String detailMessage) {
28 | super(detailMessage);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NullParentException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when a RendererBuilder is created without parent. RendererBuilder
20 | * needs a ViewGroup parent to pass it as parameter to Renderer instances.
21 | *
22 | * @author Pedro Vicente Gómez Sánchez.
23 | */
24 | public class NullParentException extends RendererException {
25 |
26 | public NullParentException(String detailMessage) {
27 | super(detailMessage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NullPrototypeClassException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * RendererException created to be thrown when the RendererBuilder implementation returns a null
20 | * prototype class.
21 | *
22 | * @author Pedro Vicente Gómez Sánchez.
23 | */
24 | public class NullPrototypeClassException extends RendererException {
25 |
26 | public NullPrototypeClassException(String detailMessage) {
27 | super(detailMessage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/NullRendererBuiltException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Exception created to be thrown when a RendererBuilder returns a null Renderer instance. Your
20 | * RendererBuilder always have to return a built renderer.
21 | *
22 | * @author Pedro Vicente Gómez Sánchez.
23 | */
24 | public class NullRendererBuiltException extends RendererException {
25 |
26 | public NullRendererBuiltException(String detailMessage) {
27 | super(detailMessage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/PrototypeNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers.exception;
2 |
3 | /**
4 | * Exception created to be thrown when RendererBuilders returns one Renderer class not found in
5 | * prototypes collection.
6 | *
7 | * @author Pedro Vicente Gómez Sánchez.
8 | */
9 | public class PrototypeNotFoundException extends RendererException {
10 |
11 | public PrototypeNotFoundException(String detailMessage) {
12 | super(detailMessage);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/renderers/src/main/java/com/pedrogomez/renderers/exception/RendererException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.exception;
17 |
18 | /**
19 | * Top class in the renderer exception hierarchy.
20 | *
21 | * @author Pedro Vicente Gómez Sánchez.
22 | */
23 | public class RendererException extends RuntimeException {
24 |
25 | public RendererException(String detailMessage) {
26 | super(detailMessage);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/ObjectRenderer.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Renderer created only for testing purposes.
11 | *
12 | * @author Pedro Vicente Gómez Sánchez.
13 | */
14 | public class ObjectRenderer extends Renderer {
15 |
16 | private View view;
17 |
18 | @Override
19 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
20 | return view;
21 | }
22 |
23 | @Override
24 | public void render(List payloads) { }
25 |
26 | public void setView(View view) {
27 | this.view = view;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/ObjectRendererBuilder.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * RendererBuilder created only for testing purposes.
7 | *
8 | * @author Pedro Vicente Gómez Sánchez.
9 | */
10 | public class ObjectRendererBuilder extends RendererBuilder {
11 |
12 | public ObjectRendererBuilder(List prototypes) {
13 | super(prototypes);
14 | }
15 |
16 | @Override
17 | protected Class getPrototypeClass(Object content) {
18 | return null;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/ObjectRendererContentRenderer.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Renderer created only for testing purposes.
11 | *
12 | * @author alberto.ballano
13 | */
14 | public class ObjectRendererContentRenderer extends Renderer> {
15 |
16 | private View view;
17 |
18 | @Override
19 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
20 | return view;
21 | }
22 |
23 | @Override
24 | public void render(List payloads) { }
25 |
26 | public void setView(View view) {
27 | this.view = view;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/RendererAdapterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers;
17 |
18 | import android.support.v7.widget.RecyclerView;
19 | import android.view.LayoutInflater;
20 | import android.view.View;
21 | import android.view.ViewGroup;
22 |
23 | import com.github.pedrovgs.renderers.BuildConfig;
24 | import com.pedrogomez.renderers.exception.NullRendererBuiltException;
25 |
26 | import org.junit.Before;
27 | import org.junit.Test;
28 | import org.junit.runner.RunWith;
29 | import org.mockito.Mock;
30 | import org.mockito.MockitoAnnotations;
31 | import org.robolectric.RobolectricTestRunner;
32 | import org.robolectric.RuntimeEnvironment;
33 | import org.robolectric.annotation.Config;
34 |
35 | import java.util.Collection;
36 | import java.util.Collections;
37 | import java.util.LinkedList;
38 | import java.util.List;
39 |
40 | import static org.junit.Assert.assertEquals;
41 | import static org.mockito.Matchers.notNull;
42 | import static org.mockito.Mockito.spy;
43 | import static org.mockito.Mockito.verify;
44 | import static org.mockito.Mockito.when;
45 |
46 | @Config(sdk = 19, constants = BuildConfig.class)
47 | @RunWith(RobolectricTestRunner.class)
48 | public class RendererAdapterTest {
49 |
50 | private static final int ANY_SIZE = 11;
51 | private static final int ANY_POSITION = 2;
52 | private static final Object ANY_OBJECT = new Object();
53 | private static final Object ANY_OTHER_OBJECT = new Object();
54 | private static final Collection ANY_OBJECT_COLLECTION = new LinkedList<>();
55 | private static final int ANY_ITEM_VIEW_TYPE = 3;
56 |
57 | private RendererAdapter adapter;
58 |
59 | @Mock private RendererBuilder mockedRendererBuilder;
60 | @Mock private List mockedCollection;
61 | @Mock private View mockedConvertView;
62 | @Mock private ViewGroup mockedParent;
63 | @Mock private ObjectRenderer mockedRenderer;
64 | @Mock private View mockedView;
65 | @Mock private RendererViewHolder mockedRendererViewHolder;
66 | @Mock private RecyclerView mockedRecyclerView;
67 |
68 | @Before
69 | public void setUp() throws Exception {
70 | initializeMocks();
71 | initializeRendererAdapter();
72 | }
73 |
74 | @Test
75 | public void shouldReturnTheCollection() {
76 | assertEquals(mockedCollection, adapter.getCollection());
77 | }
78 |
79 | @Test
80 | public void shouldReturnCollectionSizeOnGetCount() {
81 | when(mockedCollection.size()).thenReturn(ANY_SIZE);
82 |
83 | assertEquals(ANY_SIZE, adapter.getItemCount());
84 | }
85 |
86 | @Test
87 | public void shouldReturnItemAtCollectionPositionOnGetItem() {
88 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
89 | }
90 |
91 | @Test
92 | public void shouldReturnPositionAsItemId() {
93 | assertEquals(ANY_POSITION, adapter.getItemId(ANY_POSITION));
94 | }
95 |
96 | @Test
97 | public void shouldDelegateIntoRendererBuilderToGetItemViewType() {
98 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
99 | when(mockedRendererBuilder.getItemViewType(ANY_OBJECT)).thenReturn(ANY_ITEM_VIEW_TYPE);
100 |
101 | assertEquals(ANY_ITEM_VIEW_TYPE, adapter.getItemViewType(ANY_POSITION));
102 | }
103 |
104 | @Test
105 | public void shouldBuildRendererUsingAllNeededDependencies() {
106 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
107 | when(mockedRendererBuilder.buildRendererViewHolder()).thenReturn(mockedRendererViewHolder);
108 |
109 | adapter.onCreateViewHolder(mockedParent, ANY_ITEM_VIEW_TYPE);
110 |
111 | verify(mockedRendererBuilder).withParent(mockedParent);
112 | verify(mockedRendererBuilder).withLayoutInflater((LayoutInflater) notNull());
113 | verify(mockedRendererBuilder).withViewType(ANY_ITEM_VIEW_TYPE);
114 | verify(mockedRendererBuilder).buildRendererViewHolder();
115 | }
116 |
117 | @Test
118 | public void shouldGetRendererFromViewHolderAndCallUpdateRendererExtraValuesOnBind() {
119 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
120 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
121 |
122 | adapter.onBindViewHolder(mockedRendererViewHolder, ANY_POSITION);
123 |
124 | verify(adapter).updateRendererExtraValues(ANY_OBJECT, mockedRenderer, ANY_POSITION);
125 | }
126 |
127 | @Test
128 | public void shouldForwardAttachEvent() {
129 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
130 |
131 | adapter.onViewAttachedToWindow(mockedRendererViewHolder);
132 |
133 | verify(mockedRenderer).onAttached();
134 | }
135 |
136 | @Test
137 | public void shouldForwardDetachEvent() {
138 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
139 |
140 | adapter.onViewDetachedFromWindow(mockedRendererViewHolder);
141 |
142 | verify(mockedRenderer).onDetached();
143 | }
144 |
145 | @Test
146 | public void shouldForwardRecycleEvent() {
147 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
148 |
149 | adapter.onViewRecycled(mockedRendererViewHolder);
150 |
151 | verify(mockedRenderer).onRecycled();
152 | }
153 |
154 | @Test(expected = NullRendererBuiltException.class)
155 | public void shouldThrowNullRendererBuiltException() {
156 | adapter.onCreateViewHolder(mockedParent, ANY_ITEM_VIEW_TYPE);
157 | }
158 |
159 | @Test
160 | public void shouldAddElementToCollection() {
161 | when(mockedCollection.size()).thenReturn(ANY_SIZE);
162 | adapter.addAndNotify(ANY_OBJECT);
163 |
164 | verify(mockedCollection).add(ANY_OBJECT);
165 | verify(adapter).notifyItemInserted(ANY_SIZE);
166 | }
167 |
168 | @Test
169 | public void shouldAddElementAtPositionToCollection() {
170 | adapter.addAndNotify(0, ANY_OBJECT);
171 |
172 | verify(mockedCollection).add(0, ANY_OBJECT);
173 | verify(adapter).notifyItemInserted(0);
174 | }
175 |
176 | @Test
177 | public void shouldAddElementAtEndPositionToCollection() {
178 | when(mockedCollection.size()).thenReturn(ANY_SIZE);
179 | adapter.addAndNotify(-1, ANY_OBJECT);
180 |
181 | verify(mockedCollection).add(ANY_OBJECT);
182 | verify(adapter).notifyItemInserted(ANY_SIZE);
183 | }
184 |
185 | @Test
186 | public void shouldAddAllElementsToCollection() {
187 | when(mockedCollection.size()).thenReturn(ANY_SIZE);
188 | adapter.addAllAndNotify(ANY_OBJECT_COLLECTION);
189 |
190 | verify(mockedCollection).addAll(ANY_OBJECT_COLLECTION);
191 | verify(adapter).notifyItemRangeInserted(ANY_SIZE, ANY_OBJECT_COLLECTION.size());
192 | }
193 |
194 | @Test
195 | public void shouldAddAllElementsAtPositionToCollection() {
196 | adapter.addAllAndNotify(0, ANY_OBJECT_COLLECTION);
197 |
198 | verify(mockedCollection).addAll(0, ANY_OBJECT_COLLECTION);
199 | verify(adapter).notifyItemRangeInserted(0, ANY_OBJECT_COLLECTION.size());
200 | }
201 |
202 | @Test
203 | public void shouldRemoveElementFromCollection() {
204 | adapter.remove(ANY_OBJECT);
205 | verify(mockedCollection).remove(ANY_OBJECT);
206 | }
207 |
208 | @Test
209 | public void shouldRemoveElementFromCollection2() {
210 | when(mockedCollection.indexOf(ANY_OBJECT)).thenReturn(ANY_SIZE);
211 | adapter.removeAndNotify(ANY_OBJECT);
212 |
213 | verify(mockedCollection).remove(ANY_SIZE);
214 | verify(adapter).notifyItemRemoved(ANY_SIZE);
215 | }
216 |
217 | @Test
218 | public void shouldUpdateElementAtPositionFromCollection() {
219 | adapter.updateAndNotify(0, ANY_OBJECT);
220 |
221 | verify(mockedCollection).set(0, ANY_OBJECT);
222 | verify(adapter).notifyItemChanged(0, null);
223 | }
224 |
225 | @Test
226 | public void shouldUpdateElementAtPositionFromCollectionAndPassPayload() {
227 | adapter.updateAndNotify(0, ANY_OBJECT, ANY_OTHER_OBJECT);
228 |
229 | verify(mockedCollection).set(0, ANY_OBJECT);
230 | verify(adapter).notifyItemChanged(0, ANY_OTHER_OBJECT);
231 | }
232 |
233 | @Test
234 | public void shouldMoveElementFromOnePositionToAnotherFromCollection() {
235 | adapter.moveAndNotify(0, 1, ANY_OBJECT);
236 |
237 | verify(mockedCollection).remove(0);
238 | verify(mockedCollection).add(1, ANY_OBJECT);
239 | verify(adapter).notifyItemMoved(0, 1);
240 | }
241 |
242 | @Test
243 | public void shouldRemoveAllElementsFromCollection() {
244 | adapter.removeAllAndNotify(ANY_OBJECT_COLLECTION);
245 |
246 | verify(mockedCollection).removeAll(ANY_OBJECT_COLLECTION);
247 | verify(adapter).notifyDataSetChanged();
248 | }
249 |
250 | @Test
251 | public void shouldClearElementsFromCollection() {
252 | adapter.clearAndNotify();
253 |
254 | verify(mockedCollection).clear();
255 | verify(adapter).notifyDataSetChanged();
256 | }
257 |
258 | @Test
259 | public void shouldGetIndexFromCollection() {
260 | adapter.indexOf(ANY_OBJECT);
261 |
262 | verify(mockedCollection).indexOf(ANY_OBJECT);
263 | }
264 |
265 | @Test
266 | public void shouldContainAllItemsInCollection() {
267 | adapter.containsAll(ANY_OBJECT_COLLECTION);
268 |
269 | verify(mockedCollection).containsAll(ANY_OBJECT_COLLECTION);
270 | }
271 |
272 | @Test
273 | public void shouldContainItemInCollection() {
274 | adapter.contains(ANY_OBJECT);
275 |
276 | verify(mockedCollection).contains(ANY_OBJECT);
277 | }
278 |
279 | @Test
280 | public void shouldGetRendererFromViewHolderAndUpdateContentOnBind() {
281 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
282 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
283 |
284 | adapter.onBindViewHolder(mockedRendererViewHolder, ANY_POSITION);
285 |
286 | verify(mockedRenderer).setContent(ANY_OBJECT);
287 | }
288 |
289 | @Test
290 | public void shouldGetRendererFromViewHolderAndRenderItOnBind() {
291 | when(mockedCollection.get(ANY_POSITION)).thenReturn(ANY_OBJECT);
292 | when(mockedRendererViewHolder.getRenderer()).thenReturn(mockedRenderer);
293 |
294 | adapter.onBindViewHolder(mockedRendererViewHolder, ANY_POSITION);
295 |
296 | verify(mockedRenderer).render(Collections.emptyList());
297 | }
298 |
299 | @Test(expected = NullRendererBuiltException.class)
300 | public void shouldThrowExceptionIfNullRenderer() {
301 | adapter.onBindViewHolder(mockedRendererViewHolder, ANY_POSITION);
302 | }
303 |
304 | @Test
305 | public void shouldHookIntoRecyclerView() throws Exception {
306 | RendererAdapter adapter = new RendererAdapter<>(mockedRendererBuilder);
307 | adapter.into(mockedRecyclerView);
308 |
309 | verify(mockedRecyclerView).setAdapter(adapter);
310 | }
311 |
312 | private void initializeMocks() {
313 | MockitoAnnotations.initMocks(this);
314 | when(mockedParent.getContext()).thenReturn(RuntimeEnvironment.application);
315 | }
316 |
317 | private void initializeRendererAdapter() {
318 | adapter = new RendererAdapter<>(mockedRendererBuilder, mockedCollection);
319 | adapter = spy(adapter);
320 | }
321 | }
322 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/RendererBuilderTest.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import com.github.pedrovgs.renderers.BuildConfig;
8 | import com.pedrogomez.renderers.exception.NeedsPrototypesException;
9 | import com.pedrogomez.renderers.exception.NullContentException;
10 | import com.pedrogomez.renderers.exception.NullLayoutInflaterException;
11 | import com.pedrogomez.renderers.exception.NullParentException;
12 | import com.pedrogomez.renderers.exception.PrototypeNotFoundException;
13 |
14 | import org.junit.Before;
15 | import org.junit.Test;
16 | import org.junit.runner.RunWith;
17 | import org.mockito.Mock;
18 | import org.mockito.MockitoAnnotations;
19 | import org.robolectric.RobolectricTestRunner;
20 | import org.robolectric.annotation.Config;
21 |
22 | import java.util.Arrays;
23 | import java.util.Collections;
24 | import java.util.List;
25 |
26 | import static org.junit.Assert.assertEquals;
27 | import static org.junit.Assert.assertTrue;
28 |
29 | @SuppressWarnings({"unchecked", "ResultOfObjectAllocationIgnored", "ConstantConditions"})
30 | @Config(sdk = 19, constants = BuildConfig.class)
31 | @RunWith(RobolectricTestRunner.class)
32 | public class RendererBuilderTest {
33 |
34 | @Mock private View mockedConvertView;
35 | @Mock private ViewGroup mockedParent;
36 | @Mock private LayoutInflater mockedLayoutInflater;
37 | @Mock private Object mockedContent;
38 | @Mock private View mockedRendererView;
39 |
40 | @Before
41 | public void setUp() {
42 | initializeMocks();
43 | initializePrototypes();
44 | }
45 |
46 | @Test(expected = NeedsPrototypesException.class)
47 | public void shouldThrowNeedsPrototypeExceptionIfPrototypesIsNull() {
48 | new ObjectRendererBuilder(null);
49 | }
50 |
51 | @Test(expected = NeedsPrototypesException.class)
52 | public void shouldNotAcceptNullPrototypes() {
53 | RendererBuilder rendererBuilder = RendererBuilder.create()
54 | .getRendererBuilder();
55 |
56 | rendererBuilder.withPrototypes(null);
57 | }
58 |
59 | @Test
60 | public void shouldAcceptNotNullPrototypes() {
61 | RendererBuilder rendererBuilder = RendererBuilder.create()
62 | .getRendererBuilder();
63 |
64 | ObjectRenderer renderer = new ObjectRenderer();
65 | rendererBuilder.withPrototypes(Collections.singletonList(renderer));
66 | assertEquals(1, rendererBuilder.getPrototypes().size());
67 | assertEquals(renderer, rendererBuilder.getPrototypes().get(0));
68 | }
69 |
70 | @Test(expected = IllegalArgumentException.class)
71 | public void shouldNotAcceptNullKeysBindingAPrototype() {
72 | RendererBuilder.create().bind(null, new ObjectRenderer());
73 | }
74 |
75 | @Test(expected = IllegalArgumentException.class)
76 | public void shouldNotAcceptNullClass() {
77 | RendererBuilder.create().bind(ObjectRenderer.class, null);
78 | }
79 |
80 | @Test(expected = IllegalArgumentException.class)
81 | public void shouldNotAcceptNullTypePrototype() {
82 | RendererBuilder.create().bind(1, null);
83 | }
84 |
85 | @Test
86 | public void shouldAddPrototypeAndConfigureRendererBinding() {
87 | RendererBuilder rendererBuilder = RendererBuilder.create()
88 | .bind(String.class, new ObjectRenderer())
89 | .getRendererBuilder();
90 |
91 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(""));
92 | }
93 |
94 | @Test
95 | public void shouldAddPrototypeAndConfigureRendererBindingWithBuilder() {
96 | ObjectRenderer renderer = new ObjectRenderer();
97 | renderer.setView(mockedRendererView);
98 |
99 | RendererBuilder rendererBuilder = RendererBuilder.create()
100 | .bind(String.class, renderer)
101 | .getRendererBuilder()
102 | .withParent(mockedParent)
103 | .withLayoutInflater(mockedLayoutInflater)
104 | .withViewType(0);
105 |
106 | rendererBuilder.buildRendererViewHolder();
107 |
108 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
109 | }
110 |
111 | @Test(expected = NullContentException.class)
112 | public void shouldThrowNullContentException() {
113 | ObjectRenderer renderer = new ObjectRenderer();
114 | renderer.setView(mockedRendererView);
115 |
116 | RendererBuilder rendererBuilder = RendererBuilder.create()
117 | .bind(String.class, renderer)
118 | .getRendererBuilder()
119 | .withParent(mockedParent)
120 | .withLayoutInflater(mockedLayoutInflater)
121 | .withViewType(null);
122 |
123 | rendererBuilder.buildRendererViewHolder();
124 |
125 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
126 | }
127 |
128 | @Test(expected = NullLayoutInflaterException.class)
129 | public void shouldThrowNullLayoutInflaterException() {
130 | ObjectRenderer renderer = new ObjectRenderer();
131 | renderer.setView(mockedRendererView);
132 |
133 | RendererBuilder rendererBuilder = RendererBuilder.create()
134 | .bind(String.class, renderer)
135 | .getRendererBuilder()
136 | .withParent(mockedParent)
137 | .withLayoutInflater(null)
138 | .withViewType(0);
139 |
140 | rendererBuilder.buildRendererViewHolder();
141 |
142 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
143 | }
144 |
145 | @Test(expected = NullParentException.class)
146 | public void shouldThrowNullParentException() {
147 | ObjectRenderer renderer = new ObjectRenderer();
148 | renderer.setView(mockedRendererView);
149 |
150 | RendererBuilder rendererBuilder = RendererBuilder.create()
151 | .bind(String.class, renderer)
152 | .getRendererBuilder()
153 | .withParent(null)
154 | .withLayoutInflater(mockedLayoutInflater)
155 | .withViewType(0);
156 |
157 | rendererBuilder.buildRendererViewHolder();
158 |
159 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
160 | }
161 |
162 | @Test
163 | public void shouldAddPrototypeAndConfigureRendererBindingForType() {
164 | int type = 1;
165 | RendererBuilder rendererBuilder = RendererBuilder.create()
166 | .bind(type, new ObjectRendererContentRenderer())
167 | .getRendererBuilder();
168 |
169 | assertEquals(ObjectRendererContentRenderer.class, rendererBuilder.getPrototypeClass(
170 | new RendererContent<>(new Object(), type)));
171 | }
172 |
173 | @Test(expected = PrototypeNotFoundException.class)
174 | public void shouldFailForWrongType() {
175 | int type = 1;
176 | int anotherType = 2;
177 | RendererBuilder rendererBuilder = RendererBuilder.create()
178 | .bind(type, new ObjectRendererContentRenderer())
179 | .bind(anotherType, new ObjectRendererContentRenderer())
180 | .getRendererBuilder();
181 |
182 | rendererBuilder.getPrototypeClass(new RendererContent<>(new Object(), -1));
183 | }
184 |
185 | @Test
186 | public void shouldAddPrototypeAndConfigureRendererBindingForTypeWithMultiplePrototypes() {
187 | RendererBuilder rendererBuilder = RendererBuilder.create()
188 | .bind(Integer.class, new ObjectRenderer())
189 | .bind(String.class, new ObjectRenderer())
190 | .getRendererBuilder();
191 |
192 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(1));
193 | }
194 |
195 | @Test
196 | public void shouldAddPrototypeAndConfigureBindingOnConstruction() {
197 | ObjectRenderer renderer = new ObjectRenderer();
198 | RendererBuilder rendererBuilder = RendererBuilder.create(renderer)
199 | .getRendererBuilder();
200 |
201 | assertEquals(1, rendererBuilder.getPrototypes().size());
202 | assertEquals(renderer, rendererBuilder.getPrototypes().get(0));
203 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
204 | }
205 |
206 | @Test
207 | public void shouldCheckBindingsThatInheritParentClass() {
208 | RendererBuilder rendererBuilder = RendererBuilder.create()
209 | .bind(ParentClass.class, new ObjectRenderer())
210 | .getRendererBuilder();
211 |
212 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new ChildClass()));
213 | }
214 |
215 | @Test(expected = IllegalArgumentException.class)
216 | public void shouldThrowIllegalArgumentExceptionForObjectBinding() {
217 | RendererBuilder rendererBuilder = RendererBuilder.create()
218 | .bind(Object.class, new ObjectRenderer())
219 | .getRendererBuilder();
220 |
221 | assertEquals(ObjectRenderer.class, rendererBuilder.getPrototypeClass(new Object()));
222 | }
223 |
224 | @Test
225 | public void shouldCreateEmptyAdapter() throws Exception {
226 | RendererAdapter adapter = RendererBuilder.create()
227 | .bind(String.class, new ObjectRenderer())
228 | .build();
229 |
230 | assertTrue(adapter.getCollection().isEmpty());
231 | }
232 |
233 | @Test
234 | public void shouldCreateAdapterWithItems() throws Exception {
235 | List list = Arrays.asList("1", "2", "3");
236 | RendererAdapter adapter = RendererBuilder.create()
237 | .bind(String.class, new ObjectRenderer())
238 | .buildWith(list);
239 |
240 | assertEquals(list, adapter.getCollection());
241 | }
242 |
243 | private void initializeMocks() {
244 | MockitoAnnotations.initMocks(this);
245 | }
246 |
247 | private void initializePrototypes() {
248 | ObjectRenderer objectRenderer = new ObjectRenderer();
249 | objectRenderer.setView(mockedRendererView);
250 | SubObjectRenderer subObjectRenderer = new SubObjectRenderer();
251 | subObjectRenderer.setView(mockedRendererView);
252 | }
253 |
254 | private static class ParentClass {
255 | ParentClass() {
256 | }
257 | }
258 |
259 | private static class ChildClass extends ParentClass {
260 | ChildClass() {
261 | }
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/RendererContentTest.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 | import static org.junit.Assert.assertNotEquals;
7 |
8 | public class RendererContentTest {
9 | @Test
10 | public void shouldReturnItemItem() throws Exception {
11 | String item = "string";
12 | RendererContent rendererContent = new RendererContent<>(item, 1);
13 |
14 | assertEquals(item, rendererContent.getItem());
15 | }
16 |
17 | @Test
18 | public void shouldSetItem() throws Exception {
19 | String item = "string";
20 | RendererContent rendererContent = new RendererContent<>(item, 1);
21 |
22 | String item2 = "string2";
23 | rendererContent.setItem(item2);
24 | assertEquals(item2, rendererContent.getItem());
25 | }
26 |
27 | @Test
28 | public void shouldReturnType() throws Exception {
29 | int type = 1;
30 | RendererContent rendererContent = new RendererContent<>("string", type);
31 |
32 | assertEquals(type, rendererContent.getType());
33 | }
34 |
35 | @Test
36 | public void shouldDoEqualsWithItemAndType() throws Exception {
37 | RendererContent rendererContent1 = new RendererContent<>("a", 1);
38 | RendererContent rendererContent2 = new RendererContent<>("b", 1);
39 | RendererContent rendererContent3 = new RendererContent<>("a", 2);
40 | RendererContent rendererContent4 = new RendererContent<>("a", 1);
41 |
42 | assertNotEquals(rendererContent1, rendererContent2);
43 | assertNotEquals(rendererContent1, rendererContent3);
44 | assertNotEquals(rendererContent2, rendererContent3);
45 |
46 | assertEquals(rendererContent1, rendererContent4);
47 | }
48 |
49 | @Test
50 | public void shouldDoHashcodeWithItemAndType() throws Exception {
51 | RendererContent rendererContent1 = new RendererContent<>("a", 1);
52 | RendererContent rendererContent2 = new RendererContent<>("b", 1);
53 | RendererContent rendererContent3 = new RendererContent<>("a", 2);
54 | RendererContent rendererContent4 = new RendererContent<>("a", 1);
55 |
56 | assertNotEquals(rendererContent1.hashCode(), rendererContent2.hashCode());
57 | assertNotEquals(rendererContent1.hashCode(), rendererContent3.hashCode());
58 | assertNotEquals(rendererContent2.hashCode(), rendererContent3.hashCode());
59 |
60 | assertEquals(rendererContent1.hashCode(), rendererContent4.hashCode());
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/RendererTest.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.Nullable;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.pedrogomez.renderers.exception.NotInflateViewException;
10 |
11 | import org.junit.Before;
12 | import org.junit.Test;
13 | import org.mockito.Mock;
14 | import org.mockito.MockitoAnnotations;
15 | import org.mockito.Spy;
16 |
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertNull;
19 | import static org.junit.Assert.assertNotNull;
20 | import static org.mockito.Mockito.mock;
21 | import static org.mockito.Mockito.verify;
22 | import static org.mockito.Mockito.when;
23 |
24 | public class RendererTest {
25 |
26 | @Spy
27 | private ObjectRenderer renderer;
28 |
29 | @Mock
30 | private Object mockedContent;
31 | @Mock
32 | private LayoutInflater mockedLayoutInflater;
33 | @Mock
34 | private ViewGroup mockedParent;
35 | @Mock
36 | private View mockedView;
37 |
38 | private int testPosition = 1;
39 |
40 | @Before
41 | public void setUp() {
42 | initializeRenderer();
43 | initializeMocks();
44 | }
45 |
46 | @Test
47 | public void shouldKeepTheContentAfterOnCreateCall() {
48 | givenARendererInflatingView(mockedView);
49 |
50 | onCreateRenderer();
51 |
52 | assertEquals(mockedContent, renderer.getContent());
53 | }
54 |
55 | @Test
56 | public void shouldReturnCorrectItemPosition() {
57 | givenARendererInflatingView(mockedView);
58 |
59 | onCreateRenderer();
60 |
61 | assertEquals(renderer.getPosition(), testPosition);
62 | }
63 |
64 | @Test
65 | public void shouldInflateViewUsingLayoutInflaterAndParentAfterOnCreateCall() {
66 | givenARendererInflatingView(mockedView);
67 |
68 | onCreateRenderer();
69 |
70 | verify(renderer).inflate(mockedLayoutInflater, mockedParent);
71 | }
72 |
73 | @Test(expected = NotInflateViewException.class)
74 | public void shouldThrowExceptionIfInflateReturnsAnEmptyViewAfterOnCreateCall() {
75 | givenARendererInflatingANullView();
76 |
77 | onCreateRenderer();
78 | }
79 |
80 | @Test
81 | public void shouldSetUpViewWithTheInflatedViewAfterOnCreateCall() {
82 | givenARendererInflatingView(mockedView);
83 |
84 | onCreateRenderer();
85 |
86 | verify(renderer).setUpView(mockedView);
87 | }
88 |
89 | @Test
90 | public void shouldHookListenersViewWithTheInflatedViewAfterOnCreateCall() {
91 | givenARendererInflatingView(mockedView);
92 |
93 | onCreateRenderer();
94 |
95 | verify(renderer).hookListeners(mockedView);
96 | }
97 |
98 | @Test
99 | public void shouldKeepTheContentAfterOnRecycleCall() {
100 | givenARendererInflatingView(mockedView);
101 |
102 | onRecycleRenderer();
103 |
104 | assertEquals(mockedContent, renderer.getContent());
105 | }
106 |
107 | @Test
108 | public void shouldReturnNonNullContextAfterCreation() throws Exception {
109 | givenARendererInflatingView(mockedView);
110 | when(mockedParent.getContext()).thenReturn(mock(Context.class));
111 | assertNull(renderer.getContext());
112 |
113 | renderer.onCreate(mockedContent, mockedLayoutInflater, mockedParent);
114 |
115 | assertNotNull(renderer.getContext());
116 | }
117 |
118 | private void initializeRenderer() {
119 | renderer = new ObjectRenderer();
120 | }
121 |
122 | private void initializeMocks() {
123 | MockitoAnnotations.initMocks(this);
124 | }
125 |
126 | private void onCreateRenderer() {
127 | renderer.onCreate(mockedContent, mockedLayoutInflater, mockedParent);
128 | renderer.setPosition(testPosition);
129 | }
130 |
131 | private void onRecycleRenderer() {
132 | renderer.onRecycle(mockedContent);
133 | }
134 |
135 | private void givenARendererInflatingANullView() {
136 | givenARendererInflatingView(null);
137 | }
138 |
139 | private void givenARendererInflatingView(@Nullable View view) {
140 | when(renderer.inflate(mockedLayoutInflater, mockedParent)).thenReturn(view);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/SubObjectRenderer.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Renderer created only for testing purposes.
11 | *
12 | * @author Pedro Vicente Gómez Sánchez.
13 | */
14 | public class SubObjectRenderer extends Renderer {
15 |
16 | private View view;
17 |
18 | @Override
19 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
20 | return view;
21 | }
22 |
23 | @Override
24 | public void render(List payloads) {
25 | }
26 |
27 | public void setView(View view) {
28 | this.view = view;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/renderers/src/test/java/com/pedrogomez/renderers/ViewRendererTest.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import com.github.pedrovgs.renderers.BuildConfig;
8 | import com.pedrogomez.renderers.ViewRenderer.InflateFunction;
9 | import com.pedrogomez.renderers.ViewRenderer.RenderFunction;
10 |
11 | import org.junit.Before;
12 | import org.junit.Test;
13 | import org.junit.runner.RunWith;
14 | import org.mockito.Mock;
15 | import org.mockito.MockitoAnnotations;
16 | import org.robolectric.RobolectricTestRunner;
17 | import org.robolectric.RuntimeEnvironment;
18 | import org.robolectric.annotation.Config;
19 |
20 | import java.util.List;
21 |
22 | import static org.mockito.Mockito.mock;
23 | import static org.mockito.Mockito.spy;
24 | import static org.mockito.Mockito.verify;
25 | import static org.mockito.Mockito.verifyZeroInteractions;
26 | import static org.mockito.Mockito.when;
27 |
28 | @SuppressWarnings("unchecked")
29 | @Config(sdk = 19, constants = BuildConfig.class)
30 | @RunWith(RobolectricTestRunner.class)
31 | public class ViewRendererTest {
32 |
33 | @Mock private ViewGroup mockedParent;
34 | @Mock private LayoutInflater mockedInflater;
35 | @Mock private InflateFunction inflateFunction;
36 | @Mock private RenderFunction renderFunction;
37 | private ViewRenderer renderer;
38 |
39 | @Before
40 | public void setUp() {
41 | MockitoAnnotations.initMocks(this);
42 | when(mockedParent.getContext()).thenReturn(RuntimeEnvironment.application);
43 |
44 | renderer = spy(new ViewRenderer(inflateFunction, renderFunction));
45 | }
46 |
47 | @Test
48 | public void shouldCallInflateFunctionWithContext() throws Exception {
49 | renderer.inflate(mockedInflater, mockedParent);
50 |
51 | verify(inflateFunction).inflate(RuntimeEnvironment.application);
52 | verifyZeroInteractions(mockedInflater);
53 | }
54 |
55 | @Test
56 | public void shouldCallRenderFunctionWithContentAndRootView() throws Exception {
57 | Object content = new Object();
58 | renderer.setContent(content);
59 | View rootView = mock(View.class);
60 | when(renderer.getRootView()).thenReturn(rootView);
61 |
62 | List payloads = mock(List.class);
63 | renderer.render(payloads);
64 |
65 | verify(renderFunction).render(content, rootView);
66 | verifyZeroInteractions(payloads);
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 |
6 | defaultConfig {
7 | applicationId "com.github.pedrovgs.renderers.sample"
8 | minSdkVersion 14
9 | targetSdkVersion 28
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | }
17 | }
18 |
19 | lintOptions {
20 | abortOnError false
21 | }
22 | }
23 |
24 | dependencies {
25 | implementation 'com.squareup.picasso:picasso:2.5.2'
26 | implementation project(':renderers')
27 | implementation 'com.android.support:appcompat-v7:28.0.0'
28 | implementation 'com.jakewharton:butterknife:8.8.1'
29 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
30 | implementation 'com.android.support:recyclerview-v7:28.0.0'
31 | }
32 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
21 |
22 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
44 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/model/RandomVideoCollectionGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.model;
17 |
18 | import java.util.ArrayList;
19 | import java.util.HashMap;
20 | import java.util.LinkedList;
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.Random;
24 |
25 | /**
26 | * Auxiliary class created to generate a VideoCollection with random data.
27 | *
28 | * @author Pedro Vicente Gómez Sánchez.
29 | */
30 | public final class RandomVideoCollectionGenerator {
31 |
32 | private static final Map VIDEO_INFO = new HashMap<>();
33 |
34 | /**
35 | * Initialize VIDEO_INFO data.
36 | */
37 | static {
38 | VIDEO_INFO.put("The Big Bang Theory", "http://thetvdb.com/banners/_cache/posters/80379-9.jpg");
39 | VIDEO_INFO.put("Breaking Bad", "http://thetvdb.com/banners/_cache/posters/81189-22.jpg");
40 | VIDEO_INFO.put("Arrow", "http://thetvdb.com/banners/_cache/posters/257655-15.jpg");
41 | VIDEO_INFO.put("Game of Thrones", "http://thetvdb.com/banners/_cache/posters/121361-26.jpg");
42 | VIDEO_INFO.put("Lost", "http://thetvdb.com/banners/_cache/posters/73739-2.jpg");
43 | VIDEO_INFO.put("How I met your mother", "http://thetvdb.com/banners/_cache/posters/75760-29.jpg");
44 | VIDEO_INFO.put("Dexter", "http://thetvdb.com/banners/_cache/posters/79349-24.jpg");
45 | VIDEO_INFO.put("Sleepy Hollow", "http://thetvdb.com/banners/_cache/posters/269578-5.jpg");
46 | VIDEO_INFO.put("The Vampire Diaries", "http://thetvdb.com/banners/_cache/posters/95491-27.jpg");
47 | VIDEO_INFO.put("Friends", "http://thetvdb.com/banners/_cache/posters/79168-4.jpg");
48 | VIDEO_INFO.put("New Girl", "http://thetvdb.com/banners/_cache/posters/248682-9.jpg");
49 | VIDEO_INFO.put("The Mentalist", "http://thetvdb.com/banners/_cache/posters/82459-1.jpg");
50 | VIDEO_INFO.put("Sons of Anarchy", "http://thetvdb.com/banners/_cache/posters/82696-1.jpg");
51 | }
52 |
53 | private static final Random RANDOM = new Random();
54 |
55 | private RandomVideoCollectionGenerator() { }
56 |
57 | public static List generateList(int videoCount) {
58 | List videos = new LinkedList<>();
59 | for (int i = 0; i < videoCount; i++) {
60 | Video video = generateRandomVideo();
61 | videos.add(video);
62 | }
63 | return new ArrayList<>(videos);
64 | }
65 |
66 | /**
67 | * Create a random video.
68 | *
69 | * @return random video.
70 | */
71 | private static Video generateRandomVideo() {
72 | Video video = new Video();
73 | configureFavoriteStatus(video);
74 | configureLikeStatus(video);
75 | configureLiveStatus(video);
76 | configureTitleAndThumbnail(video);
77 | return video;
78 | }
79 |
80 | private static void configureLikeStatus(Video video) {
81 | boolean liked = RANDOM.nextBoolean();
82 | video.setLiked(liked);
83 | }
84 |
85 | private static void configureFavoriteStatus(Video video) {
86 | boolean favorite = RANDOM.nextBoolean();
87 | video.setFavorite(favorite);
88 | }
89 |
90 | private static void configureLiveStatus(Video video) {
91 | boolean live = RANDOM.nextBoolean();
92 | video.setLive(live);
93 | }
94 |
95 | private static void configureTitleAndThumbnail(Video video) {
96 | int maxInt = VIDEO_INFO.size();
97 | int randomIndex = RANDOM.nextInt(maxInt);
98 | String title = getKeyForIndex(randomIndex);
99 | video.setTitle(title);
100 | String thumbnail = getValueForIndex(randomIndex);
101 | video.setThumbnail(thumbnail);
102 | }
103 |
104 | private static String getKeyForIndex(int randomIndex) {
105 | int i = 0;
106 | for (String index : VIDEO_INFO.keySet()) {
107 | if (i == randomIndex) {
108 | return index;
109 | }
110 | i++;
111 | }
112 | return null;
113 | }
114 |
115 | private static String getValueForIndex(int randomIndex) {
116 | int i = 0;
117 | for (String index : VIDEO_INFO.keySet()) {
118 | if (i == randomIndex) {
119 | return VIDEO_INFO.get(index);
120 | }
121 | i++;
122 | }
123 | return "";
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/model/Video.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.model;
17 |
18 | /**
19 | * Main domain class created to simulate fake data for the example.
20 | *
21 | * @author Pedro Vicente Gómez Sánchez.
22 | */
23 | public class Video {
24 |
25 | private boolean favorite;
26 | private boolean liked;
27 | private boolean live;
28 | private String thumbnail;
29 | private String title;
30 |
31 | public boolean isFavorite() {
32 | return favorite;
33 | }
34 |
35 | public void setFavorite(boolean favorite) {
36 | this.favorite = favorite;
37 | }
38 |
39 | public boolean isLiked() {
40 | return liked;
41 | }
42 |
43 | public void setLiked(boolean liked) {
44 | this.liked = liked;
45 | }
46 |
47 | public String getThumbnail() {
48 | return thumbnail;
49 | }
50 |
51 | public void setThumbnail(String resourceThumbnail) {
52 | this.thumbnail = resourceThumbnail;
53 | }
54 |
55 | public String getTitle() {
56 | return title;
57 | }
58 |
59 | public void setTitle(String title) {
60 | this.title = title;
61 | }
62 |
63 | public boolean isLive() {
64 | return live;
65 | }
66 |
67 | public void setLive(boolean live) {
68 | this.live = live;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/AdvancedRecyclerViewActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 | import android.support.v7.widget.LinearLayoutManager;
21 | import android.support.v7.widget.RecyclerView;
22 |
23 | import com.pedrogomez.renderers.RendererAdapter;
24 | import com.pedrogomez.renderers.RendererBuilder;
25 | import com.pedrogomez.renderers.sample.R;
26 | import com.pedrogomez.renderers.sample.model.RandomVideoCollectionGenerator;
27 | import com.pedrogomez.renderers.sample.model.Video;
28 | import com.pedrogomez.renderers.sample.ui.renderers.SectionRenderer;
29 | import com.pedrogomez.renderers.sample.ui.renderers.VideoRenderer;
30 |
31 | import java.util.List;
32 |
33 | import butterknife.BindView;
34 | import butterknife.ButterKnife;
35 |
36 | /**
37 | * AdvancedRecyclerViewActivity for the Renderers demo.
38 | *
39 | * @author alberto.ballano
40 | */
41 | public class AdvancedRecyclerViewActivity extends Activity {
42 |
43 | private static final int VIDEO_COUNT = 100;
44 |
45 | @BindView(R.id.rv_renderers)
46 | RecyclerView recyclerView;
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_recycler_view);
52 | ButterKnife.bind(this);
53 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
54 |
55 | List videoCollection = RandomVideoCollectionGenerator.generateList(VIDEO_COUNT);
56 |
57 | RendererAdapter adapter = RendererBuilder.create()
58 | .bind(Video.class, new VideoRenderer())
59 | .bind(String.class, new SectionRenderer())
60 | .build()
61 | .into(recyclerView);
62 | recyclerView.setAdapter(adapter);
63 |
64 | for (int i = 0, videoCollectionSize = videoCollection.size(); i < videoCollectionSize; i++) {
65 | adapter.add("Video #" + (i + 1));
66 | adapter.add(videoCollection.get(i));
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/ComplexRecyclerViewActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 | import android.support.v7.widget.LinearLayoutManager;
21 | import android.support.v7.widget.RecyclerView;
22 |
23 | import com.pedrogomez.renderers.RendererAdapter;
24 | import com.pedrogomez.renderers.RendererBuilder;
25 | import com.pedrogomez.renderers.RendererContent;
26 | import com.pedrogomez.renderers.sample.R;
27 | import com.pedrogomez.renderers.sample.model.RandomVideoCollectionGenerator;
28 | import com.pedrogomez.renderers.sample.model.Video;
29 | import com.pedrogomez.renderers.sample.ui.renderers.FooterRenderer;
30 | import com.pedrogomez.renderers.sample.ui.renderers.SectionRenderer2;
31 | import com.pedrogomez.renderers.sample.ui.renderers.VideoRenderer;
32 |
33 | import java.util.List;
34 |
35 | import butterknife.BindView;
36 | import butterknife.ButterKnife;
37 |
38 | /**
39 | * AdvancedRecyclerViewActivity for the Renderers demo.
40 | *
41 | * @author alberto.ballano
42 | */
43 | public class ComplexRecyclerViewActivity extends Activity {
44 |
45 | // Let's add less videos so we can see the footer :)
46 | private static final int VIDEO_COUNT = 3;
47 | private static final int TYPE_SECTION = 0;
48 | private static final int TYPE_FOOTER = 1;
49 |
50 | @BindView(R.id.rv_renderers)
51 | RecyclerView recyclerView;
52 |
53 | @Override
54 | protected void onCreate(Bundle savedInstanceState) {
55 | super.onCreate(savedInstanceState);
56 | setContentView(R.layout.activity_recycler_view);
57 | ButterKnife.bind(this);
58 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
59 |
60 | List videoCollection = RandomVideoCollectionGenerator.generateList(VIDEO_COUNT);
61 |
62 | RendererAdapter adapter = RendererBuilder.create()
63 | .bind(Video.class, new VideoRenderer())
64 | .bind(TYPE_FOOTER, new FooterRenderer())
65 | .bind(TYPE_SECTION, new SectionRenderer2())
66 | .build()
67 | .into(recyclerView);
68 |
69 | for (int i = 0, videoCollectionSize = videoCollection.size(); i < videoCollectionSize; i++) {
70 | adapter.add(new RendererContent<>("Video #" + (i + 1), TYPE_SECTION));
71 | adapter.add(videoCollection.get(i));
72 | }
73 | adapter.add(new RendererContent<>("by Alberto Ballano", TYPE_FOOTER));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.pedrogomez.renderers.sample.ui;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 |
7 | import com.pedrogomez.renderers.sample.R;
8 |
9 | import butterknife.ButterKnife;
10 | import butterknife.OnClick;
11 |
12 | /**
13 | * ListViewActivity for the Renderers demo.
14 | *
15 | * @author Pedro Vicente Gómez Sánchez.
16 | */
17 | public class MainActivity extends Activity {
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 | ButterKnife.bind(this);
24 | }
25 |
26 | @OnClick(R.id.bt_open_rv_simple)
27 | public void openRecyclerViewSample() {
28 | open(SimpleRecyclerViewActivity.class);
29 | }
30 |
31 | @OnClick(R.id.bt_open_rv_advanced)
32 | public void openRecyclerViewAdvanced() {
33 | open(AdvancedRecyclerViewActivity.class);
34 | }
35 | @OnClick(R.id.bt_open_rv_complex)
36 | public void openRecyclerViewComplex() {
37 | open(ComplexRecyclerViewActivity.class);
38 | }
39 |
40 | private void open(Class activity) {
41 | Intent intent = new Intent(this, activity);
42 | startActivity(intent);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/SimpleRecyclerViewActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 | import android.support.v7.widget.LinearLayoutManager;
21 | import android.support.v7.widget.RecyclerView;
22 |
23 | import com.pedrogomez.renderers.RendererBuilder;
24 | import com.pedrogomez.renderers.sample.R;
25 | import com.pedrogomez.renderers.sample.model.RandomVideoCollectionGenerator;
26 | import com.pedrogomez.renderers.sample.model.Video;
27 | import com.pedrogomez.renderers.sample.ui.renderers.VideoRenderer;
28 |
29 | import java.util.List;
30 |
31 | import butterknife.BindView;
32 | import butterknife.ButterKnife;
33 |
34 | /**
35 | * SimpleRecyclerViewActivity for the Renderers demo.
36 | *
37 | * @author alberto.ballano
38 | */
39 | public class SimpleRecyclerViewActivity extends Activity {
40 |
41 | private static final int VIDEO_COUNT = 100;
42 |
43 | @BindView(R.id.rv_renderers)
44 | RecyclerView recyclerView;
45 |
46 | @Override
47 | protected void onCreate(Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | setContentView(R.layout.activity_recycler_view);
50 | ButterKnife.bind(this);
51 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
52 |
53 | List videoCollection = RandomVideoCollectionGenerator.generateList(VIDEO_COUNT);
54 |
55 | RendererBuilder.create(new VideoRenderer())
56 | .buildWith(videoCollection)
57 | .into(recyclerView);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/renderers/FooterRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui.renderers;
17 |
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 |
22 | import com.pedrogomez.renderers.sample.R;
23 |
24 | import butterknife.ButterKnife;
25 |
26 | /**
27 | * Abstract class that works as base renderer for Renderer. This class implements the main
28 | * render algorithm and declare some abstract methods to be implemented by subtypes.
29 | *
30 | * @author alberto.ballano
31 | */
32 | public class FooterRenderer extends SectionRenderer2 {
33 |
34 | /**
35 | * Inflate the main layout used to render videos in the list view.
36 | *
37 | * @param inflater LayoutInflater service to inflate.
38 | * @param parent ViewGroup used to inflate xml.
39 | * @return view inflated.
40 | */
41 | @Override
42 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
43 | View inflatedView = inflater.inflate(R.layout.footer_renderer, parent, false);
44 | /*
45 | * You don't have to use ButterKnife library to implement the mapping between your layout
46 | * and your widgets you can implement setUpView and hookListener methods declared in
47 | * Renderer class.
48 | */
49 | ButterKnife.bind(this, inflatedView);
50 | return inflatedView;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/renderers/SectionRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui.renderers;
17 |
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import android.widget.TextView;
22 |
23 | import com.pedrogomez.renderers.Renderer;
24 | import com.pedrogomez.renderers.sample.R;
25 |
26 | import java.util.List;
27 |
28 | import butterknife.BindView;
29 | import butterknife.ButterKnife;
30 |
31 | /**
32 | * Abstract class that works as base renderer for Renderer. This class implements the main
33 | * render algorithm and declare some abstract methods to be implemented by subtypes.
34 | *
35 | * @author alberto.ballano
36 | */
37 | public class SectionRenderer extends Renderer {
38 |
39 | @BindView(R.id.tv_title)
40 | TextView title;
41 |
42 | /**
43 | * Inflate the main layout used to render videos in the list view.
44 | *
45 | * @param inflater LayoutInflater service to inflate.
46 | * @param parent ViewGroup used to inflate xml.
47 | * @return view inflated.
48 | */
49 | @Override
50 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
51 | View inflatedView = inflater.inflate(R.layout.section_renderer, parent, false);
52 | /*
53 | * You don't have to use ButterKnife library to implement the mapping between your layout
54 | * and your widgets you can implement setUpView and hookListener methods declared in
55 | * Renderer class.
56 | */
57 | ButterKnife.bind(this, inflatedView);
58 | return inflatedView;
59 | }
60 |
61 | /**
62 | * Main render algorithm based on render the video thumbnail, render the title, render the marker
63 | * and the label.
64 | */
65 | @Override
66 | public void render(List payloads) {
67 | title.setText(getContent());
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/renderers/SectionRenderer2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui.renderers;
17 |
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import android.widget.TextView;
22 |
23 | import com.pedrogomez.renderers.Renderer;
24 | import com.pedrogomez.renderers.RendererContent;
25 | import com.pedrogomez.renderers.sample.R;
26 |
27 | import java.util.List;
28 |
29 |
30 | import butterknife.BindView;
31 | import butterknife.ButterKnife;
32 |
33 | /**
34 | * Abstract class that works as base renderer for Renderer. This class implements the main
35 | * render algorithm and declare some abstract methods to be implemented by subtypes.
36 | *
37 | * @author alberto.ballano
38 | */
39 | public class SectionRenderer2 extends Renderer> {
40 |
41 | @BindView(R.id.tv_title)
42 | TextView title;
43 |
44 | /**
45 | * Inflate the main layout used to render videos in the list view.
46 | *
47 | * @param inflater LayoutInflater service to inflate.
48 | * @param parent ViewGroup used to inflate xml.
49 | * @return view inflated.
50 | */
51 | @Override
52 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
53 | View inflatedView = inflater.inflate(R.layout.section_renderer, parent, false);
54 | /*
55 | * You don't have to use ButterKnife library to implement the mapping between your layout
56 | * and your widgets you can implement setUpView and hookListener methods declared in
57 | * Renderer class.
58 | */
59 | ButterKnife.bind(this, inflatedView);
60 | return inflatedView;
61 | }
62 |
63 | /**
64 | * Main render algorithm based on render the video thumbnail, render the title, render the marker
65 | * and the label.
66 | */
67 | @Override
68 | public void render(List payloads) {
69 | title.setText(getContent().getItem());
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/pedrogomez/renderers/sample/ui/renderers/VideoRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Pedro Vicente Gómez Sánchez.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.pedrogomez.renderers.sample.ui.renderers;
17 |
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import android.widget.ImageView;
22 | import android.widget.TextView;
23 | import android.widget.Toast;
24 |
25 | import com.pedrogomez.renderers.Renderer;
26 | import com.pedrogomez.renderers.sample.R;
27 | import com.pedrogomez.renderers.sample.model.Video;
28 | import com.squareup.picasso.Picasso;
29 |
30 | import java.util.List;
31 |
32 |
33 | import butterknife.BindView;
34 | import butterknife.ButterKnife;
35 | import butterknife.OnClick;
36 |
37 | /**
38 | * Abstract class that works as base renderer for Renderer. This class implements the main
39 | * render algorithm and declare some abstract methods to be implemented by subtypes.
40 | *
41 | * @author Pedro Vicente Gómez Sánchez.
42 | */
43 | public class VideoRenderer extends Renderer {
44 |
45 | @BindView(R.id.iv_thumbnail)
46 | ImageView thumbnail;
47 | @BindView(R.id.tv_title)
48 | TextView title;
49 |
50 | /**
51 | * Inflate the main layout used to render videos in the list view.
52 | *
53 | * @param inflater LayoutInflater service to inflate.
54 | * @param parent ViewGroup used to inflate xml.
55 | * @return view inflated.
56 | */
57 | @Override
58 | protected View inflate(LayoutInflater inflater, ViewGroup parent) {
59 | View inflatedView = inflater.inflate(R.layout.video_renderer, parent, false);
60 | /*
61 | * You don't have to use ButterKnife library to implement the mapping between your layout
62 | * and your widgets you can implement setUpView and hookListener methods declared in
63 | * Renderer class.
64 | */
65 | ButterKnife.bind(this, inflatedView);
66 | return inflatedView;
67 | }
68 |
69 | @OnClick(R.id.iv_thumbnail)
70 | void onVideoClicked() {
71 | Video video = getContent();
72 | Toast.makeText(getContext(), "Video clicked. Title = " + video.getTitle(), Toast.LENGTH_LONG).show();
73 | }
74 |
75 | /**
76 | * Main render algorithm based on render the video thumbnail, render the title, render the marker
77 | * and the label.
78 | */
79 | @Override
80 | public void render(List payloads) {
81 | Video video = getContent();
82 | Picasso.with(getContext()).cancelRequest(thumbnail);
83 | Picasso.with(getContext())
84 | .load(video.getThumbnail())
85 | .placeholder(R.drawable.placeholder)
86 | .into(thumbnail);
87 | title.setText(video.getTitle());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/fav_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-hdpi/fav_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/like_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-hdpi/like_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/like_unactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-hdpi/like_unactive.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-hdpi/play.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/fav_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-mdpi/fav_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/like_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-mdpi/like_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/like_unactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-mdpi/like_unactive.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-mdpi/play.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/fav_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/fav_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/like_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/like_active.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/like_unactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/like_unactive.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/placeholder.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xhdpi/play.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aballano/GenericRenderers/894762408e131769273b1e4829c526dff2bad229/sample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_list_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
21 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
26 |
27 |
32 |
33 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
22 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/footer_renderer.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
20 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/section_renderer.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
20 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/video_renderer.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
23 |
24 |
27 |
28 |
31 |
32 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #FFFFFFFF
19 | #7F000000
20 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | 0dip
20 | 240dip
21 | 12dip
22 | 24dip
23 | 16dip
24 | 14dip
25 | 4dip
26 |
27 |
28 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | GenericRenderers
20 | Favorite
21 | Like
22 | Dislike
23 | Live
24 | Open RecyclerView simple
25 | Open RecyclerView advanced
26 | Open RecyclerView complex
27 |
28 |
29 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
22 |
23 |
27 |
28 |
31 |
32 |
33 |
38 |
39 |
43 |
44 |
50 |
51 |
58 |
59 |
67 |
68 |
80 |
81 |
92 |
93 |
104 |
105 |
117 |
118 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':renderers', ':sample'
2 |
--------------------------------------------------------------------------------