1 通过继承ViewGroup时一般都要重写onMeasure() onLayout()方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取模式和大小,边界参数共有3种模式:UNSPECIFIED一般为0, EXACTLY准确尺寸, AT_MOST自适应尺寸
int w_mode = MeasureSpec.getMode(widthMeasureSpec);
int w_size = MeasureSpec.getSize(widthMeasureSpec);
int h_mode = MeasureSpec.getMode(heightMeasureSpec);
int h_size = MeasureSpec.getSize(heightMeasureSpec);
//计算自定义的所有子控件的大小
measureChildren(widthMeasureSpec, heightMeasureSpec);
//通知父控件,宽高需要多大地方放置子控件
//setMeasuredDimension(resolveSize(size, widthMeasureSpec),resolveSize(size, heightMeasureSpec));
setMeasuredDimension(w_size, h_size);
Log.e("onMeasure","宽mode=" + w_mode + "宽size="+ w_size
+ "高mode=" + h_mode+ "高size=" +h_size);
// super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
//onLayout是为了指定视图的显示位置,方法执行的前后顺序是在onMeasure之后,因为视图肯定是只有知道大小才能指定位置放置
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// 记录总高度
int mTotalHeight = 0;
// 遍历所有子视图
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// 获取在onMeasure中计算的视图尺寸
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
childView.layout(l, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);
mTotalHeight += measureHeight;
}
}
2 获取View控件宽高大小
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus){
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(spec,spec);
int measuredWidth=view.getMeasuredWidth();int measuredHeight=view.getMeasuredHeight();//原始大小
int width=view.getWidth();int height=view.getHeight();//真实大小
LinearLayout.LayoutParams lp=(LinearLayout.LayoutParams)view.getLayoutParams();
lp.width=width;
lp.height=width*(measuredHeight / measuredWidth);
view.setLayoutParams(lp);//设置大小
}
}
附:屏幕和控件计算
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.RelativeLayout;
public class DisplayUtils {
private DisplayUtils(){}
/**
* display widthpixels
*/
public static int widthPixels(Context context){
final float scale = context.getResources().getDisplayMetrics().widthPixels;
return (int) scale;
}
/**
* display heightpixels
*/
public static int heightPixels(Context context){
final float scale = context.getResources().getDisplayMetrics().heightPixels;
return (int) scale;
}
/**
* dp2px
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
*自适应listview gridview真实高度
*/
@SuppressLint("NewApi")
public static void setViewHeight(final ListView listView, GridView gridView, int gridheight) {
if (listView!=null&&listView.getAdapter()!=null) {
listView.post(new Runnable() {
@Override
public void run() {
int totalHeight = 0;
int widthSpec = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),View.MeasureSpec.AT_MOST);
for(int i = 0,len = listView.getAdapter().getCount();i<len;i++){//返回数据项的数目
View listItem = listView.getAdapter().getView(i, null, listView);
listItem.measure(widthSpec,0);//计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight();//统计所有子项的总高度
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height =totalHeight +(listView.getDividerHeight()*(listView.getAdapter().getCount()-1));
//listView.getDividerHeight()获取子项间分隔符占用的高度
listView.setLayoutParams(params);
}
});
}
if (gridView!=null&&gridView.getAdapter()!=null) {
int totalHeight = 0;
int columns=gridView.getNumColumns();//每行几个
int rows;//共几行
if(gridView.getAdapter().getCount()%columns>0){
rows=gridView.getAdapter().getCount()/columns+1;
}else {
rows=gridView.getAdapter().getCount()/columns;
}
for (int i = 0; i < rows; i++) { //只计算每项高度*行数
View listItem = gridView.getAdapter().getView(i, null, gridView);
listItem.measure(0, 0); // 计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
}
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight + gridheight*(rows-1);//最后加上分割线总高度
gridView.setLayoutParams(params);
}
}
/**
* 横屏竖屏切换
* @param activity
* @param vv
*/
public static void setFull(Activity activity,View vv){
if (activity.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT){
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//横屏
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
vv.setLayoutParams(lp);//!!上级布局RelativeLayout
}else{
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,580);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
vv.setLayoutParams(lp);//!!上级布局RelativeLayout
}
}
/**
* 输入法判断
* @param activity
* @return isSoftShowing
*/
public static boolean isSoftShowing(Activity activity){
int screenHeight = activity.getWindow().getDecorView().getHeight();
Rect rect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int appHeight = rect.bottom;
return screenHeight*2/3 > appHeight;
}
}