android中部分控件具有maxHeight功能,如button,但是对于ViewGroup类的控件,没有此属性,那么,如何为ViewGroup添加一个最大高度的属性呢?其实很简单,主要就是使用onMeasure()函数,在函数中控制高度即可。
先看下效果图:
这是一个dialog,dialog中添加了共有17个button,如果不使用最大高度可控的view,则体验效果不好,可能会完全遮住后边的背景。
java代码实现如下:
1 package cn.carbs.maxheightview; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.util.AttributeSet; 6 import android.util.Log; 7 import android.view.View; 8 import android.view.WindowManager; 9 import android.widget.FrameLayout; 10 11 /** 12 * 先判断是否设定了mMaxHeight,如果设定了mMaxHeight,则直接使用mMaxHeight的值, 13 * 如果没有设定mMaxHeight,则判断是否设定了mMaxRatio,如果设定了mMaxRatio的值 14 * 则使用此值与屏幕高度的乘积作为最高高度 15 * @author Rick.Wang 16 * 17 */ 18 public class MaxHeightView extends FrameLayout{ 19 20 private static final float DEFAULT_MAX_RATIO = 0.4f; 21 private static final float DEFAULT_MAX_HEIGHT = -1f; 22 23 private Context mContext; 24 private float mMaxHeight = DEFAULT_MAX_HEIGHT;//优先级高 25 private float mMaxRatio = DEFAULT_MAX_RATIO;//优先级低 26 27 public MaxHeightView(Context context) { 28 this(context, null); 29 } 30 31 public MaxHeightView(Context context, AttributeSet attrs) { 32 this(context, attrs, 0); 33 } 34 35 public MaxHeightView(Context context, AttributeSet attrs, int defStyle) { 36 super(context, attrs, defStyle); 37 mContext = context; 38 39 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.maxHeightView); 40 41 final int count = a.getIndexCount(); 42 for (int i = 0; i < count; ++i) { 43 int attr = a.getIndex(i); 44 switch (attr) { 45 case R.styleable.maxHeightView_maxHeightRatio: 46 mMaxRatio = a.getFloat(attr, DEFAULT_MAX_RATIO); 47 break; 48 case R.styleable.maxHeightView_maxHeightDimen: 49 mMaxHeight = a.getDimension(attr, DEFAULT_MAX_HEIGHT); 50 break; 51 } 52 } 53 a.recycle(); 54 55 if(mMaxHeight < 0){ 56 mMaxHeight = mMaxRatio * (float)getScreenHeight(mContext); 57 } 58 } 59 60 @Override 61 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 62 63 int heightMode = View.MeasureSpec.getMode(heightMeasureSpec); 64 int heightSize = View.MeasureSpec.getSize(heightMeasureSpec); 65 66 Log.d("wang", "onMeasure heightSize is " + heightSize + " | mMaxHeight is " + mMaxHeight); 67 68 if(heightMode == View.MeasureSpec.EXACTLY){ 69 Log.d("wang", "heightMode == View.MeasureSpec.EXACTLY"); 70 heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight; 71 } 72 73 if(heightMode == View.MeasureSpec.UNSPECIFIED){ 74 Log.d("wang", "heightMode == View.MeasureSpec.UNSPECIFIED"); 75 heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight; 76 } 77 if(heightMode == View.MeasureSpec.AT_MOST){ 78 Log.d("wang", "heightMode == View.MeasureSpec.AT_MOST"); 79 heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight; 80 } 81 82 int maxHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(heightSize, heightMode); 83 84 super.onMeasure(widthMeasureSpec, maxHeightMeasureSpec); 85 } 86 87 88 /** 89 * 获取屏幕高度 90 * @param context 91 */ 92 public static int getScreenHeight(Context context){ 93 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 94 return wm.getDefaultDisplay().getHeight(); 95 } 96 97 /** 98 * 获取屏幕宽度 99 * @param context 100 */ 101 public static int getScreenWidth(Context context){ 102 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 103 return wm.getDefaultDisplay().getWidth(); 104 } 105 106 /** 107 * 获取屏幕大小 108 * @param context 109 * @param outDimension 110 */ 111 public static void getScreenDimension(Context context, int[] outDimension){ 112 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 113 outDimension[0] = wm.getDefaultDisplay().getWidth(); 114 outDimension[1] = wm.getDefaultDisplay().getHeight(); 115 } 116 117 }
属性文件如下:
attrs.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <declare-styleable name="maxHeightView"> 5 <attr name="maxHeightRatio" format="reference|float" /> 6 <attr name="maxHeightDimen" format="reference|dimension" /> 7 </declare-styleable> 8 9 10 </resources>
使用方法:
在布局中使用如下代码:
1 <cn.carbs.maxheightview.MaxHeightView 2 android:id="@+id/maxview" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 app:maxHeightRatio="0.7" > 6 7 <ScrollView 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" > 10 11 <LinearLayout 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:orientation="vertical" > 15 16 <Button 17 android:id="@+id/button0" 18 android:layout_width="match_parent" 19 android:layout_height="60dp" 20 android:text="button0" /> 21 ............... 22 23 </LinearLayout> 24 </ScrollView> 25 </cn.carbs.maxheightview.MaxHeightView>
要注意,此自定义view继承自FrameLayout,使用时最好嵌套一个ScrollView,以提高用户体验
时间: 2024-10-12 23:23:26