下面列出了android.view.View#layout ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
final int count = getChildCount();
int cLeft = 0;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() == View.GONE)
continue;
// child.setVisibility(View.VISIBLE);
final int childWidth = child.getMeasuredWidth();
child.layout(cLeft, 0, cLeft + childWidth,
child.getMeasuredHeight());
cLeft += childWidth;
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static Bitmap b(View view) {
Bitmap bitmap = null;
view.measure(View.MeasureSpec.makeMeasureSpec(0, 0),
View.MeasureSpec.makeMeasureSpec(0, 0));
int i = view.getMeasuredWidth();
int j = view.getMeasuredHeight();
view.layout(0, 0, i, j);
view.setDrawingCacheEnabled(false);
view.setWillNotCacheDrawing(true);
view.setDrawingCacheEnabled(false);
view.setWillNotCacheDrawing(true);
if (i > 0 && j > 0) {
bitmap = Bitmap.createBitmap(i, j,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
if (Build.VERSION.SDK_INT >= 11)
view.setLayerType(1, null);
view.draw(canvas);
}
return bitmap;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
childCount = getChildCount(); // 获取子视图数
childWidth = childCount > 0 ? getChildAt(0).getMeasuredWidth() : 0; // 获取字节点的宽度
if (!setShareWindowFlag && defaultWindow >= 0
&& defaultWindow <= childCount - 1) {
// 设置默认窗口的左端距离
offset = -1 * defaultWindow * childWidth;
setShareWindowFlag = true;
}
// 设置距离(0,0)点X轴方向的初始距离
int left = 0 + offset;
for (int i = 0; i < childCount; i++) {
// 设置每个子视图在布局中的位置
View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
child.layout(left, 0, childWidth + left,
child.getMeasuredHeight());
left = left + childWidth;
}
}
}
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {
int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(widgetInfo.spanX,
widgetInfo.spanY, widgetInfo, false);
int visibility = layout.getVisibility();
layout.setVisibility(VISIBLE);
int width = MeasureSpec.makeMeasureSpec(unScaledSize[0], MeasureSpec.EXACTLY);
int height = MeasureSpec.makeMeasureSpec(unScaledSize[1], MeasureSpec.EXACTLY);
Bitmap b = Bitmap.createBitmap(unScaledSize[0], unScaledSize[1],
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
layout.measure(width, height);
layout.layout(0, 0, unScaledSize[0], unScaledSize[1]);
layout.draw(c);
c.setBitmap(null);
layout.setVisibility(visibility);
return b;
}
/**
* Return the bitmap of screen.
*
* @param activity The activity.
* @param isDeleteStatusBar True to delete status bar, false otherwise.
* @return the bitmap of screen
*/
public static Bitmap screenShot(@NonNull final Activity activity, boolean isDeleteStatusBar) {
View decorView = activity.getWindow().getDecorView();
boolean drawingCacheEnabled = decorView.isDrawingCacheEnabled();
boolean willNotCacheDrawing = decorView.willNotCacheDrawing();
decorView.setDrawingCacheEnabled(true);
decorView.setWillNotCacheDrawing(false);
Bitmap bmp = decorView.getDrawingCache();
if (bmp == null) {
decorView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
decorView.layout(0, 0, decorView.getMeasuredWidth(), decorView.getMeasuredHeight());
decorView.buildDrawingCache();
bmp = Bitmap.createBitmap(decorView.getDrawingCache());
}
if (bmp == null) {
return null;
}
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Bitmap ret;
if (isDeleteStatusBar) {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = resources.getDimensionPixelSize(resourceId);
ret = Bitmap.createBitmap(bmp,
0,
statusBarHeight,
dm.widthPixels,
dm.heightPixels - statusBarHeight);
} else {
ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
}
decorView.destroyDrawingCache();
decorView.setWillNotCacheDrawing(willNotCacheDrawing);
decorView.setDrawingCacheEnabled(drawingCacheEnabled);
return ret;
}
/**
* 当菜单被ContentView遮住的时候,要设置菜单为Invisible,防止已隐藏的菜单接收到点击事件。
*/
private void updateMenu() {
View contentView = getContentView();
if (contentView != null) {
int contentLeft = contentView.getLeft();
if (contentLeft == 0) {
for (View view : mMenus.values()) {
if (checkAbsoluteGravity(view, Gravity.LEFT)) {
view.layout(-view.getWidth(), view.getTop(), 0, view.getBottom());
} else {
view.layout(getMeasuredWidth(), view.getTop(),
getMeasuredWidth() + view.getMeasuredWidth(), view.getBottom());
}
}
} else {
if (mCurrentMenu != null && mCurrentMenu.getLeft() != 0) {
if (isLeftMenu()) {
mCurrentMenu.layout(0, mCurrentMenu.getTop(),
mCurrentMenu.getMeasuredWidth(), mCurrentMenu.getBottom());
} else {
mCurrentMenu.layout(
getMeasuredWidth() - mCurrentMenu.getMeasuredWidth(),
mCurrentMenu.getTop(),
getMeasuredWidth(),
mCurrentMenu.getBottom());
}
}
}
}
}
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
View view = getChildAt(1);
int left = startScrollLeftOffset + scroller.getCurrX();
view.layout(left, view.getTop(), left + view.getWidth(),
view.getHeight());
postInvalidate();
}
}
protected int positionChild(View child, int x, int y, int contentHeight) {
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
int childTop = y + (contentHeight - childHeight) / 2;
child.layout(x, childTop, x + childWidth, childTop + childHeight);
return childWidth;
}
protected int positionChildInverse(View child, int x, int y, int contentHeight) {
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
int childTop = y + (contentHeight - childHeight) / 2;
child.layout(x - childWidth, childTop, x, childTop + childHeight);
return childWidth;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight());
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final View child = getChildAt(0);
if (child == null) {
return;
}
if (mGravity == Gravity.TOP) {
child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
} else {
child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();// 获取子组件数
int row = 1;// 子组件行数,初始化赋值为1
int left = 0;// 子组件的左边“坐标”
int right = 0;// 子组件的右边“坐标”
int top = 0;// 子组件的顶部“坐标”
int bottom = 0;// 子组件的底部“坐标”
int p = getPaddingLeft();// 在父组件中设置的padding属性的值,该值显然也会影响到子组件在屏幕的显示位置
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
int width = view.getMeasuredWidth();// 测量子组件的宽
int height = view.getMeasuredHeight();// 测量子组件的高
left = p + right;// ---------------------------------------------------备注1
right = left + width;// -----------------------------------------------备注2
top = p * row + height * (row - 1);// ---------------------------------备注3
bottom = top + height;// ----------------------------------------------备注4
if (right > maxWidth) {
row++;
left = 0;//每次换行后要将子组件左边“坐标”与右边“坐标”重新初始化
right = 0;
left = p + right ;
right = left + width;
top = p * row + height * (row - 1);
bottom = top + height;
}
view.layout(left, top, right, bottom);// 最后按照计算出来的“坐标”将子组件放在父容器内
}
}
public Bitmap loadBitmapFromView(View view) {
if (view.getMeasuredHeight() <= 0) {
view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
loadedBitmap = true;
view.draw(canvas);
return bitmap;
}
@Override
protected void onLayout(boolean changed,
int l, int t, int r, int b) {
int childCount = getChildCount();
// 设置ViewGroup的高度
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
mlp.height = mScreenHeight * childCount;
setLayoutParams(mlp);
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
child.layout(l, i * mScreenHeight,r, (i + 1) * mScreenHeight);
}
}
}
@Override
protected void onLayout(final boolean changed, final int l, final int t,
final int r, final int b) {
int maxWidth = r - l;
int line = 1;
int xPos = 0;
int padding = 12;
int size = getChildCount();
for (int i = 0; i < size; ++i) {
final View child = getChildAt(i);
int w = child.getMeasuredWidth();
int h = child.getMeasuredHeight();
if (xPos + w + padding > maxWidth) {
// break line
line++;
xPos = 0;
}
int left = xPos + padding;
int top = maxLineHeight * line;
int right = left + w;
int bottom = top + h;
child.layout(left, top, right, bottom);
xPos += w + padding;
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mTracking) {
return;
}
final int width = r - l;
final int height = b - t;
final View handle = mHandle;
int childWidth = handle.getMeasuredWidth();
int childHeight = handle.getMeasuredHeight();
int childLeft;
int childTop;
final View content = mContent;
if (mVertical) {
childLeft = (width - childWidth) / 2;
childTop = mExpanded ? mTopOffset : height - childHeight + mBottomOffset;
content.layout(0, mTopOffset + childHeight, content.getMeasuredWidth(),
mTopOffset + childHeight + content.getMeasuredHeight());
} else {
childLeft = mExpanded ? mTopOffset : width - childWidth + mBottomOffset;
childTop = (height - childHeight) / 2;
content.layout(mTopOffset + childWidth, 0,
mTopOffset + childWidth + content.getMeasuredWidth(),
content.getMeasuredHeight());
}
handle.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
mHandleHeight = handle.getHeight();
mHandleWidth = handle.getWidth();
}
private Bitmap loadBitmap(int width, int height, int index) {
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(mBitmapIds[index],null);
v.measure(MeasureSpec.makeMeasureSpec(width,MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
protected void onLayout(boolean flag, int i, int j, int k, int i1)
{
int j1;
int k1;
int l1;
j1 = getPaddingLeft();
k1 = getPaddingTop();
l1 = getSlidingTop();
int i2 = getChildCount();
if (mFirstLayout)
{
int j2;
switch (l.a[mSlideState.ordinal()])
{
default:
mSlideOffset = 1.0F;
break;
case 1: // '\001'
float f1;
if (mCanSlide)
{
f1 = 0.0F;
} else
{
f1 = 1.0F;
}
mSlideOffset = f1;
continue;
case 2: // '\002'
float f;
if (mCanSlide)
{
f = mAnchorPoint;
} else
{
f = 1.0F;
}
mSlideOffset = f;
continue;
}
break;
}
do
{
j2 = 0;
while (j2 < i2)
{
View view = getChildAt(j2);
if (view.getVisibility() != 8)
{
LayoutParams layoutparams = (LayoutParams)view.getLayoutParams();
int k2 = view.getMeasuredHeight();
if (layoutparams.slideable)
{
mSlideRange = k2 - mPanelHeight;
}
int l2;
if (mIsSlidingUp)
{
int i3;
int j3;
if (layoutparams.slideable)
{
j3 = l1 + (int)((float)mSlideRange * mSlideOffset);
} else
{
j3 = k1;
}
l2 = j3;
} else
{
if (layoutparams.slideable)
{
l2 = l1 - (int)((float)mSlideRange * mSlideOffset);
} else
{
l2 = k1;
}
if (!layoutparams.slideable && !mOverlayContent)
{
l2 += mPanelHeight;
}
}
i3 = l2 + k2;
view.layout(j1, l2, j1 + view.getMeasuredWidth(), i3);
}
j2++;
}
if (mFirstLayout)
{
updateObscuredViewVisibility();
}
mFirstLayout = false;
return;
} while (true);
}
/**
* 可以绘制在内容的上面,覆盖内容
*
* @param c
* @param parent
* @param state
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onDrawOver(Canvas c, final RecyclerView parent, RecyclerView.State state) {
// 当前屏幕的第一个item
int pos = ((LinearLayoutManager) (parent.getLayoutManager())).findFirstVisibleItemPosition();
String tag = mDatas.get(pos).getTag();
Log.e(TAG, "onDrawOver: pos:" + pos + "\ttag:" + tag);
View child = parent.findViewHolderForLayoutPosition(pos).itemView;
// 当发现下一个title顶上来的时候,将canvas向上平移,产生一种向上挤压的动画效果
boolean flag = false;
if ((pos + 1) < mDatas.size()) {
String suspensionTag = mDatas.get(pos + 1).getTag();
if (null != tag && !tag.equals(suspensionTag)) {
if (child.getHeight() + child.getTop() < mTitleHeight) {
c.save();
flag = true;
c.translate(0, child.getHeight() + child.getTop() - mTitleHeight);
}
}
}
// 绘制一个与列表中标题一样的东西(吸顶效果)
View topTitleView = mInflater.inflate(R.layout.item_title, parent, false);
TextView tvTitle = (TextView) topTitleView.findViewById(R.id.tv_title);
tvTitle.setText("测试数据" + tag);
int toDrawWidthSpec;//用于测量的widthMeasureSpec
int toDrawHeightSpec;//用于测量的heightMeasureSpec
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) topTitleView.getLayoutParams();
if (lp == null) {
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);//这里是根据复杂布局layout的width height,new一个Lp
// topTitleView.setLayoutParams(lp);
}
topTitleView.setLayoutParams(lp);
if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
//如果是MATCH_PARENT,则用父控件能分配的最大宽度和EXACTLY构建MeasureSpec。
toDrawWidthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight(), View.MeasureSpec.EXACTLY);
} else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
//如果是WRAP_CONTENT,则用父控件能分配的最大宽度和AT_MOST构建MeasureSpec。
toDrawWidthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight(), View.MeasureSpec.AT_MOST);
} else {
//否则则是具体的宽度数值,则用这个宽度和EXACTLY构建MeasureSpec。
toDrawWidthSpec = View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY);
}
//高度同理
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT) {
toDrawHeightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight() - parent.getPaddingTop() - parent.getPaddingBottom(), View.MeasureSpec.EXACTLY);
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
toDrawHeightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight() - parent.getPaddingTop() - parent.getPaddingBottom(), View.MeasureSpec.AT_MOST);
} else {
toDrawHeightSpec = View.MeasureSpec.makeMeasureSpec(mTitleHeight, View.MeasureSpec.EXACTLY);
}
//依次调用 measure,layout,draw方法,将复杂头部显示在屏幕上。
topTitleView.measure(toDrawWidthSpec, toDrawHeightSpec);
topTitleView.layout(parent.getPaddingLeft(), parent.getPaddingTop(), parent.getPaddingLeft() + topTitleView.getMeasuredWidth(), parent.getPaddingTop() + topTitleView.getMeasuredHeight());
topTitleView.draw(c);//Canvas默认在视图顶部,无需平移,直接绘制
if (flag)
c.restore();//恢复画布到之前保存的状态
if (!TextUtils.equals(tag, currentTag)) {
currentTag = tag;
Integer integer = Integer.valueOf(currentTag);
Log.e(TAG, "onDrawOver: " + integer);
mCheckListener.check(integer);
}
}
protected void onLayoutChild(View child, int position, int l, int t, int r, int b) {
child.layout(l, t, r, b);
}