我们建好一个android 的项目后,默认的res下面 有drawable、layout、values等目录
启开一个新的Android专案后在res资料夹内会有
drawable-hdpidrawable-mdpi
drawable-ldpi
drawable-xhdpi
drawable-xxhdpi
三个目录,所定义的dpi皆不同
xhdpi是Android 2.2才开始增加的分类;xlarge是Android 2.3才开始增加的分类; tvdip 则是最近的事。
此外
drawable-hdpi 对应的解析度为 WVGA (480x800),FWVGA (480x854),是放高解析度的图片
drawable-mdpi 对应的解析度为 HVGA (320x480),是放中等解析度的图片
drawable-ldpi 对应的解析度为 QVGA (240x320),是放低解析度的图片
Android系统会根据机器的解析度来分辨鉴定对应到相关的资料夹找出对应的图片,什么分辨率就使用对应的drawable下的目录;
在android中要让手机自适应不同分辨率的手机,总的来说有三种方法:
1.一种是代码实现布局
2.一种是多个layout来实现。
3.最后是使用属性layout_weight来实现自适应多个分辨率,但是确定是如果布局较复杂,实现起来比较难控制,复杂。
---------1.普通情况
这里是说res目录当然是说的使用多个layout来自适应分辨率:
其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。
屏幕方向:
横屏竖屏自动切换:
可以在res目录下建立layout-port-800x600和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,这样在手机屏幕方向变化的时候系统会自动调用相应的布局文件,避免一种布局文件无法满足两种屏幕显示的问题。
不同分辨率横屏竖屏自动切换:
以800x600为例
可以在res目录下建立layout-port-800x600和layout-land-800x600两个目录
不切换:
以下步骤是网上流传的,不过我自己之前是通过图形化界面实现这个配置,算是殊途同归,有空我会把图片贴上来。
还要说明一点:每个activity都有这个属性screenOrientation,每个activity都需要设置,可以设置为竖屏(portrait),也可以设置为无重力感应(nosensor)。
要让程序界面保持一个方向,不随手机方向转动而变化的处理办法:
在AndroidManifest.xml里面配置一下就可以了。加入这一行android:screenOrientation="landscape"。
例如(landscape是横向,portrait是纵向):
Java代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ray.linkit"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".GamePlay"
android:screenOrientation="portrait"></activity>
<activity android:name=".OptionView"
android:screenOrientation="portrait"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
另外,android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!
有的程序适合从竖屏切换到横屏,或者反过来,这个时候怎么办呢?可以在配置Activity的地方进行如下的配置android:screenOrientation="portrait"。这样就可以保证是竖屏总是竖屏了,或者landscape横向。
而有的程序是适合横竖屏切换的。如何处理呢?首先要在配置Activity的时候进行如下的配置:android:configChanges="keyboardHidden|orientation",另外需要重写Activity的
onConfigurationChanged方法。实现方式如下,不需要做太多的内容:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// land do nothing is ok
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// port do nothing is ok
}
}
写一个支持多分辨的程序,基于1.6开发的,建立了三个资源文件夹drawable-hdpi
drawable-mdpi drawable-ldpi,里面分别存放72*72 48*48 36*36的icon图标文件。当我在G1(1.5的系统)上测试时,图标应该自适应为48*48才对啊,但实际显示的是36*36。怎么才能让其自适应
48*48的icon图标呢
解决办法 drawable-hdpi drawable-mdpi drawable-ldpi改成drawable-480X320 drawable-800X480的多分辨支持的文件夹
values目录是程序默认的资源文件目录,如果要实现多语言版本的话,我们就要添加要实现语言的对应的资源文件。
首先我们点击添加Android Xml File按钮,会出现下面的界面:
输入文件名:string.xml,选中Values单选框,并把下面左列表中的Region添加到左边的列表里面,并在Region输入框里输入cn,如下图
这时,上面的消息提示:如果用Region的话,需要使用语言项,和Region一样,我们把Language也添加到右面的列表里面,填入zh,如下图
4.0的是选择Android xml values file,输入名字后,点击next 进行操作,和上面的操作差不多。
点击Finish按钮,资源文件就会建好了,目录:res\values-zh-rCN(其实上面一大堆操作,就是为生成这个目录)
默认生成的string.xml的代码:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, Test!</string> <string name="app_name">Test-Multilingual</string> </resources>
修改刚刚生成的res\values-zh-rCN目录下的string.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">测试多语言</string> <string name="hello">你好 多语言测试</string> </resources>
Values文件汇总如下:
中文(中国):values-zh-rCN
中文(台湾):values-zh-rTW
中文(香港):values-zh-rHK
英语(美国):values-en-rUS
英语(英国):values-en-rGB
英文(澳大利亚):values-en-rAU
英文(加拿大):values-en-rCA
英文(爱尔兰):values-en-rIE
英文(印度):values-en-rIN
英文(新西兰):values-en-rNZ
英文(新加坡):values-en-rSG
英文(南非):values-en-rZA
阿拉伯文(埃及):values-ar-rEG
阿拉伯文(以色列):values-ar-rIL
保加利亚文: values-bg-rBG
加泰罗尼亚文:values-ca-rES
捷克文:values-cs-rCZ
丹麦文:values-da-rDK
德文(奥地利):values-de-rAT
德文(瑞士):values-de-rCH
德文(德国):values-de-rDE
德文(列支敦士登):values-de-rLI
希腊文:values-el-rGR
西班牙文(西班牙):values-es-rES
西班牙文(美国):values-es-rUS
芬兰文(芬兰):values-fi-rFI
法文(比利时):values-fr-rBE
法文(加拿大):values-fr-rCA
法文(瑞士):values-fr-rCH
法文(法国):values-fr-rFR
希伯来文:values-iw-rIL
印地文:values-hi-rIN
克罗里亚文:values-hr-rHR
匈牙利文:values-hu-rHU
印度尼西亚文:values-in-rID
意大利文(瑞士):values-it-rCH
意大利文(意大利):values-it-rIT
日文:values-ja-rJP
韩文:values-ko-rKR
立陶宛文:valueslt-rLT
拉脱维亚文:values-lv-rLV
挪威博克马尔文:values-nb-rNO
荷兰文(比利时):values-nl-BE
荷兰文(荷兰):values-nl-rNL
波兰文:values-pl-rPL
葡萄牙文(巴西):values-pt-rBR
葡萄牙文(葡萄牙):values-pt-rPT
罗马尼亚文:values-ro-rRO
俄文:values-ru-rRU
斯洛伐克文:values-sk-rSK
斯洛文尼亚文:values-sl-rSI
塞尔维亚文:values-sr-rRS
瑞典文:values-sv-rSE
泰文:values-th-rTH
塔加洛语:values-tl-rPH
土耳其文:values--r-rTR
乌克兰文:values-uk-rUA
越南文:values-vi-rVN
假设需要适应320x240,480x320分辨率。在res目录下新建文件夹values-320x240, values-480x320。然后在文件夹 values ,values-320x240 和 values-480x320 下新建xml文件dimens.xml,该xml文件内容如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="btnTextSize">14dip</dimen> </resources>
针对不同的分辨率,btnTextSize的值不同。在布局文件中,用下面的方式引用该值:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/lblSet" android:textSize="@dimen/btnTextSize"> </TextView>
通过这种方法,可以方便设置在不同分辨率下,字体的大小了。当然,不仅仅字体大小,宽和高等其他的一些属性,也可以通过类似的方式来设置
layout中设置图片自适应大小,并且设置最大宽高,当图片的宽高大于设置的最大值时,宽高值为设置的最大值。
<ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" android:maxWidth="42dp" android:maxHeight="42dp" android:scaleType="fitCenter" android:layout_marginLeft="3dp" android:src="/blog_article/@drawable/icon/index.html" />
关键代码:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxWidth="42dp"
android:maxHeight="42dp"
values-v11代表在API 11+的设备上,用该目录下的styles.xml代替res/values/styles.xml
values-v14代表在API 14+的设备上,用该目录下的styles.xml代替res/values/styles.xml
其中API 11+代表android 3.0 +
其中API 14+代表android 4.0 +
比较新的Android版本中附带了一些应用程序可以利用的主题,并在这些平台上运行时,可能要使用这些主题,同时依然要兼容旧的版本。基于不同的平台版本,通过选择定制主题所使用的资源在不同的父主题之间的切换来达到兼容的目的。
例如,以下是用标准的平台默认的亮度主题声明的一个简化的定制主题,它被放在res/values文件夹下的一个XML文件中(通常是res/values/styles.xml):
<stylename="LightThemeSelector"parent="android:Theme.Light">
...
</style>
当应用程序运行在Android3.0(API级别11)或更高的版本上时,针对这个主题要使用比较新的holographic主题,所以,要在res/values-v11的文件夹下的一个XML文件中放入一个可选的主题声明,把它的父主题设置为holographic主题:
<stylename="LightThemeSelector"parent="android:Theme.Holo.Light">
...
</style>
现在就可以像平常一样使用这个LightThemSelector主题了,如果应用程序运行在Android3.0或更高的版本,就会自动的切换到holographic主题。
在R.styleable.Theme类中可以找到用于主题的标准属性列表。
有关提供可选资源的更多信息,如基于平台版本或其他设备配置的主题和布局,可以查看“Providing Resources”文档。
http://developer.android.com/guide/topics/resources/providing-resources.html
使用平台样式和主题
Android平台提供了一个大的用于应用程序的样式和主题集合。可以在R.style类中找到所有可用的样式。要使用其中列出的样式,就要用一个前缀来替换在样式名中的所有下划线。如,可以用”@android:style/Theme.NoTitleBar”来替代Theme_NoTitleBar。
但是,R.style类文档没有完整的描述样式,因此查看实际的使用这些样式和主题的源代码会更好的帮助理解提供的每种样式属性。为了更好的引用Android的样式和主题,请看下列源代码:
1. Android样式(styles.xml)
2. Android主题(themes.xml)
这两个文件会通过例子帮助你设计,例如,在Android主题的源代码中,能够找到<style name=”Theme.Dialog”>声明。在这个定义中,可以看到所有的Android框架使用的对话框样式属性。
以上资源都来自于互联网
(本文是我综合网上的资料合成的,所以比较全面)。
另外请参照我的另一篇文章综合学习:http://blog.csdn.net/fth826595345/article/details/8754805
核心竞争力,说白了就是一种掌握稀缺资源的能力。你拥有的资源,别人不能很轻易的获得。对于IT技术人而言,我们需要对自己所希望获取的稀缺资源有很清楚的认识,在你作一次次职业选择的时候,不妨问问自己:“这个选择有助于我积累这种资源么?”
在我主持一次讨论中场休息时,一位听众和我攀谈起来。他目前已经从事Linux架构多年,问我如何获得VMware的高级认证。我问他为什么对VMware认证感兴趣,他觉得这对他的职业发展有帮助。
他的情况不禁让我想起了自己的IT职业经历。Linux系统管理员也是我技术积累中非常重要的一个阶段。我至今认为在2000年网络大潮中快速积累的Linux能力,为我奠定了一个相对较好的技术素养。很怀念那段求知若渴的时光,因为年轻的原因,吸收东西特别快。晚上在机房一整夜作服务器移植或者升级,第二天稍事休息后还能神采奕奕。在网站作Linux管理员两年之后,我对网络有了兴趣。跳到一家小ISP作网管,积累了一些实际的网络经验。两年之后又希望编程,跳到一家外企作程序员。回头看来,我在国内7年的工作中经历4家工司,从事完全不同的技术工作。之后就是出国后从事Linux系统管理工作,最近五年专注于VMware的运维,项目实施和设计。
在国内7年的工作中,我并没有想过职业发展。基本是以技术为主导来决定自己的下一步。其后果可想而知。我对Linux,网络和编程都有涉猎,可始终没能登堂入室,能力泛泛。这是一件很可惜的事。同时对自己的信心也不是很足。
出国后我幸运的在第一个月时就找到了别人艳羡的工作,Linux管理员的工作也还混得过去。几年日子就这么一天天的过去了。直到2008年我开始接触VMware,也并不是自己多么有预见性,只是一位同事离职空出一个VMware培训机会,才开始了5年来对VMware技术的痴迷。由于我有网络和系统的基础,当时的ESX对我是较容易的。我曾一度对非命令行的管理界面嗤之以鼻,现在想想幼稚的可爱。
和大多数人一样,我是一个再普通不过的IT人。稍微有点轴,认准的事想把他做好。这就有了后来的VCDX之路。现在回头想,如果没有我五年来的专注,我可能就是一个二流的Linux管理员,在大公司里混混日子了。当然曾经的杂乱IT经历多少帮了我点忙,有点歪打正着的意思。
如果问我问题的那位朋友看到我这篇文章,我想他明白我想说的意思。与其被某种技术牵着鼻子走,不妨先想想自己的优势在哪里,自己想获取的稀缺资源是什么?
对于目前的我而言,VCDX仅仅是一个起点。在这段宝贵的经历中,我学习了,我坚持了,我有意识的积累了成为架构师的经验和思维方式。也收获了我认为最宝贵的一项财富:自信。敢于去挑战别人的想法,也敢于坚持自己的观点,这些都是建立在自信的基础之上的。
在近年咨询公司的经历中,我受益于技术背景的优势,也认识到多年技术思维带来的局限性。我也在项目管理,技术管理以及架构设计的众多选择中挣扎着,至今也仍在努力找到一个平衡点。坦白说,这并不容易。过去的经验教训告诉我,认清自己的核心竞争力是多么的重要。如果我拼了全力,可以在英语国家作一个二流的项目经理,很难做到一流。可我有足够的信心去作一个一流的架构师。我目前所追求的稀缺资源,就是能在项目需求和技术方案之间搭一座桥梁,我的稀缺性和竞争力也在此体现。除了保证技术不断更新作为硬能力之外,我格外需要加强的是软能力。那就是对客户需求的洞察力,在客户和项目组之间的协调能力和谈判能力,以及对技术发展趋势的预测能力。
人的能力精力有限,尽早明确你的核心竞争力,也许会让你事半功倍。找寻核心竞争力很简单的一个根本问题是:“你对什么有热情,是什么事不给工钱你也愿意干?是什么让你在寒冷的冬天早晨起床?”
知道了什么是自己追寻的核心竞争力,并敢于坚持付诸行动,你离成功还会远么?
这句话在IT界是再贴切不过了。有网友在什么是你的核心竞争力一文后留言说:“技术更新换代如此频繁的年代,没有一劳永逸,选择了IT就选择了逐日,无尽的黑洞。” 作为一个多年来摸爬滚打的IT老兵,我也深深理解个中滋味。不过我认为与其学盲目逐日的夸父,不如暂时停下你忙碌的脚步,好好规划一下自己的方向。只要你能认清自己、辨别大势并且付诸行动,相信你会在纷繁变化的业界里占据一个有利的位置。
本来什么是你的核心竞争力一文是我的自言自语,不曾想得到很多朋友回复。其中不乏有朋友询问职业发展方向的问题。我无法一一作答,只能尝试在这篇文章中聊聊个人浅见。比起刚入职场的新人而言,我不过多吃十几年IT饭而已,哪有资格评论职业发展。此文系抛砖引砖,尽管砸来。
认清自己
这恐怕是最难的一件事了。我成长在一个榜样的年代,也是一个磨灭个性的时代。从小的教育让我们习惯于崇尚权威,服从师长,可极大地压抑了创造性和对自我的认知。我们小时候的偶像突然在一夜之间就失去了光芒。而新的观念和潮流又让我们觉得无所适从。坦白说认清自己并不容易,这需要勇气,更需要一点点执着。认清自己不仅仅是对自己学历、经验、优缺点和目前人生阶段的评估,而且要知道自己内心深处真正追求的什么。
我也曾经抱着随大流的想法,谁谁谁怎么着了,我是不是也该那么做啊。大家都觉得这才是王道啊。我曾经的一位同事对我的职业发展有很大的帮助,他本人并不知道我是一直以他的经历激励自己的。有一次我谈到了自己对销售、管理和技术等众多选择中的困惑,很羡慕他的华丽转身。他很直接的问我:“你对什么有热情?别人的选择是不是你内心真的想要的?”我记住了这句话。
辨别大势
2013 VMware合作伙伴大会的主题是“掌云势,蕴未来”。 在你低头工作时,不妨抬头看看什么是势,自己目前的位置是顺势而动,还是逆势而行。想套用多年前的一句广告语“网络就是计算机”,我想说“云计算就是IT”。 我相信有很多人对此不以为然,首先云计算的概念有很多时候被滥用造成人们对这三个字的混淆和疲劳,其次很容易列举出一大堆云计算不适用的理由,再次中国市场的特殊性也让人对云何时落地产生疑惑。 作为咨询顾问,我深知没有一个是适用于所有情况,当然云计算也不例外。 但是云计算是大势所趋,这一点我深信不疑。云计算所带来IT业的变革是革命性的,当然也影响到一个个普通你我的职业去向。
下图摘自著名国际独立评估机构Gartner的一份分析报告。
三个轴分别代表技术能力、商业分析能力以及前瞻性和创造性。 三角形很形象的勾勒出你在三个方面的能力对比。拿中间蓝色三角形来说,体现了很多IT技术人的能力比重。技术能力强,商业能力和前瞻性/创造力相比较弱。一些在三色区域的职位在云计算时代面临的挑战是空前的。比如操作系统管理员和数据库管理员。我非常尊敬这两个角色,因为我也曾是全职的Linux管理员和DBA。但我不得不说,初中级的职位在云时代会慢慢减少, 原因如下:一某些初级的安装调试和排错工作不再有必要。 预先定制好的虚拟机的Template会很快速方便的新建操作系统,甚至新建包括应用和操作系统在内的全套服务。当年我们在2000年时候搭Linux服务器的时候还得一步步配置,现在一套LAMP的服务在公有云上从申请到上线也许5分钟就够了 二 自动化代替了人工操作。 人工操作的问题有:不一致性,人为差错和由于人工干预造成的拖延。 很多重复性的系统管理工作是可以用脚本或者工具来实现的(比如Puppet或者Orchestrator) 三 软件定义的数据中心,软件定义存储,软件定义网络。软件定义把控制层从硬件剥离出来,更灵活高效的适应多变的IT环境。这也意味着某些系统管理工作会大大简化,甚至不必要了。
绿色三角形代表的人群商业分析能力强,技术能力和前瞻/创造能力相对较弱。 我认为Business Analyst的缺口很大。如果上SaaS项目,技术方面主要靠SaaS服务商,成功的关键是对企业内部商业流程的透彻了解,以及和已有系统的集成。Business Analyst需要和企业各部门收集并验证需求,然后参与到项目的论证、设计等各个阶段中来。
紫色三角形代表的人群三种能力都比较均衡,比如CTO,高级架构师和项目联络人等等。这个领域对人才的需求是很强劲的,当然对能力的要求也较高。
红色三角形代表的人群多从事于云计算的提供商或者咨询行业。比如策略分析师、愿景设计师和商业/社交网络专家等等。要求三种能力都要强。我个人并不完全认同上图对技术能力的要求,该人群技术能力应该多注重“博”,而不是“专”。人的精力能力有限,要求三方面都一样出色有点不太实际。
Garner的报告指出,如果你在蓝色三角形内,那么就该有点危机意识了。绿色三角形和紫色三角形人群在企业内部还是相对安全的。而红色三角形的技能是云计算运营商所迫切需要的,该人群在云时代也占据一个有利的制高点。
虽然该报告有点绝对化,我还是觉得这种技能需求的评估方式很说明一个大趋势。
在认清自己和辨别大势之后,关键就是付诸行动了。该怎么做?咱们下回分解吧。
服务端:
import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server { public static final int PORT = 8000;//监听的端口号 public static void main(String[] args) { Server server = new Server(); server.init(); } public void init() { try { ServerSocket serverSocket = new ServerSocket(PORT); while (true) { Socket client = serverSocket.accept(); //一个客户端连接就开户一个线程处理 new Thread(new HandlerThread(client)).start(); } } catch (Exception e) { System.out.println("服务器异常: " + e.getMessage()); } } private class HandlerThread implements Runnable { private Socket client; public HandlerThread(Socket client) { this.client = client; } public void run() { try { //读取客户端数据 DataInputStream dis = new DataInputStream(client.getInputStream()); String reciver = dis.readUTF(); //处理客户端数据 System.out.println("客户端发过来的内容:" + reciver); //向客户端回复信息 DataOutputStream dos = new DataOutputStream(client.getOutputStream()); System.out.print("请输入:\t"); // 发送键盘输入的一行 String send = new BufferedReader(new InputStreamReader(System.in)).readLine(); dos.writeUTF(send); dos.close(); dis.close(); } catch (Exception e) { System.out.println("服务器异常: " + e.getMessage()); } finally { if (client != null) { try { client.close(); } catch (Exception e) { client = null; System.out.println("服务端异常:" + e.getMessage()); } } } } } }
客户端:
import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; public class Client { public static final String IP = "localhost";//服务器地址 public static final int PORT = 8000;//服务器端口号 public static void main(String[] args) { while (true) { Socket client = null; try { //创建一个流套接字,连接到指定主机上的指定端口号 client = new Socket(IP, PORT); //读取服务器端数据 DataInputStream dis = new DataInputStream(client.getInputStream()); //向服务器端发送数据 DataOutputStream dos = new DataOutputStream(client.getOutputStream()); System.out.print("请输入: \t"); String send = new BufferedReader(new InputStreamReader(System.in)).readLine(); dos.writeUTF(send); String reciver = dis.readUTF(); System.out.println("服务器端返回过来的是: " + reciver); dos.close(); dis.close(); } catch (Exception e) { System.out.println("客户端异常:" + e.getMessage()); } finally { if (client != null) { try { client.close(); } catch (IOException e) { client = null; System.out.println("客户端异常:" + e.getMessage()); } } } } } }