android开发屏幕
‘壹’ 怎样让android开发程序不随着屏幕转动啊
1.在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入 android:screenOrientation=”landscape” 属性。 landscape = 横向 portrait = 纵向 2.android中每次屏幕方向切换时都会重启Activity,所以应该在Activity销毁前保存当前活动的。
禁止屏幕随手机旋转变化 有时候我们希望让一个程序的界面始终保持在一个方向,不随手机方向旋转而变化: 在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入android:screenOrientation=”landscape” 属性。 landscape = 横向 portra。
在manifest文件中加入 screenOrientation=“portrait” 限制屏幕竖屏显示 screenOrientation=“landscape” 限制屏幕横屏显示
使用嵌套布局 相对布局里面嵌套一个线性布局 可以防止出现分辨率混乱 这里我们使用相对布局嵌套一个线性布局可以完成 标题在最上方 最下方是一个ActivityGroup 右边的abcdef。选项条在最右边 这3个都是相对布局里的元素 然后 中间是一个线性布。
LZ可以试试android:screenOrientation="portrait"强制竖屏,然后通过传感器来检测是否旋转了屏幕。LZ可以先尝试一下啊加速度传感器看看,这个应该每个手机都会有
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE););//强制为横屏 或者在AndroidManifest.xml 里面添加android:screenOrientation=”landscape”
Android 平台提供了两类动画,一类是 Tween 动画,即通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果;第二类是 Frame 动画,即顺序播放事先做好的图像,跟电影类似。本文分析 Tween动画的rotate实现旋转效果。
‘贰’ Android开发常用的Util方法(屏幕UI篇)
如果你要封装工具类,注意使用 static关键字
有错误或者需要补充的欢迎及时指正~~
调用: showToast(上下文, 土司内容)
说明: Toast 是可以用 Application的Context 当上下文的,如果你有写Application类,可以直接把它的 单例 弄过来,这样就又少传一个参数了。友情提示Application的单例应该这样写
调用: showSnackBar(当前Activity, 提示文字, 按钮文字, 点击回调, Snackbar回调)
说明: Snackbar 和 Toast 就不一样了,显示环境必须有一个 View ,这里选择把当前Activity的rootView传给它,可避免它与导航栏的不河蟹问题。此封装参数较多(还没涉及颜色呢),建议根据实际应用场景再重载几个。比如你没打算让Snackbar消失时再做什么事,最后那个Callback就可以传null(当然要自己把相关判断做了)
调用: getScreenWidth(上下文)
说明:上下文可以传Application的Context。 getWidth() 和 getHeight() 两个方法已过时,不推荐再用
调用:重写 Activity 的 onKeyDown() 方法
说明:给用户的提示建议用Toast或者Snackbar。
调用:重写 Activity 的 dispatchTouchEvent() 方法
说明:调用时传的是 this ,实际上也可以传Application的Context。另外单就隐藏软键盘而言,方法有很多,这里给出的并非最优解,有兴趣可继续搜索。
没有外传参数,一般不用封装,直接写到你的 Activity 的 onCreate() 或者 Fragment (这时需要先getActivity()再getWindow())的 onCreateView ()方法里面就行,页面较多时建议弄一个base父类。
说明:如果有 ToolBar 或者 ActionBar ,状态栏会和它们一体化,这时你也可以选择把bar隐藏或设成透明。另外如果写成下面这样
结果就是导航栏也跟着变透明了。游戏一类的应用可以这么写,看图的话见仁见智,我本人更喜欢保留导航栏
‘叁’ Android开发中如何固定屏幕显示
在Androidmanifest文件里面设置
android:screenOrientation="landscape"是限制此页面横屏显示,
android:screenOrientation="portrait"是限制此页面数竖屏显示。
‘肆’ Android开发 怎样获取屏幕的宽高是多少厘米
我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸
下面的代码即可获取屏幕的尺寸。
在一个Activity的onCreate方法中,写入如下代码:
[java] view plain print?
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
但是,需要注意的是,在一个低密度的小屏手机上,仅靠上面的代码是不能获取正确的尺寸的。比如说,一部240x320像素的低密度手机,如果运行上述代码,获取到的屏幕尺寸是320x427。因此,研究之后发现,若没有设定多分辨率支持的话,Android系统会将240x320的低密度(120)尺寸转换为中等密度(160)对应的尺寸,这样的话就大大影响了程序的编码。所以,需要在工程的AndroidManifest.xml文件中,加入supports-screens节点,具体的内容如下:
[html] view plain print?
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true" />
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true" /> 这样的话,当前的Android程序就支持了多种分辨率,那么就可以得到正确的物理尺寸了。
[java] view plain print?
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.TextView;
public class TextCanvasActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(new MyView(this));
//定义DisplayMetrics 对象
setContentView(R.layout.main);
DisplayMetrics dm = new DisplayMetrics();
//取得窗口属性
getWindowManager().getDefaultDisplay().getMetrics(dm);
//窗口的宽度
int screenWidth = dm.widthPixels;
//窗口高度
int screenHeight = dm.heightPixels;
TextView textView = (TextView)findViewById(R.id.tv1);
textView.setText("屏幕宽度: " + screenWidth + "\n屏幕高度: " + screenHeight);
}
}
‘伍’ android开发横竖屏问题
Android横屏竖屏设置
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置成全屏模式
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE););//强制为横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
我做的东西里面还用到了去掉标题栏。
我也贴出来
requestWindowFeature(Window.FEATURE_NO_TITLE);
垂直居中:
android:layout_centerVertical="true"
水平居中:
android:layout_centerHorizontal="true"
1.hideStatusbarAndTitlebar()隐藏statusbar和titlebar.
private void hideStatusbarAndTitlebar() {
final Window win = getWindow();
// No Statusbar
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// No Titlebar
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
2.设置屏幕显示模式ScreenOrientation.
在activity里设置android:screenOrientation的值。
android:screenOrientation的属性有以下值:
unspecified(默 认值,由系统判断状态自动切换),The default value. The system chooses the orientation. The policy it uses, and therefore the choices made in specific contexts, may differ from device to device.
landscape,横屏
portrait,竖屏
user(用户当前设置的orientation值),The user's current preferred orientation.
behind(下一个要显示的Activity的orientation值),The same orientation as the activity that's immediately beneath it in the activity stack.
sensor(传 感器的方向),The orientation determined by a physical orientation sensor. The orientation of the display depends on how the user is holding the device; it changes when the user rotates the device.
nosensor(不 使用传感器,这个效果差不多等于unspecified).An orientation determined without reference to a physical orientation sensor. The sensor is ignored, so the display will not rotate based on how the user moves the device. Except for this distinction, the system chooses the orientation using the same policy as for the "unspecified" setting.
3.水平/垂直居中的方法.
设置parent的android:gravity为"center"。
4.获得当前屏幕宽高的方法.
Display display = getWindowManager().getDefaultDisplay();
Config.screenWidth = display.getWidth();
Config.screenHeight = display.getHeight();
‘陆’ android屏幕适配
android设备碎片化严重,因此在实际开发的时候需要做屏幕适配
适配主要是在以下几个方面:
常见的布局适配主要是以下几点:
a.避免写死布局尺寸,使用wrap_content或者martch_parent
b.使用权重,比如linearlayout中的weight;
c.使用relative的相对位置摆放,比如layout_centerInParent="true"
d.ConstraintLayout 原理类似于relatvie,相对摆放,但是性能相对于relatvie会好一点
e.android官方的库Percent-support-lib,该库主要是用的是百分比适配
a. .9图适配,这个是使用了.9图可以在特别区域拉伸不失真的特性来适配
b. 使用多套位图,匹配不同的分辨率,比如在mipmap,mipmap-xhdpi,mipmap-xxhdpi,等文件夹下面放多套分辨率不同的内容相同的图片
是指同一个业务逻辑,在不同的设备上执行不同的跳转方式,比如在手机上打开一个新的activity,但是在平板上,可以在横屏状态下,右侧增加一个fragment,展示打开的页面。
a.分辨率限定符,使用drawable-dpi,drawable-hdpi等
b.尺寸限定符
c.最小宽度限定符
d.屏幕方向限定符
a.android9.0开始 有官方的api进行适配
b.华为,小米,魅族,vivo,oppo各大room厂商有对应的api进行适配
除了以上这些,还有dimens适配,但是都各有缺点,有的需要多套图,有的需要多套资源文件,dimens适配的dimens文件过多,需要针对不同的屏幕分辨率来生成对应的文件,比较繁琐
以上,实际开发中,做的最多的适配为布局适配
开发中屏幕适配的核心是在于屏幕缩放,不论是哪种屏幕适配,都是以这个缩放为基础
已知:设计图手机像素(W,H),设计图上控件的像素值(ViewW,ViewH),目标设备分辨率(TargetW,TargetH)
求:目标设备上view的宽高(TargetViewW,TargetViewH)
公式:宽:ViewW / W * TargetW=TargetViewW
高:ViewH / H * TargetH =TargetViewH
原理:根据当前设备的分辨率,计算出设计图上的控件在该设备上的缩放比,然后根据缩放比,来动态的设置view, 最终换算出来的单位为px
该适配方式是通过自定义外部的ViewGroup,比如LinearLayout,RelativeLayout,在onMeasure方法中,遍历子view,设置宽高以及padding,margin
以下是封装了一个工具类,用来获取屏幕宽高以及计算缩放比:
未完待续
‘柒’ 进行Android开发的时候没有测试机适配怎么办,如何进行屏幕适配
Android项目的res目录下一般加上我们自己创建的,会有6个目录,分别是:drawble drawble-ldpi drawble-mdpi drawble-hdpi drawble-xhdpi drawble-xxhdpi, 这里就不包括更为特殊的drawble目录了,(比如drawlbe-land-hdpi, 表示水平方向的高分辨率的图片,这些都目录不管多么长,它们都是按一丁点规律匹配的, 我们的目的是, 从个别中发现规律,从而应用到整体)。
当一个apk运行起来时,Android系统会根据其所运行的手机的屏幕密度去相对应的图片文件夹里找指定名称的图片。 注意, 先去哪个目录里找,完全是根据这个手机的屏幕密度决定的。
其中注意两点:
1, 中等分辨率,即mdpi的屏幕密度是160,他是标准的参考密度。所以计算比例的时候它的比例值是1. 其他屏幕密度的参考比例都是以这个为依据。
2, 默认的drawble目录(一般是自己建的),和mdpi是一样的。将图片放到这个目录和放到drawble-mdpi目录是一样的效果。不过一般习惯性的放一些自定义selector或者点9的图片在这里。
现在我们来看, HTC one V手机的屏幕密度是252ppi, 那距离哪一个最靠近呢, 就是hdpi了。 所以当apk运行在这个手机上时,首先会去这个目录找图片。
下面是用常见的一些类型的手机总结的一个表格:
注意一点: 上面说的对应关系,都是首选目录, 那如果首选目录里面找不到图片呢?
Android图片选择策略
上面说到, 如果屏幕所对应的文件夹没有要找的图片,怎么办。这是很常见的,我们开发项目时一般不会去为每一个级别的屏幕去切一套图片。那样做只会让apk很大。所以一般性的图片我们只切一两个典型密度屏幕的图片。但是apk是有可能会运行在从ldpi到xxhdpi的各种级别的手机上。这个时候就需要根据一定的策略去寻找图片了。
Android系统寻找图片的步骤是这样的:
1, 去屏幕密度对应的目录去找。如果找到就拿来用。
2, 如果没找到,就去比这个密度高一级的目录里面去找,如果找到就拿来用。
3, 如果没找到就继续往上找。以此类推。
4, 如果到了xxhdpi目录还没有找到的话,就会去比自身屏幕密度低一级的目录去找,如果低一级的目录>=hdpi,找到了就拿来用。
5, 如果没找到, 就去mdpi目录去找, 如果找到了,就拿来用。
6, 如果没找到,就去默认的drawble目录里去找, 如果找到了就拿来用。
7 ,如果没找到,再去最低的ldpi目录里去找。如果找到了,就拿来用。
8, 如果没找到, 那就是没找到了, 图片无法显示。(不过一般不会出现这种现象,因为如果每个目录都没有这个图片的话,你是编译不过的)
这里有两点需要注意:
① 首先会去比自己密度高的目录里去找,这是因为因为系统相信,你在密度更高的目录里会放置分辨率更大的图片,这样的话这个图片会被缩小,但同时显示效果不会有损失,但是如果优先去低一级别的目录去找的话, 找到的图片就会被放大,这样的话这个图片就会被拉扯模糊了。
e.g. 同一张图片,你在mdpi和xxhdpi目录各放了一份, 这个应用你现在运行在hdpi的手机上, 那应用会选择哪张图片呢。答案是xxhdpi目录里的。即便hdpi离mdpi更近一点!
②,如果在mdpi里找不到是不会直接去ldpi里找的, 而是先去默认的drawble目录里找,这是drawble目录和drawble-mdpi是一个级别的。
下面用一张流程图来总结:
(注: 以上流程图是我通过做实验总结出来的,如有谬误还望指出。)
Android系统对图片的缩放规则
上文中提到如果在手机对应的目录没有找到图片,就会按照一定的策略去其他目录找,那找到了以后就原图显示么? 非也。
对于放在不同目录下的图片, 系统会按照一定比例对原始的图片进行放大或者缩小, 具体的放大缩小比例可参考下表, 图片所在目录和对应的屏幕密度是相同时图片缩放比例为1,也就是原图显示,而横向的比例表示分别放在该密度手机上运行时图片被缩放的比例。
对原始图片的缩放倍数。
上表几点值得注意的地方:
①, drawable目录和drawable-mdpi目录和dp到px的转换关系是一样的。
②,当你放一个120px*180px的图片到drawable-hdpi目录,如果此应用运行在一个xhdpi的手机上,则这个图片会被拉扯到160px*240px。
③, 最后一行dp->px, 说明了在代码或者布局文件中声明一个dp值, 这个值在不同屏幕密度的手机中会被乘以不同的倍数。 比如你在布局文件中写了一个宽和高分别为120dp和180dp的LinearLayout, 那么当这个应用运行在xhdpi的手机上时(比如上面那个常见手机表中的中兴U985手机),它的实际像素就会被转换为240px*360px。 如果运行在ldpi的手机上,就变成了90px*135px。 但是在这两个手机中显示的区域大小从肉眼看,是一模一样大的。(这点作为后面内容的一个引子,“看起来”一样大,这就是Android的一个神奇的地方)
我们来做个试验
试验材料:
① 一张120px*180px的图片
② 四部手机, 具体参数参考上面的一张表格。三星 Galaxy win pro 3218 (hdpi)、 HTC one V (hdpi)、 中兴U985 (xhdpi)、Google Nexus 7 (xhdpi)。
③ 我在布局文件里声明了3个View, 第一个位于左上角,是一个线性布局,宽和高指定为120dp*180dp(注意是dp哦), 第二个位于右上角,是一个ImageView,内容就是上面这张120px*180px的图片, 第三个位于左下角也是一个线性布局,固定宽高,是120px*180px。
我将这个图片放到一个Android工程里的drawable-hdpi目录
从上面的那种缩放关系表中我们可以知道,图片从hdpi目录中取, 运行在hdpi手机上宽高保持原始值,,运行在xhdpi手机上,宽高会乘以4/3, 也就是说图片会被拉扯变大, 但是图片的实际显示效果,即“视觉大小”怎么样呢。
下面是运行后的效果:
如图: 黑色区域是120dp*180dp的View, 蓝色区域是120px*180px的图片, 灰色区域是120px*120px的View。
1, 可以看到使用dp的View(黑色区域)在不同分辨率,不同屏幕尺寸,不同屏幕密度的手机下,视觉大小看起来是一模一样的。
但是他们的实际像素值是不一样的: 120dp*180dp -> (hdpi) -> 180px*270px, 而120dp*180dp ->(xhdpi)-> 240px*360px。 由于屏幕密度的不同,缩放以后的像素可以显示出一样的视觉大小。
2, 蓝色图片的视觉大小也是一样的, 由于图片放到了hdpi目录下, 所以前两个手使用的是图片的原始像素120px*180px, 而后两个手机对图片进行了放大, 参考上面的屏幕密度缩放关系表, 放大了4/3倍。 我通过对屏幕的截图,测量下来的结果的确是放大了这么多, 分别为160px*240px。 由于屏幕密度的不同,它们显示出来的视觉大小是相同的。
3, 但是使用固定像素值的View就没那么幸运了, 它在hdpi的手机上看起来要比在xhdpi的手机上大一些。 要是在屏幕密度相差更大的手机上看的话, 这个区域的大小会相差很大。 这就是为什么Android推荐使用dp作为View的尺寸,而不是真实像素的原因了。
4, 经过反复试验,(实验结果就不贴图了,很多),得出一个结论,使用哪个目录下的图片(前提是图片只放在某一个目录中),在所有,不管是分辨率还是屏幕尺寸还是屏幕密度,3个参数都在改变的情况下,图片显示的视觉大小都和运行在这个目录对应屏幕密度手机上时的大小是一样的。
UI给工程师切多大图是合适的。
说说我之前走的冤枉路吧。
在之前, 设计师的交互和视觉设计都是基于480*800的界面, 切图的时候会以480*800为基础切一版, 然后在给所切图片的宽和高乘上个4/3,然后在出一版。
比如同一个120*180的图片, 就会出两个版本, 一个是120*180的一个是160*240的。分别放到hdpi目录和xhdpi目录。
吃到的苦头是,UI很累, apk很大。T^T
这番探究下来, 发现直接基于720*1280的视觉稿切一版图片就可以了。 将图片只放到xhdpi目录中,这样系统会在不同密度屏幕的手机中对图片进行合理的缩放, 而之前这个缩放工作竟然是人工完成的!
另: 如果想在xxhdpi的手机上显示的很好, 也可以基于1080P的屏幕设计, 这样的话就兼容所有低密度屏幕的手机, 而且也不会出现图片被拉扯的现象。
‘捌’ Android一般开发的时候的屏幕适配是怎么做的
Android中一个layout想适配各种屏幕尺寸那么需要按以下规则去写layout:
1. 尽量使用wrap_content、match_parent、weight 来规定layout的大小。
2. 要确保布局的灵活性并适应各种尺寸的屏幕,应使用 “wrap_content” 和 “match_parent” 控制某些视图组件的宽度和高度。
3. 使用 “wrap_content”,系统就会将视图的宽度或高度设置成所需的最小尺寸以适应视图中的内容,而 “match_parent”(在低于 API 级别 8 的级别中称为“fill_parent”)则会展开组件以匹配其父视图的尺寸。
4. 如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以填满可用空间。此方法可让布局正确适应各种屏幕尺寸和屏幕方向。
5. 如果某些地方必须要规定控件的大小,那么要使用dp 或者 dip单位。
6. 字段必须使用 sp单位。
7. 将不同的图片放到不同的drawable目录下,分辨率的匹配规则如下:
drawable-mdpi 320 * 480
drawable-hdpi 480*800
drawable-xhdpi 720 * 1280
drawable-xxhdpi 1080 * 1920
drawable-xxxhdpi 1080+
‘玖’ android开发 使用夜神模拟器 屏幕旋转问题
没想到在中演示时候遇到了崩溃,检查发现是Asdk关闭之后在Bsdk的onActivityResult 方法,B页面成员变量丢失。
最终发现有夜神模拟器有横竖屏切换,加上没有保存现场,由于页面都是竖屏,于是选择了最简单的在AndroidManifest 配置了
强制竖屏,但是还是在返回过程中 模拟器切换横屏页面一闪而过,debug验证确认。这种情况再正常情况下不会出现,考虑是不是夜神模拟器做了横屏的修改。
解决办法
1.页面做了保存现场,和现场恢复
2.夜神模拟器在后台直接配置成手机竖屏模式
如果还有其他解决方法,可以讨论一下
‘拾’ 如何在Android开发中实现屏幕切换
屏幕切换指的是在同一个Activity内屏幕间的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面;一个个性化设置页面。android.widget.ViewAnimator类继承至FrameLayout,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。
该类有如下几个和动画相关的函数:
setInAnimation:设置View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为 android.view.animation.Animation,一个接受两个参数,类型为Context和int,分别为Context对象和定义 Animation的resourceID。
setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。
showNext: 调用该函数来显示FrameLayout里面的下一个View。
多数情况下是使用ViewFlipper 是继承至FrameLayout的,所以它是一个Layout里面可以放置多个View。ViewFlipper可以用来指定FrameLayout内多 个View之间的切换效果,可以一次指定也可以每次切换的时候都指定单独的效果。
isFlipping:用来判断View切换是否正在进行
setFilpInterval:设置View之间切换的时间间隔
startFlipping:使用上面设置的时间间隔来开始切换所有的View,切换会循环进行
stopFlipping: 停止View切换