почему никто (пока -> см. 2016.05) не упомянул здесь подход, основанный на отражениях?
1. точка входа:
/**
* generates default layout params for given view group
* with width and height set to WLayoutParams.RAP_CONTENT
*
* @param viewParent - parent of this layout params view
* @param <L> - layout param class
* @return layout param class object
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
@NonNull
private <L extends ViewGroup.LayoutParams> L generateDefaultLayoutParams(@NonNull ViewGroup viewParent)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method generateDefaultLayoutParamsMethod = ViewGroup.class.getDeclaredMethod("generateDefaultLayoutParams");
// caution: below way to obtain method has some flaw as we need traverse superclasses to obtain method in case we look in object and not a class
// = viewParent.getClass().getDeclaredMethod("generateDefaultLayoutParams");
generateDefaultLayoutParamsMethod.setAccessible(true);
return (L) generateDefaultLayoutParamsMethod.invoke(viewParent);
}
2. обыкновения:
@NonNull
protected <T extends ViewGroup.LayoutParams> T createLayoutParamsForView(ViewGroup viewParent,
@IdRes int belowViewId)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
return createLayoutParamsForView(null,null,viewParent,belowViewId);
}
@NonNull
protected <T extends ViewGroup.LayoutParams> T createLayoutParamsForView(@NonNull Context context,
@NonNull Class<? extends ViewGroup> parentClass,
@IdRes int belowViewId)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
return createLayoutParamsForView(context,parentClass,null,belowViewId);
}
@NonNull
private <T extends ViewGroup.LayoutParams> T createLayoutParamsForView(@Nullable Context context,
@Nullable Class<? extends ViewGroup> parentClass,
@Nullable ViewGroup parent,
@IdRes int belowViewId)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
if(context == null && parent == null) throw new IllegalStateException("either context and parent class or must be non null!");
T layoutParams = (T) (parent != null ? generateDefaultLayoutParams(parent) : generateDefaultLayoutParams(context, parentClass));
if (belowViewId != NO_ID && RelativeLayout.LayoutParams.class.isAssignableFrom(layoutParams.getClass())){
((RelativeLayout.LayoutParams)layoutParams).addRule(RelativeLayout.BELOW, belowViewId);
}
return layoutParams;
}
@NonNull
private <P extends ViewGroup> P instantiateParent(Class parentClass, Context context)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor constructor = parentClass.getDeclaredConstructor(Context.class);
constructor.setAccessible(true);
return (P) constructor.newInstance(context);
}
@NonNull
private <L extends ViewGroup.LayoutParams, P extends ViewGroup> L generateDefaultLayoutParams(Context context, @NonNull Class<? extends ViewGroup> viewParentClass)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
P viewParent = instantiateParent(viewParentClass, context);
return generateDefaultLayoutParams(viewParent);
}