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

news/2024/7/7 12:48:13

【转】Android根据分辨率进行单位转换-(dp,sp转像素px)

  • 博客分类: 
  • Android 开发学习
 

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/

 

http://www.niftyadmin.cn/n/3649592.html

相关文章

[sync4j]Nokia手机和sync4j服务器同步的第三次尝试

第三次手机登录&#xff1a;按照前面所说的&#xff0c;设置手机上面的“远程数据库”为“./contact”&#xff0c;然后做手机同步。结果&#xff0c;经过漫长的初始化时间&#xff0c;手机上报告错误“连接错误同步类型不被支持无法和服务器同步”在服务器日志中&#xff0c;我…

Ionic6使用组件出现错误:Did you add it to @NgModule.entryComponents

缘由 在Ionic6和Angular8项目中使用组件时出现错误:Error: No component factory found for LoginComponent. Did you add it to NgModule.entryComponents? 在我的上一篇文章&#xff1a;移动开发&#xff1a;Ionic框架实现注册与登录功能中&#xff0c;实现软件运行时弹出登…

new一个Object对象占用多少内存?

Java的自动内存管理机制省却了很多编码工作&#xff0c;大大地提高了Java的生产力&#xff0c;而且JVM的性能也越来越好&#xff0c;特别是G1的出现&#xff0c;改善了垃圾回收中stop the world的状况。 也许很多人都没有考虑过这个问题&#xff0c;new一个Object对象到底占用多…

[Domino]“java.lang.ClassCastException:lotus.domino.cso.Item”异常解决办法

[Domino] “java.lang.ClassCastException&#xff1a;lotus.domino.cso.Item”异常解决办法编写者日期关键词郑昀ultrapower2005-6Java Domino RichTextItem通过Domino的Document.getFirstItem("Body")是可以获取当前邮件的Body字段&#xff0c;并试图直接转换为Ric…

命令行基础知识:使用ImageMagick调整图像大小

If you’ve ever done programmatic image manipulation (especially in PHP) you have probably encountered the ImageMagick library or it’s major fork, GraphicsMagick. In addition to being able to leverage it’s power from many popular programming languages, y…

什么是华为认证?HCIA HCIP HCIE分别是什么认证体系?

一、华为公司简介 华为创立于1987年&#xff0c;是全球领先的ICT (信息与通信&#xff09;基础设施和智能终端提供商&#xff0c;我们致力于把数字世界带入每个人、 每个家庭、每个组织&#xff0c;构建万物互联的智能世界。目前华为有18.8万员工&#xff0c;业务遍及170多个国…

Sync4j的Nokia手机实践结果

配置好Sync4j服务器后&#xff0c;我在Nokia手机上设置好同步&#xff0c;准备和这个远端服务器进行联系人的同步。下面的日志记录了两次失败的过程&#xff1a;第一次手机登录&#xff1a;由于Sync4j对设备要求事先在管理控制台上配置好&#xff0c;并添加规则&#xff0c;才能…

jarhoo是一个很棒的地方

jarhoo是一个很棒的根据类名找jar包的地方&#xff0c;。在写程序的时候&#xff0c;我反正是经常遇到某一个类声明不知道是哪一个jar包的&#xff0c;比如某一个开源包报告了java.lang.NoClassDefFoundError: javax/servlet/http/HttpSessionListener错误&#xff0c;搞得满世…