com.madgag.android.listviews.ReflectiveHolderFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of android-viewholder-listviews Show documentation
Show all versions of android-viewholder-listviews Show documentation
Small library around using the 'ViewHolder' pattern with ListViews
/*
* Copyright 2011 Kevin Sawicki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.madgag.android.listviews;
import android.view.View;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
/**
* {@link ViewHolderFactory} that uses reflection to create new
* {@link ViewHolder} instances with the given parameters that are injected into
* each {@link ViewHolder} created.
*
* @param
* model class that views are bound to
*/
public class ReflectiveHolderFactory implements ViewHolderFactory {
private final Class extends ViewHolder> holderClass;
public static ReflectiveHolderFactory reflectiveFactoryFor(
Class extends ViewHolder> holderClass,
Object... args) {
return new ReflectiveHolderFactory(holderClass, args);
}
private static Constructor> findMatch(final Class> clazz,
final Class>[] types) {
Constructor>[] candidates = clazz.getConstructors();
for (Constructor> candidate : candidates) {
Class>[] params = candidate.getParameterTypes();
if (params.length != types.length)
continue;
boolean match = true;
for (int i = 0; i < types.length; i++)
if (!params[i].isAssignableFrom(types[i])) {
match = false;
break;
}
if (match)
return candidate;
}
return null;
}
private final Constructor extends ViewHolder> constructor;
private final Object[] args;
/**
* Create holder factory for constructor and arguments
*
* @param holderClass
* @param args
* @throws RuntimeException
*/
@SuppressWarnings("unchecked")
private ReflectiveHolderFactory(final Class extends ViewHolder> holderClass,
Object... args) {
this.holderClass = holderClass;
if (args == null)
args = new Object[0];
if (holderClass.isMemberClass() && !Modifier.isStatic(holderClass.getModifiers()))
throw new IllegalArgumentException(
"Non-static member classes not supported");
Class>[] types = new Class[args.length + 1];
// First argument must be the view itself
types[0] = View.class;
for (int i = 0; i < args.length; i++)
types[i + 1] = args[i].getClass();
constructor = (Constructor extends ViewHolder>) findMatch(holderClass,
types);
if (constructor == null)
throw new IllegalArgumentException(
"No constructor found to bind arguments to");
this.args = new Object[args.length + 1];
System.arraycopy(args, 0, this.args, 1, args.length);
}
public ViewHolder createViewHolderFor(final View view) {
try {
args[0] = view;
return constructor.newInstance(args);
} catch (InstantiationException e) {
throw new IllegalArgumentException(e);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(e);
}
}
public Class extends ViewHolder> getHolderClass() {
return holderClass;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy