Android根据分辨率进行单位转换-(dp,sp转像素px) - topMan'blog - ITeye技术网站

Android系统中,默认的单位是像素(px)。也就是说,在没有明确说明的情况下,所有的大小设置都是以像素为单位。

如果以像素设置大小,会导致不同分辨率下出现不同的效果。那么,如何将应用中所有大小的单位都设置为’dp’呢?
实际上TextView.setTextSize()重载了根据单位设置大小的方法。

笔者在此基础上实现了以下方法:

Java代码  收藏代码
  1. /** 
  2.  * 获取当前分辨率下指定单位对应的像素大小(根据设备信息) 
  3.  * px,dip,sp -> px 
  4.  *  
  5.  * Paint.setTextSize()单位为px 
  6.  *  
  7.  * 代码摘自:TextView.setTextSize() 
  8.  *  
  9.  * @param unit  TypedValue.COMPLEX_UNIT_* 
  10.  * @param size 
  11.  * @return 
  12.  */  
  13. public float getRawSize(int unit, float size) {  
  14.        Context c = getContext();  
  15.        Resources r;  
  16.   
  17.        if (c == null)  
  18.            r = Resources.getSystem();  
  19.        else  
  20.            r = c.getResources();  
  21.           
  22.        return TypedValue.applyDimension(unit, size, r.getDisplayMetrics());  
  23. }   

 

 

下面是网友提供的方法:

Java代码 
  1. /** 
  2. * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
  3. */  
  4. public static int dip2px(Context context, float dpValue) {  
  5.   final float scale = context.getResources().getDisplayMetrics().density;  
  6.   return (int) (dpValue * scale + 0.5f);  
  7. }  
  8.   
  9. /** 
  10. * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 
  11. */  
  12. public static int px2dip(Context context, float pxValue) {  
  13.   final float scale = context.getResources().getDisplayMetrics().density;  
  14.   return (int) (pxValue / scale + 0.5f);  
  15. }   

 

Android使用BitmapFactory.Options获取图片文件类型(mime)

Android系统中在读取图片时可通过BitmapFactory.Options的outMimeType来直接读取其图片类型。如果要知道一个文件的类型,最好方式是直接读取文件头信息,可查看Android中Java根据文件头获取文件类型

参考代码:

Java代码 
  1. BitmapFactory.Options opts = new BitmapFactory.Options();  
  2. opts.inJustDecodeBounds = true//确保图片不加载到内存  
  3. BitmapFactory.decodeResource(getResources(), R.drawable.a, opts);  
  4. System.out.println(opts.outMimeType);   

 

 

Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。

1、异常处理类,代码如下:

Java代码 
  1. public class CrashHandler implements UncaughtExceptionHandler {  
  2.     public static final String TAG = "CrashHandler";  
  3.     private static CrashHandler INSTANCE = new CrashHandler();  
  4.     private Context mContext;  
  5.     private Thread.UncaughtExceptionHandler mDefaultHandler;  
  6.   
  7.     private CrashHandler() {  
  8.     }  
  9.   
  10.     public static CrashHandler getInstance() {  
  11.         return INSTANCE;  
  12.     }  
  13.   
  14.     public void init(Context ctx) {  
  15.         mContext = ctx;  
  16.         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
  17.         Thread.setDefaultUncaughtExceptionHandler(this);  
  18.     }  
  19.   
  20.     @Override  
  21.     public void uncaughtException(Thread thread, Throwable ex) {  
  22.         // if (!handleException(ex) && mDefaultHandler != null) {  
  23.         // mDefaultHandler.uncaughtException(thread, ex);  
  24.         // } else {  
  25.         // android.os.Process.killProcess(android.os.Process.myPid());  
  26.         // System.exit(10);  
  27.         // }  
  28.         System.out.println("uncaughtException");  
  29.   
  30.         new Thread() {  
  31.             @Override  
  32.             public void run() {  
  33.                 Looper.prepare();  
  34.                 new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)  
  35.                         .setMessage("程序崩溃了...").setNeutralButton("我知道了"new OnClickListener() {  
  36.                             @Override  
  37.                             public void onClick(DialogInterface dialog, int which) {  
  38.                                 System.exit(0);  
  39.                             }  
  40.                         })  
  41.                         .create().show();  
  42.                 Looper.loop();  
  43.             }  
  44.         }.start();  
  45.     }  
  46.   
  47.     /** 
  48.      * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑 
  49.      *  
  50.      * @param ex 
  51.      * @return true:如果处理了该异常信息;否则返回false 
  52.      */  
  53.     private boolean handleException(Throwable ex) {  
  54.         if (ex == null) {  
  55.             return true;  
  56.         }  
  57.         // new Handler(Looper.getMainLooper()).post(new Runnable() {  
  58.         // @Override  
  59.         // public void run() {  
  60.         // new AlertDialog.Builder(mContext).setTitle("提示")  
  61.         // .setMessage("程序崩溃了...").setNeutralButton("我知道了", null)  
  62.         // .create().show();  
  63.         // }  
  64.         // });  
  65.   
  66.         return true;  
  67.     }  
  68. }   

 

2、线程绑定异常处理类

Java代码 
  1. public class CrashHandlerActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.main);  
  7.         CrashHandler crashHandler = CrashHandler.getInstance();    
  8.         crashHandler.init(this);  //传入参数必须为Activity,否则AlertDialog将不显示。  
  9.         // 创建错误  
  10.         throw new NullPointerException();  
  11.     }  
  12. }   

 

TextView属性android:ellipsize实现跑马灯效果

Android系统中TextView实现跑马灯效果,必须具备以下几个条件:
1、android:ellipsize=”marquee”
2、TextView必须单行显示,即内容必须超出TextView大小
3、TextView要获得焦点才能滚动

XML代码:

Java代码 
  1. android:ellipsize="marquee", android:singleLine="true"   

 

1android:ellipsize="marquee", android:singleLine="true"

Java代码:

Java代码 
  1. mTVText.setText("哼唱接撒砥砺风节雷锋精神http://orgcent.com/,很长很长很长很长很长很长的数据");  
  2. mTVText.setSingleLine(true);  
  3. mTVText.setEllipsize(TruncateAt.MARQUEE);   

 

1
2
3
mTVText.setText("哼唱接撒砥砺风节雷锋精神http://orgcent.com/,很长很长很长很长很长很长的数据");
mTVText.setSingleLine(true);
mTVText.setEllipsize(TruncateAt.MARQUEE);

PS: TextView.setHorizontallyScrolling(true); //让文字可以水平滑动

TextView还可以设置跑马灯效果的滚动次数,如下:
XML代码设置:

Java代码 
  1. android:marqueerepeatlimit="1"1代表1次,-1代表无限循环。   

 

1android:marqueerepeatlimit="1"。1代表1次,-1代表无限循环。

Java代码设置:

 

1mTVText.setMarqueeRepeatLimit(-1);
Java代码 
  1. mTVText.setMarqueeRepeatLimit(-1);   

 

Android闹钟程序周期循环提醒源码(AlarmManager)

Android系统提供了AlarmManager类来管理闹钟定时提醒任务。通过AlarmManager实现定时提醒及定时循环提醒。那么,AlarmManager类可以应用到以下场景:
1、定时循环启动组件(Component,如Activity、BroadcastReceiver),这样能替代在后台启动Service进行定时提醒任务
2、实现闹钟的按小时、天、周等形式的定时循环提醒功能。

定时启动组件很简单,下面贴出闹钟按天、周形式的定时循环提醒功能的核心代码。此功能核心的是计算出下一次闹钟提醒时间,代码如下:

Java代码 
  1. /** 
  2.  * 闹钟三种设置模式(dateMode): 
  3.  * 1、DATE_MODE_FIX:指定日期,如20120301   , 参数dateValue格式:2012-03-01 
  4.  * 2、DATE_MODE_WEEK:按星期提醒,如星期一、星期三 ,  参数dateValue格式:1,3 
  5.  * 3、DATE_MODE_MONTH:按月提醒,如3月2、3号,4月2、3号,  参数dateValue格式:3,4|2,3 
  6.  *   
  7.  * startTime:为当天开始时间,如上午9点, 参数格式为09:00 
  8.  */  
  9. public static long getNextAlarmTime(int dateMode, String dateValue,  
  10.         String startTime) {  
  11.     final SimpleDateFormat fmt = new SimpleDateFormat();  
  12.     final Calendar c = Calendar.getInstance();  
  13.     final long now = System.currentTimeMillis();  
  14.   
  15.     // 设置开始时间  
  16.     try {  
  17.         if(Task.DATE_MODE_FIX == dateMode) {  
  18.             fmt.applyPattern("yyyy-MM-dd");  
  19.             Date d = fmt.parse(dateValue);  
  20.             c.setTimeInMillis(d.getTime());  
  21.         }  
  22.           
  23.         fmt.applyPattern("HH:mm");  
  24.         Date d = fmt.parse(startTime);  
  25.         c.set(Calendar.HOUR_OF_DAY, d.getHours());  
  26.         c.set(Calendar.MINUTE, d.getMinutes());  
  27.         c.set(Calendar.SECOND, 0);  
  28.         c.set(Calendar.MILLISECOND, 0);  
  29.     } catch (Exception e) {  
  30.         e.printStackTrace();  
  31.     }  
  32.   
  33.     long nextTime = 0;  
  34.     if (Task.DATE_MODE_FIX == dateMode) { // 按指定日期  
  35.         nextTime = c.getTimeInMillis();  
  36.         // 指定日期已过  
  37.         if (now >= nextTime) nextTime = 0;  
  38.     } else if (Task.DATE_MODE_WEEK == dateMode) { // 按周  
  39.         final long[] checkedWeeks = parseDateWeeks(dateValue);  
  40.         if (null != checkedWeeks) {  
  41.             for (long week : checkedWeeks) {  
  42.                 c.set(Calendar.DAY_OF_WEEK, (int) (week + 1));  
  43.   
  44.                 long triggerAtTime = c.getTimeInMillis();  
  45.                 if (triggerAtTime <= now) { // 下周  
  46.                     triggerAtTime += AlarmManager.INTERVAL_DAY * 7;  
  47.                 }  
  48.                 // 保存最近闹钟时间  
  49.                 if (0 == nextTime) {  
  50.                     nextTime = triggerAtTime;  
  51.                 } else {  
  52.                     nextTime = Math.min(triggerAtTime, nextTime);  
  53.                 }  
  54.             }  
  55.         }  
  56.     } else if (Task.DATE_MODE_MONTH == dateMode) { // 按月  
  57.         final long[][] items = parseDateMonthsAndDays(dateValue);  
  58.         final long[] checkedMonths = items[0];  
  59.         final long[] checkedDays = items[1];  
  60.   
  61.         if (null != checkedDays && null != checkedMonths) {  
  62.             boolean isAdd = false;  
  63.             for (long month : checkedMonths) {  
  64.                 c.set(Calendar.MONTH, (int) (month - 1));  
  65.                 for (long day : checkedDays) {  
  66.                     c.set(Calendar.DAY_OF_MONTH, (int) day);  
  67.   
  68.                     long triggerAtTime = c.getTimeInMillis();  
  69.                     if (triggerAtTime <= now) { // 下一年  
  70.                         c.add(Calendar.YEAR, 1);  
  71.                         triggerAtTime = c.getTimeInMillis();  
  72.                         isAdd = true;  
  73.                     } else {  
  74.                         isAdd = false;  
  75.                     }  
  76.                     if (isAdd) {  
  77.                         c.add(Calendar.YEAR, -1);  
  78.                     }  
  79.                     // 保存最近闹钟时间  
  80.                     if (0 == nextTime) {  
  81.                         nextTime = triggerAtTime;  
  82.                     } else {  
  83.                         nextTime = Math.min(triggerAtTime, nextTime);  
  84.                     }  
  85.                 }  
  86.             }  
  87.         }  
  88.     }  
  89.     return nextTime;  
  90. }  
  91.   
  92. public static long[] parseDateWeeks(String value) {  
  93.     long[] weeks = null;  
  94.     try {  
  95.         final String[] items = value.split(",");  
  96.         weeks = new long[items.length];  
  97.         int i = 0;  
  98.         for (String s : items) {  
  99.             weeks[i++] = Long.valueOf(s);  
  100.         }  
  101.     } catch (Exception e) {  
  102.         e.printStackTrace();  
  103.     }  
  104.     return weeks;  
  105. }  
  106.   
  107. public static long[][] parseDateMonthsAndDays(String value) {  
  108.     long[][] values = new long[2][];  
  109.     try {  
  110.         final String[] items = value.split("\\|");  
  111.         final String[] monthStrs = items[0].split(",");  
  112.         final String[] dayStrs = items[1].split(",");  
  113.         values[0] = new long[monthStrs.length];  
  114.         values[1] = new long[dayStrs.length];  
  115.   
  116.         int i = 0;  
  117.         for (String s : monthStrs) {  
  118.             values[0][i++] = Long.valueOf(s);  
  119.         }  
  120.         i = 0;  
  121.         for (String s : dayStrs) {  
  122.             values[1][i++] = Long.valueOf(s);  
  123.         }  
  124.     } catch (Exception e) {  
  125.         e.printStackTrace();  
  126.     }  
  127.     return values;  
  128. }   

 

1、异常处理类,代码如下:

1
2
3
4
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true; //确保图片不加载到内存
BitmapFactory.decodeResource(getResources(), R.drawable.a, opts);
System.out.println(opts.outMimeType);

转载请注明地址: http://orgcent.com/android-dpsppx-unit-conversion/

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值