package com.cheng.utils.view; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.content.res.Configuration; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.GridView; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.widget.TextView; /** * ViewUtils * <ul> * <strong>get view height</strong> * <li>{@link ViewUtil#getListViewHeightBasedOnChildren(ListView)}</li> * <li>{@link ViewUtil#getAbsListViewHeightBasedOnChildren(AbsListView)}</li> * </ul> * <ul> * <strong>set view height</strong> * <li>{@link ViewUtil#setViewHeight(View, int)} set view height</li> * <li>{@link ViewUtil#setListViewHeightBasedOnChildren(ListView)}</li> * <li>{@link ViewUtil#setAbsListViewHeightBasedOnChildren(AbsListView)}</li> * </ul> * <ul> * <strong>get other info</strong> * <li>{@link ViewUtil#getGridViewVerticalSpacing(GridView)} get GridView * vertical spacing</li> * </ul> * <ul> * <strong>set other info</strong> * <li>{@link ViewUtil#setSearchViewOnClickListener(View, OnClickListener)}</li> * </ul> */ public final class ViewUtil { /** * Don't let anyone instantiate this class. */ private ViewUtil() { throw new Error("Do not need instantiate!"); } /** * get ListView height according to every children * * @param view * @return */ public static int getListViewHeightBasedOnChildren(ListView view) { int height = getAbsListViewHeightBasedOnChildren(view); ListAdapter adapter; int adapterCount; if (view != null && (adapter = view.getAdapter()) != null && (adapterCount = adapter.getCount()) > 0) { height += view.getDividerHeight() * (adapterCount - 1); } return height; } private static final String CLASS_NAME_GRID_VIEW = "android.widget.GridView"; private static final String FIELD_NAME_VERTICAL_SPACING = "mVerticalSpacing"; /** * get GridView vertical spacing * * @param view * @return */ public static int getGridViewVerticalSpacing(GridView view) { // get mVerticalSpacing by android.widget.GridView Class<?> demo = null; int verticalSpacing = 0; try { demo = Class.forName(CLASS_NAME_GRID_VIEW); Field field = demo.getDeclaredField(FIELD_NAME_VERTICAL_SPACING); field.setAccessible(true); verticalSpacing = (Integer) field.get(view); return verticalSpacing; } catch (Exception e) { /** * accept all exception, include ClassNotFoundException, * NoSuchFieldException, InstantiationException, * IllegalArgumentException, IllegalAccessException, * NullPointException */ e.printStackTrace(); } return verticalSpacing; } /** * get AbsListView height according to every children * * @param view * @return */ public static int getAbsListViewHeightBasedOnChildren(AbsListView view) { ListAdapter adapter; if (view == null || (adapter = view.getAdapter()) == null) { return 0; } int height = 0; for (int i = 0; i < adapter.getCount(); i++) { View item = adapter.getView(i, null, view); if (item instanceof ViewGroup) { item.setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } item.measure(0, 0); height += item.getMeasuredHeight(); } height += view.getPaddingTop() + view.getPaddingBottom(); return height; } /** * get Font height * * @param view * @return */ public static int getFontHeight(TextView view) { Paint paint = new Paint(); paint.setTextSize(view.getTextSize()); FontMetrics fm = paint.getFontMetrics(); return (int) (Math.ceil(fm.descent - fm.ascent)); } /** * set view height * * @param view * @param height */ public static void setViewHeight(View view, int height) { if (view == null) { return; } ViewGroup.LayoutParams params = view.getLayoutParams(); params.height = height; } // /** // * set GistView height which is calculated by {@link # // getGridViewHeightBasedOnChildren(GridView)} // * // * @param view // * @return // */ // public static void setGridViewHeightBasedOnChildren(GridView view) { // setViewHeight(view, getGridViewHeightBasedOnChildren(view)); // } /** * set ListView height which is calculated by * {@link # getListViewHeightBasedOnChildren(ListView)} * * @param view * @return */ public static void setListViewHeightBasedOnChildren(ListView view) { setViewHeight(view, getListViewHeightBasedOnChildren(view)); } /** * set AbsListView height which is calculated by * {@link # getAbsListViewHeightBasedOnChildren(AbsListView)} * * @param view * @return */ public static void setAbsListViewHeightBasedOnChildren(AbsListView view) { setViewHeight(view, getAbsListViewHeightBasedOnChildren(view)); } /** * set SearchView OnClickListener * * @param v * @param listener */ public static void setSearchViewOnClickListener(View v, OnClickListener listener) { if (v instanceof ViewGroup) { ViewGroup group = (ViewGroup) v; int count = group.getChildCount(); for (int i = 0; i < count; i++) { View child = group.getChildAt(i); if (child instanceof LinearLayout || child instanceof RelativeLayout) { setSearchViewOnClickListener(child, listener); } if (child instanceof TextView) { TextView text = (TextView) child; text.setFocusable(false); } child.setOnClickListener(listener); } } } /** * get descended views from parent. * * @param parent * @param filter Type of views which will be returned. * @param includeSubClass Whether returned list will include views which are subclass of * filter or not. * @return */ public static <T extends View> List<T> getDescendants(ViewGroup parent, Class<T> filter, boolean includeSubClass) { List<T> descendedViewList = new ArrayList<T>(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); Class<? extends View> childsClass = child.getClass(); if ((includeSubClass && filter.isAssignableFrom(childsClass)) || (!includeSubClass && childsClass == filter)) { descendedViewList.add(filter.cast(child)); } if (child instanceof ViewGroup) { descendedViewList.addAll(getDescendants((ViewGroup) child, filter, includeSubClass)); } } return descendedViewList; } /** * Helps determine if the app is running in a Tablet context. * * @param context * @return */ public static boolean isTablet(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } }