下面列出了android.widget.ListAdapter#getView ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 重新計算GridView的高度
*
* @param gridView
*/
public static void setGridViewHeightBasedOnChildren(GridView gridView, int columns) {
ListAdapter listAdapter = gridView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount() / columns; i++) {
View listItem = listAdapter.getView(i, null, gridView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight + (listAdapter.getCount() - 1);
gridView.setLayoutParams(params);
gridView.requestLayout();
}
/**
* @author sunglasses
* @param listView
* @category 计算listview高度
*/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
/**
* Get a View that displays the data at the specified position in the data
* set.
*
* @param position Position of the item whose data we want
* @param convertView View to recycle, if not null
* @param parent ViewGroup containing the returned View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
for (ListAdapter piece : pieces) {
int size = piece.getCount();
if (position < size) {
return (piece.getView(position, convertView, parent));
}
position -= size;
}
return (null);
}
/**
* 计算ListView的高度, 重置ListView的高度.
*
* @param listView
*/
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
{
return;
}
View listItem = null;
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++)
{
listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
/**
* Get a View that displays the data at the specified
* position in the data set.
*
* @param position
* Position of the item whose data we want
* @param convertView
* View to recycle, if not null
* @param parent
* ViewGroup containing the returned View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
for (ListAdapter piece : getPieces()) {
int size=piece.getCount();
if (position < size) {
return(piece.getView(position, convertView, parent));
}
position-=size;
}
return(null);
}
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
/**
* Get a View that displays the data at the specified position in the data
* set.
*
* @param position Position of the item whose data we want
* @param convertView View to recycle, if not null
* @param parent ViewGroup containing the returned View
*/
public View getView(int position, View convertView, ViewGroup parent) {
for (ListAdapter piece : pieces) {
int size = piece.getCount();
if (position < size) {
return piece.getView(position, convertView, parent);
}
position -= size;
}
if (noItemsText != null) {
TextView text = new TextView(parent.getContext());
text.setText(noItemsText);
return text;
}
return null;
}
/**
* @param
* @return int 返回类型
* @Title getListViewHeightBasedOnChildren
* @Description 得到children的高度
*/
public static int getListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return 0;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
int itemHeight = listItem.getMeasuredHeight();
System.out.println("itemHeight itemHeight:" + itemHeight);
totalHeight += itemHeight;
}
int height = (int) (totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1)) + 0.5);
return height;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = 0;
ListAdapter adapter = getAdapter();
int count = adapter.getCount();
for (int i = 0; i < count; i++) {
View childView = adapter.getView(i, null, this);
childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height += childView.getMeasuredHeight();
}
Rect bgPadding = new Rect();
getBackground().getPadding(bgPadding);
height += (count - 1) * getDividerHeight() + bgPadding.top + bgPadding.bottom;
setMeasuredDimension(width, height);
}
/**
* 手动设置listview的高度,包裹所有元素
* @param listView
*/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
public static int getAbsListViewHeight(AbsListView absListView, int lineNumber, int verticalSpace) {
int totalHeight = 0;
int w = MeasureSpec.makeMeasureSpec(0, 0);
int h = MeasureSpec.makeMeasureSpec(0, 0);
absListView.measure(w, h);
ListAdapter mListAdapter = (ListAdapter) absListView.getAdapter();
if (mListAdapter == null) {
return 0;
}
int count = mListAdapter.getCount();
View listItem;
if (absListView instanceof ListView) {
for (int i = 0; i < count; i++) {
listItem = mListAdapter.getView(i, null, absListView);
listItem.measure(w, h);
totalHeight += listItem.getMeasuredHeight();
}
if (count == 0) {
totalHeight = verticalSpace;
} else {
totalHeight += ((ListView) absListView).getDividerHeight() * (count - 1);
}
} else if (absListView instanceof GridView) {
int remain = count % lineNumber;
if (remain > 0) {
remain = 1;
}
if (mListAdapter.getCount() == 0) {
totalHeight = verticalSpace;
} else {
listItem = mListAdapter.getView(0, null, absListView);
listItem.measure(w, h);
int line = (count / lineNumber) + remain;
totalHeight = (listItem.getMeasuredHeight() * line) + ((line - 1) * verticalSpace);
}
}
return totalHeight;
}
/**
* This method adjusts the height of the given listView to match the combined height of all if its
* children and the dividers between list items. This is used to set the height of the mash step
* list such that it does not scroll, since it is encompassed by a ScrollView.
*
* @param listView
* ListView to adjust.
*/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
if (i == 0) {
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
//totalHeight += view.getMeasuredHeight();
}
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
@Override
public void setAdapter(ListAdapter adapter) {
if(isScroll)
{
int gridViewWidth = 0;
int adapterCount = adapter.getCount();
if(columnWidth == 0)
{
for(int i = 0 ; i< adapter.getCount();i++)
{
View rowView = adapter.getView(i,null,null);
measureView(rowView);
gridViewWidth += rowView.getMeasuredWidth();
}
}
else
{
gridViewWidth += columnWidth*adapterCount;
}
if(isAutoSetNumColumns)
{
gridViewWidth += (this.getPaddingLeft()+ this.getPaddingRight());
gridViewWidth += this.horizontalSpacing*(adapterCount-1);
this.setNumColumns(adapterCount);
}
this.setLayoutParams(new LinearLayout.LayoutParams(gridViewWidth,LayoutParams.WRAP_CONTENT));
}
super.setAdapter(adapter);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty()) {
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(mParams);
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
if (newHeight > heightSize) {
newHeight = heightSize;
}
}
} else {
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
public static void updateListViewHeight(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null)
return;
// Get listView height
int totalHeight = myListView.getPaddingTop() + myListView.getPaddingBottom();
int adapterCount = myListAdapter.getCount();
for (int i = 0; i < adapterCount; i++) {
View listItem = myListAdapter.getView(i, null, myListView);
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
// Change height of listView
ViewGroup.LayoutParams paramsList = myListView.getLayoutParams();
paramsList.height = totalHeight + (myListView.getDividerHeight() * (adapterCount - 1));
myListView.setLayoutParams(paramsList);
}
private int measureContentWidth() {
ListAdapter adapter = getAdapter();
TextInputLayout textInputLayout = findTextInputLayoutAncestor();
if (adapter == null || textInputLayout == null) {
return 0;
}
int width = 0;
View itemView = null;
int itemType = 0;
final int widthMeasureSpec =
MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec =
MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.UNSPECIFIED);
// Cap the number of items that will be measured.
int start = Math.max(0, modalListPopup.getSelectedItemPosition());
final int end = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED);
start = Math.max(0, end - MAX_ITEMS_MEASURED);
for (int i = start; i < end; i++) {
final int positionType = adapter.getItemViewType(i);
if (positionType != itemType) {
itemType = positionType;
itemView = null;
}
itemView = adapter.getView(i, itemView, textInputLayout);
if (itemView.getLayoutParams() == null) {
itemView.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
}
itemView.measure(widthMeasureSpec, heightMeasureSpec);
width = Math.max(width, itemView.getMeasuredWidth());
}
// Add background padding to measured width.
Drawable background = modalListPopup.getBackground();
if (background != null) {
background.getPadding(tempRect);
width += tempRect.left + tempRect.right;
}
// Add icon width to measured width.
int iconWidth = textInputLayout.getEndIconView().getMeasuredWidth();
width += iconWidth;
return width;
}
/**
* Measures the height of the given range of children (inclusive) and returns the height
* with this ListView's padding and divider heights included. If maxHeight is provided, the
* measuring will stop when the current height reaches maxHeight.
*
* @param widthMeasureSpec The width measure spec to be given to a child's
* {@link View#measure(int, int)}.
* @param startPosition The position of the first child to be shown.
* @param endPosition The (inclusive) position of the last child to be
* shown. Specify {@link #NO_POSITION} if the last child
* should be the last available child from the adapter.
* @param maxHeight The maximum height that will be returned (if all the
* children don't fit in this value, this value will be
* returned).
* @param disallowPartialChildPosition In general, whether the returned height should only
* contain entire children. This is more powerful--it is
* the first inclusive position at which partial
* children will not be allowed. Example: it looks nice
* to have at least 3 completely visible children, and
* in portrait this will most likely fit; but in
* landscape there could be times when even 2 children
* can not be completely shown, so a value of 2
* (remember, inclusive) would be good (assuming
* startPosition is 0).
* @return The height of this ListView with the given children.
*/
public int measureHeightOfChildrenCompat(int widthMeasureSpec, int startPosition,
int endPosition, final int maxHeight,
int disallowPartialChildPosition) {
final int paddingTop = getListPaddingTop();
final int paddingBottom = getListPaddingBottom();
final int paddingLeft = getListPaddingLeft();
final int paddingRight = getListPaddingRight();
final int reportedDividerHeight = getDividerHeight();
final Drawable divider = getDivider();
final ListAdapter adapter = getAdapter();
if (adapter == null) {
return paddingTop + paddingBottom;
}
// Include the padding of the list
int returnedHeight = paddingTop + paddingBottom;
final int dividerHeight = ((reportedDividerHeight > 0) && divider != null)
? reportedDividerHeight : 0;
// The previous height value that was less than maxHeight and contained
// no partial children
int prevHeightWithoutPartialChild = 0;
View child = null;
int viewType = 0;
int count = adapter.getCount();
for (int i = 0; i < count; i++) {
int newType = adapter.getItemViewType(i);
if (newType != viewType) {
child = null;
viewType = newType;
}
child = adapter.getView(i, child, this);
// Compute child height spec
int heightMeasureSpec;
ViewGroup.LayoutParams childLp = child.getLayoutParams();
if (childLp == null) {
childLp = generateDefaultLayoutParams();
child.setLayoutParams(childLp);
}
if (childLp.height > 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(childLp.height,
MeasureSpec.EXACTLY);
} else {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(widthMeasureSpec, heightMeasureSpec);
// Since this view was measured directly aginst the parent measure
// spec, we must measure it again before reuse.
child.forceLayout();
if (i > 0) {
// Count the divider for all but one child
returnedHeight += dividerHeight;
}
returnedHeight += child.getMeasuredHeight();
if (returnedHeight >= maxHeight) {
// We went over, figure out which height to return. If returnedHeight >
// maxHeight, then the i'th position did not fit completely.
return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1)
&& (i > disallowPartialChildPosition) // We've past the min pos
&& (prevHeightWithoutPartialChild > 0) // We have a prev height
&& (returnedHeight != maxHeight) // i'th child did not fit completely
? prevHeightWithoutPartialChild
: maxHeight;
}
if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
prevHeightWithoutPartialChild = returnedHeight;
}
}
// At this point, we went through the range of children, and they each
// completely fit, so return the returnedHeight
return returnedHeight;
}
/**
* 通过 ListView 绘制为 Bitmap
* @param listView {@link ListView}
* @param config {@link Bitmap.Config}
* @return {@link Bitmap}
*/
public static Bitmap snapshotByListView(final ListView listView, final Bitmap.Config config) {
if (listView == null || config == null) return null;
try {
// Adapter
ListAdapter listAdapter = listView.getAdapter();
// Item 总条数
int itemCount = listAdapter.getCount();
// 没数据则直接跳过
if (itemCount == 0) return null;
// 高度
int height = 0;
// 获取子项间分隔符占用的高度
int dividerHeight = listView.getDividerHeight();
// View Bitmaps
Bitmap[] bitmaps = new Bitmap[itemCount];
// 循环绘制每个 Item 并保存 Bitmap
for (int i = 0; i < itemCount; i++) {
View childView = listAdapter.getView(i, null, listView);
WidgetUtils.measureView(childView, listView.getWidth());
bitmaps[i] = canvasBitmap(childView, config);
height += childView.getMeasuredHeight();
}
// 追加子项间分隔符占用的高度
height += (dividerHeight * (itemCount - 1));
int width = listView.getMeasuredWidth();
// 创建位图
Bitmap bitmap = Bitmap.createBitmap(width, height, config);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(BACKGROUND_COLOR);
// 累加高度
int appendHeight = 0;
for (int i = 0, len = bitmaps.length; i < len; i++) {
Bitmap bmp = bitmaps[i];
canvas.drawBitmap(bmp, 0, appendHeight, PAINT);
appendHeight += (bmp.getHeight() + dividerHeight);
// 释放资源
bmp.recycle();
bmp = null;
}
return bitmap;
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "snapshotByListView");
}
return null;
}
private int getChildHeight(int position) {
if (position == mSrcPos) {
return 0;
}
View v = getChildAt(position - getFirstVisiblePosition());
if (v != null) {
// item is onscreen, therefore child height is valid,
// hence the "true"
return getChildHeight(position, v, false);
} else {
// item is offscreen
// first check cache for child height at this position
int childHeight = mChildHeightCache.get(position);
if (childHeight != -1) {
// Log.d("mobeta", "found child height in cache!");
return childHeight;
}
final ListAdapter adapter = getAdapter();
int type = adapter.getItemViewType(position);
// There might be a better place for checking for the following
final int typeCount = adapter.getViewTypeCount();
if (typeCount != mSampleViewTypes.length) {
mSampleViewTypes = new View[typeCount];
}
if (type >= 0) {
if (mSampleViewTypes[type] == null) {
v = adapter.getView(position, null, this);
mSampleViewTypes[type] = v;
} else {
v = adapter.getView(position, mSampleViewTypes[type], this);
}
} else {
// type is HEADER_OR_FOOTER or IGNORE
v = adapter.getView(position, null, this);
}
// current child height is invalid, hence "true" below
childHeight = getChildHeight(position, v, true);
// cache it because this could have been expensive
mChildHeightCache.add(position, childHeight);
return childHeight;
}
}
private int getChildHeight(int position) {
if (position == mSrcPos) {
return 0;
}
View v = getChildAt(position - getFirstVisiblePosition());
if (v != null) {
// item is onscreen, therefore child height is valid,
// hence the "true"
return getChildHeight(position, v, false);
} else {
// item is offscreen
// first check cache for child height at this position
int childHeight = mChildHeightCache.get(position);
if (childHeight != -1) {
// Log.d("mobeta", "found child height in cache!");
return childHeight;
}
final ListAdapter adapter = getAdapter();
int type = adapter.getItemViewType(position);
// There might be a better place for checking for the following
final int typeCount = adapter.getViewTypeCount();
if (typeCount != mSampleViewTypes.length) {
mSampleViewTypes = new View[typeCount];
}
if (type >= 0) {
if (mSampleViewTypes[type] == null) {
v = adapter.getView(position, null, this);
mSampleViewTypes[type] = v;
} else {
v = adapter.getView(position, mSampleViewTypes[type], this);
}
} else {
// type is HEADER_OR_FOOTER or IGNORE
v = adapter.getView(position, null, this);
}
// current child height is invalid, hence "true" below
childHeight = getChildHeight(position, v, true);
// cache it because this could have been expensive
mChildHeightCache.add(position, childHeight);
return childHeight;
}
}