如何在res下命名各种文件夹以适应各种屏幕就不多说了,这位同学(http://blog.csdn.net/z343929897/article/details/27337537)解释得非常清楚,先替受益者谢谢他。
本文的中心思想是“比例为王”,也就说,为新机型定义控件长宽的时候要考虑与原调试真机的比例一致!
下面举个 例子,比如手中有一部真机是10.1英寸的垃圾平板,用下面类获得它的宽高和dpi:
package com.freestyle.utils;
import android.content.Context;
import android.util.DisplayMetrics;
/**
* 计算公式 pixels = dips * (density / 160)
*
* @version 1.0.1 2010-12-11
*
* @author
*/
public class DensityUtil {
private static final String TAG = DensityUtil.class.getSimpleName();
// 当前屏幕的densityDpi
private static float dmDensityDpi = 0.0f;
private static DisplayMetrics dm;
private static float scale = 0.0f;
private static int screenWidth;
private static int screenHeight;
private static float scaledDensity;
/**
*
* 根据构造函数获得当前手机的屏幕系数
*
* */
public DensityUtil(Context context) {
// 获取当前屏幕
// dm = new DisplayMetrics();
dm = context.getResources().getDisplayMetrics();//context.getApplicationContext().getResources().getDisplayMetrics();
// 设置DensityDpi
setDmDensityDpi(dm.densityDpi);
// 密度因子
scale = getDmDensityDpi() / 160;
//Logger.i(TAG, toString());
screenHeight=dm.heightPixels;
screenWidth=dm.widthPixels;
scaledDensity=dm.scaledDensity;
}
/**
* 当前屏幕的density因子
*
* @param DmDensity
* @retrun DmDensity Getter
* */
public static float getDmDensityDpi() {
return dmDensityDpi;
}
/**
* 当前屏幕的density因子
*
* @param DmDensity
* @retrun DmDensity Setter
* */
public static void setDmDensityDpi(float dmDensityDpi) {
DensityUtil.dmDensityDpi = dmDensityDpi;
}
/**
* 密度转换像素
* */
public static int dip2px(float dipValue) {
return (int) (dipValue * scale + 0.5f);
}
/**
* 像素转换密度
* */
public int px2dip(float pxValue) {
return (int) (pxValue / scale + 0.5f);
}
/**
* sp转像素
* @param sp
* @return
*/
public static final int sp2px(float sp)
{
return (int) (sp * scaledDensity+ 0.5f);
}
/**
* 像素转sp
* @param px
* @return
*/
public static final float px2sp(int px)
{
return (px-0.5f)/scaledDensity;
}
@Override
public String toString() {
return " dmDensityDpi:" + dmDensityDpi;
}
/**
* 返回按比例的以像素为单位的宽度
* @param weight 0-1f
* @return
*/
public float widthPixelsFromWeight(float weight){
return screenWidth*weight;
}
/**
* 返回按比例的以像素为单位的宽度
* @param weight 0-1f
* @return
*/
public float widthPixelsFromWeight(float weight,int parentWidth){
return parentWidth*weight;
}
/**
* 返回按比例的以像素为单位的高度
* @param weight 0-1f
* @return
*/
public float heightPixelsFromHeight(float weight){
return screenHeight*weight;
}
/**
* 返回按比例的以像素为单位的高度
* @param weight 0-1f
* @return
*/
public float heightPixelsFromHeight(float weight,int parentHeight){
return parentHeight*weight;
}
public static int getScreenHeight(){
if (dm==null){
new DensityUtil(ContextUtil.getInstance());
}
return screenHeight;
}
public static int getScreenWidth(){
if (dm==null){
new DensityUtil(ContextUtil.getInstance());
}
return screenWidth;
}
}
</pre><pre name="code" class="java">new DensityUtil(this);
int lvWidth=DensityUtil.getScreenWidth();
int lvHeight=DensityUtil.getScreenHeight();
int lvDpi=DensityUtil.getDmDensityDpi();
结果出来了,是160dpi的垃圾屏。先用这个设备将所有的UI做好,不要忘了所有大小、位置相关的属性不要写死,用dimens属性代替,然后将这个dimens.xml放在values-mdpi-976x600文件夹下。
好了,接着做一份excel表,为了再做一份dimens.xml适应拥有480dpi高清屏的华为手机如下图,那么原先50dp的这份dimens.xml里面就要改为30dp:
计算公式不用废话了吧? 假如这个dp为宽相关的话,那么公式为 x * 当前因子/当前宽 = 8.33% , 求x = ??
x = 8.33% * 1080 / 3 =30 dp .
(转换公式已经整好,直接填调试好的dp值就立即显示新机型的dp值了, http://download.csdn.net/detail/rocklee/9533910)