您的位置:首页 > 移动开发 > Android开发

android自定义控件的最大高度MaxHeightView

2016-01-19 17:07 465 查看
android中部分控件具有maxHeight功能,如button,但是对于ViewGroup类的控件,没有此属性,那么,如何为ViewGroup添加一个最大高度的属性呢?其实很简单,主要就是使用onMeasure()函数,在函数中控制高度即可。

先看下效果图:



这是一个dialog,dialog中添加了共有17个button,如果不使用最大高度可控的view,则体验效果不好,可能会完全遮住后边的背景。

java代码实现如下:

package cn.carbs.maxheightview;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;

/**
* 先判断是否设定了mMaxHeight,如果设定了mMaxHeight,则直接使用mMaxHeight的值,
* 如果没有设定mMaxHeight,则判断是否设定了mMaxRatio,如果设定了mMaxRatio的值
* 则使用此值与屏幕高度的乘积作为最高高度
* @author Rick.Wang
*
*/
public class MaxHeightView extends FrameLayout{

private static final float DEFAULT_MAX_RATIO = 0.4f;
private static final float DEFAULT_MAX_HEIGHT = -1f;

private Context mContext;
private float mMaxHeight = DEFAULT_MAX_HEIGHT;//优先级高
private float mMaxRatio = DEFAULT_MAX_RATIO;//优先级低

public MaxHeightView(Context context) {
this(context, null);
}

public MaxHeightView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MaxHeightView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.maxHeightView);

final int count = a.getIndexCount();
for (int i = 0; i < count; ++i) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.maxHeightView_maxHeightRatio:
mMaxRatio = a.getFloat(attr, DEFAULT_MAX_RATIO);
break;
case R.styleable.maxHeightView_maxHeightDimen:
mMaxHeight = a.getDimension(attr, DEFAULT_MAX_HEIGHT);
break;
}
}
a.recycle();

if(mMaxHeight < 0){
mMaxHeight = mMaxRatio * (float)getScreenHeight(mContext);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);

Log.d("wang", "onMeasure heightSize is " + heightSize + " | mMaxHeight is " + mMaxHeight);

if(heightMode == View.MeasureSpec.EXACTLY){
Log.d("wang", "heightMode == View.MeasureSpec.EXACTLY");
heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight;
}

if(heightMode == View.MeasureSpec.UNSPECIFIED){
Log.d("wang", "heightMode == View.MeasureSpec.UNSPECIFIED");
heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight;
}
if(heightMode == View.MeasureSpec.AT_MOST){
Log.d("wang", "heightMode == View.MeasureSpec.AT_MOST");
heightSize = heightSize <= mMaxHeight ? heightSize : (int)mMaxHeight;
}

int maxHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(heightSize, heightMode);

super.onMeasure(widthMeasureSpec, maxHeightMeasureSpec);
}

/**
* 获取屏幕高度
* @param context
*/
public static int getScreenHeight(Context context){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return wm.getDefaultDisplay().getHeight();
}

/**
* 获取屏幕宽度
* @param context
*/
public static int getScreenWidth(Context context){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return wm.getDefaultDisplay().getWidth();
}

/**
* 获取屏幕大小
* @param context
* @param outDimension
*/
public static void getScreenDimension(Context context, int[] outDimension){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
outDimension[0] = wm.getDefaultDisplay().getWidth();
outDimension[1] = wm.getDefaultDisplay().getHeight();
}

}


属性文件如下:

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<declare-styleable name="maxHeightView">
<attr name="maxHeightRatio" format="reference|float" />
<attr name="maxHeightDimen" format="reference|dimension" />
</declare-styleable>

</resources>


使用方法:

在布局中使用如下代码:

<cn.carbs.maxheightview.MaxHeightView
android:id="@+id/maxview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:maxHeightRatio="0.7" >

<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<Button
android:id="@+id/button0"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="button0" />
...............

</LinearLayout>
</ScrollView>
</cn.carbs.maxheightview.MaxHeightView>


要注意,此自定义view继承自FrameLayout,使用时最好嵌套一个ScrollView,以提高用户体验
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: