android屏幕适配方案
2015-08-09 18:02
465 查看
以前看了android的屏幕适配方案,有很多种,其中自己用到的一种是:先找一款主流的分辨率的android机,如:1080*1920的分辨率做基准,然后在这个基准上,调整好一切布局,图片。适配其他手机分辨率的手机,用百分比来调节。例如:在480*800的主流手机上,写了一个height=520,那么在480*800的手机上,这个控件的高度则为
480height = 520 * 屏幕高度/1920. 这样的方案做屏幕适配。
项目遇到一个问题。在剩余空间里,在1080*1920的手机上适配很好,但是在480*800的低分辨率手机上则显示不完整。查看了原因:因为我的图片资源是240*240的。布局的ImageView的宽高是自适应的。所以会导致图片太大,而其余的字体,图片就不能完全显示。所以解决方案有2种:一是做低分辨率的资源图。二是外层嵌套scrollView控件,让其滑动显示剩余不能完全的部分。
动态布局首先要得到xml控件的宽高:
前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽。在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样。我测试了下面代码:
先是布局代码:
<com.lml.getvalues.MyView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="150px"
android:background="#ff0000" />
再是MyView的构造函数的代码:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
a="在MyView构造函数中 : MeasuredWidth:"+this.getMeasuredWidth()+";"+"MeasuredHeight:"+this.getMeasuredHeight()+";"
+"Width:"+this.getWidth()+";"+"Height:"+this.getHeight()+"\n";
String h="",w="";
for(int i =0 ;i < attrs.getAttributeCount();i++){
if("layout_height".equals(attrs.getAttributeName(i))){
h=attrs.getAttributeValue(i);
}else if("layout_width".equals(attrs.getAttributeName(i))){
w=attrs.getAttributeValue(i);
}
}
b="在构造函数attrs中 : width:"+w+";"+"height:"+h+"\n";
}
编译得到a="在MyView构造函数中 : MeasuredWidth:0;MeasuredHeight:0;Width:0;Height:0".
b="在构造函数attrs中 : width:-1;height:150.0px
结果显示当width为match_parent等数值时,只显示-1等,不能满足我的需求。
然后我试着在相应Activity的onCreate中获取高宽,获得的全部是0.但我在onCreate中的加了个点击控件获取高宽事件,能正确获取高宽。我在网上查了下资料,因为在onCreate中控件还未被度量,所以获取肯定为0.网上有获取三个方法,方法如下:
方法一,在onCreate中添加如下代码:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
myView.measure(w, h);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法一: height:"+height + ",width:" + width+"\n");
方法二可以实现,代码如下:
ViewTreeObserver vto2 = myView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
tvValues.append( "方法二: height:"+myView.getHeight() + ",width:" + myView.getWidth()+"\n");
}
});
但我发现removeGlobalOnLayoutListener在API 级别 16 开始已经废弃,如果去掉,系统会读取多次。
再来看看方法三,代码如下:
ViewTreeObserver vto = myView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法三: height:"+height + ",width:" + width + "..\n");
return true;
}
});
我在网上资料的基础上添加了myView.getViewTreeObserver().removeOnPreDrawListener(this);这一条,这个可以保证系统运行一次。
_____________________________________________________________________________________________________________
出现的问题:(1)用上面的2个回调监听函数,监听函数会一直调用,关闭不了,而且屏幕跳转会出现闪屏的现象。所以放弃了
(2) 选择使用第一种方法,如果xml里面是用的wrap_content宽高的,可以用getMeasureHeight()方法获取到控件的值,但是动态设置的值只有自己记住这个值大小
实现低分辨率适配效果:
高分辨率效果:
480height = 520 * 屏幕高度/1920. 这样的方案做屏幕适配。
项目遇到一个问题。在剩余空间里,在1080*1920的手机上适配很好,但是在480*800的低分辨率手机上则显示不完整。查看了原因:因为我的图片资源是240*240的。布局的ImageView的宽高是自适应的。所以会导致图片太大,而其余的字体,图片就不能完全显示。所以解决方案有2种:一是做低分辨率的资源图。二是外层嵌套scrollView控件,让其滑动显示剩余不能完全的部分。
动态布局首先要得到xml控件的宽高:
前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽。在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样。我测试了下面代码:
先是布局代码:
<com.lml.getvalues.MyView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="150px"
android:background="#ff0000" />
再是MyView的构造函数的代码:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
a="在MyView构造函数中 : MeasuredWidth:"+this.getMeasuredWidth()+";"+"MeasuredHeight:"+this.getMeasuredHeight()+";"
+"Width:"+this.getWidth()+";"+"Height:"+this.getHeight()+"\n";
String h="",w="";
for(int i =0 ;i < attrs.getAttributeCount();i++){
if("layout_height".equals(attrs.getAttributeName(i))){
h=attrs.getAttributeValue(i);
}else if("layout_width".equals(attrs.getAttributeName(i))){
w=attrs.getAttributeValue(i);
}
}
b="在构造函数attrs中 : width:"+w+";"+"height:"+h+"\n";
}
编译得到a="在MyView构造函数中 : MeasuredWidth:0;MeasuredHeight:0;Width:0;Height:0".
b="在构造函数attrs中 : width:-1;height:150.0px
结果显示当width为match_parent等数值时,只显示-1等,不能满足我的需求。
然后我试着在相应Activity的onCreate中获取高宽,获得的全部是0.但我在onCreate中的加了个点击控件获取高宽事件,能正确获取高宽。我在网上查了下资料,因为在onCreate中控件还未被度量,所以获取肯定为0.网上有获取三个方法,方法如下:
方法一,在onCreate中添加如下代码:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
myView.measure(w, h);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法一: height:"+height + ",width:" + width+"\n");
方法二可以实现,代码如下:
ViewTreeObserver vto2 = myView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
tvValues.append( "方法二: height:"+myView.getHeight() + ",width:" + myView.getWidth()+"\n");
}
});
但我发现removeGlobalOnLayoutListener在API 级别 16 开始已经废弃,如果去掉,系统会读取多次。
再来看看方法三,代码如下:
ViewTreeObserver vto = myView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法三: height:"+height + ",width:" + width + "..\n");
return true;
}
});
我在网上资料的基础上添加了myView.getViewTreeObserver().removeOnPreDrawListener(this);这一条,这个可以保证系统运行一次。
_____________________________________________________________________________________________________________
出现的问题:(1)用上面的2个回调监听函数,监听函数会一直调用,关闭不了,而且屏幕跳转会出现闪屏的现象。所以放弃了
public void setActionBar(){ ViewTreeObserver observer = mScrollView.getViewTreeObserver(); // observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { // @Override // public boolean onPreDraw() { // int i = 0; // Log.e("HomeFragment:" + (i++)); // //int scrollHeight = mScrollView.getChildAt(0).getHeight(); // int scrollHeight = getScreenHeight() - getActionView().getHeight() - mHomeAd.getHeight() - mMineCare.getHeight() -MainUI.bottomHeight; // int TextHeight = mHomeProgramTxt.getHeight(); // // if(scrollHeight > (bitmapHeight+TextHeight)*2){ // //大屏幕 // int firstBarHeight = mFirstBar.getHeight(); // int blankHeight = scrollHeight - firstBarHeight*2; // // LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mFirstBar.getLayoutParams(); // params.setMargins(0, blankHeight / 3, 0, 0); // mFirstBar.setLayoutParams(params); // // LinearLayout.LayoutParams secondParams = (LinearLayout.LayoutParams) mSecondBar.getLayoutParams(); // secondParams.setMargins(0,blankHeight/3,0,0); // mSecondBar.setLayoutParams(secondParams); // } // mScrollView.getViewTreeObserver().removeOnPreDrawListener(this); // return true; // } // });
(2) 选择使用第一种方法,如果xml里面是用的wrap_content宽高的,可以用getMeasureHeight()方法获取到控件的值,但是动态设置的值只有自己记住这个值大小
public void set(){ int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); getActionView().measure(w, h); mMineCare.measure(w,h); //具体值单独赋值 int homeAdHeight = 520 * getScreenHeight() / 1920; int scrollHeight = getScreenHeight() - getActionView().getMeasuredHeight() - homeAdHeight - mMineCare.getMeasuredHeight() -MainUI.bottomHeight; mHomeProgramTxt.measure(w,h); int TextHeight = mHomeProgramTxt.getMeasuredHeight(); if(scrollHeight > (bitmapHeight+TextHeight)*2.5){ //大屏幕 mFirstBar.measure(w,h); int firstBarHeight = mFirstBar.getMeasuredHeight(); int blankHeight = scrollHeight - firstBarHeight*2; LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mFirstBar.getLayoutParams(); params.setMargins(0, blankHeight / 3, 0, 0); mFirstBar.setLayoutParams(params); mSecondBar.setLayoutParams(params); } }
实现低分辨率适配效果:
高分辨率效果:
相关文章推荐
- 【Android】Item高度固定下动态设置ListView的高度
- Numbers of source Raster bands and source color space components do not match异常的处理
- Android用xml文件画图
- AnDroid SDK Manager 下载超慢的问题
- Android中的动画
- Android 解决ScrollView与父视图滑动冲突问题
- Android Api Demos登顶之路(二十五)Action Bar Mechanics
- android--onLayout源码 流程 思路详解
- Android基于GridView实现的翻牌游戏效果
- Android Format的使用
- 字体在Android View中的输出 drawText
- android studio常见错误
- 关于Android Canvas.drawText方法中的坐标参数的正确解释
- android 如何结束一个线程
- Android文件上传
- android获取webservice接口的数据
- android jni 调用结构体示例
- Android横竖屏切换
- 专访罗升阳:老罗的Android之旅
- Android中下载、安装和卸载(原)