【转】Android根据分辨率进行单位转换-(dp,sp转像素px)
2015-10-24 22:03
651 查看
Android系统中,默认的单位是像素(px)。也就是说,在没有明确说明的情况下,所有的大小设置都是以像素为单位。
如果以像素设置大小,会导致不同分辨率下出现不同的效果。那么,如何将应用中所有大小的单位都设置为’dp’呢?
实际上TextView.setTextSize()重载了根据单位设置大小的方法。
笔者在此基础上实现了以下方法:
Java代码
/**
* 获取当前分辨率下指定单位对应的像素大小(根据设备信息)
* px,dip,sp -> px
*
* Paint.setTextSize()单位为px
*
* 代码摘自:TextView.setTextSize()
*
* @param unit TypedValue.COMPLEX_UNIT_*
* @param size
* @return
*/
public float getRawSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
return TypedValue.applyDimension(unit, size, r.getDisplayMetrics());
}
下面是网友提供的方法:
Java代码
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
Android使用BitmapFactory.Options获取图片文件类型(mime)
Android系统中在读取图片时可通过BitmapFactory.Options的outMimeType来直接读取其图片类型。如果要知道一个文件的类型,最好方式是直接读取文件头信息,可查看Android中Java根据文件头获取文件类型。
参考代码:
Java代码
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true; //确保图片不加载到内存
BitmapFactory.decodeResource(getResources(), R.drawable.a, opts);
System.out.println(opts.outMimeType);
Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。
1、异常处理类,代码如下:
Java代码
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE = new CrashHandler();
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// if (!handleException(ex) && mDefaultHandler != null) {
// mDefaultHandler.uncaughtException(thread, ex);
// } else {
// android.os.Process.killProcess(android.os.Process.myPid());
// System.exit(10);
// }
System.out.println("uncaughtException");
new Thread() {
@Override
public void run() {
Looper.prepare();
new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)
.setMessage("程序崩溃了...").setNeutralButton("我知道了", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
})
.create().show();
Looper.loop();
}
}.start();
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
// new Handler(Looper.getMainLooper()).post(new Runnable() {
// @Override
// public void run() {
// new AlertDialog.Builder(mContext).setTitle("提示")
// .setMessage("程序崩溃了...").setNeutralButton("我知道了", null)
// .create().show();
// }
// });
return true;
}
}
2、线程绑定异常处理类
Java代码
public class CrashHandlerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this); //传入参数必须为Activity,否则AlertDialog将不显示。
// 创建错误
throw new NullPointerException();
}
}
TextView属性android:ellipsize实现跑马灯效果
Android系统中TextView实现跑马灯效果,必须具备以下几个条件:
1、android:ellipsize=”marquee”
2、TextView必须单行显示,即内容必须超出TextView大小
3、TextView要获得焦点才能滚动
XML代码:
Java代码
android:ellipsize="marquee", android:singleLine="true"
Java代码:
Java代码
mTVText.setText("哼唱接撒砥砺风节雷锋精神http://orgcent.com/,很长很长很长很长很长很长的数据");
mTVText.setSingleLine(true);
mTVText.setEllipsize(TruncateAt.MARQUEE);
PS: TextView.setHorizontallyScrolling(true); //让文字可以水平滑动
TextView还可以设置跑马灯效果的滚动次数,如下:
XML代码设置:
Java代码
android:marqueerepeatlimit="1"。1代表1次,-1代表无限循环。
Java代码设置:
Java代码
mTVText.setMarqueeRepeatLimit(-1);
Android闹钟程序周期循环提醒源码(AlarmManager)
Android系统提供了AlarmManager类来管理闹钟定时提醒任务。通过AlarmManager实现定时提醒及定时循环提醒。那么,AlarmManager类可以应用到以下场景:
1、定时循环启动组件(Component,如Activity、BroadcastReceiver),这样能替代在后台启动Service进行定时提醒任务
2、实现闹钟的按小时、天、周等形式的定时循环提醒功能。
定时启动组件很简单,下面贴出闹钟按天、周形式的定时循环提醒功能的核心代码。此功能核心的是计算出下一次闹钟提醒时间,代码如下:
Java代码
/**
* 闹钟三种设置模式(dateMode):
* 1、DATE_MODE_FIX:指定日期,如20120301 , 参数dateValue格式:2012-03-01
* 2、DATE_MODE_WEEK:按星期提醒,如星期一、星期三 , 参数dateValue格式:1,3
* 3、DATE_MODE_MONTH:按月提醒,如3月2、3号,4月2、3号, 参数dateValue格式:3,4|2,3
*
* startTime:为当天开始时间,如上午9点, 参数格式为09:00
*/
public static long getNextAlarmTime(int dateMode, String dateValue,
String startTime) {
final SimpleDateFormat fmt = new SimpleDateFormat();
final Calendar c = Calendar.getInstance();
final long now = System.currentTimeMillis();
// 设置开始时间
try {
if(Task.DATE_MODE_FIX == dateMode) {
fmt.applyPattern("yyyy-MM-dd");
Date d = fmt.parse(dateValue);
c.setTimeInMillis(d.getTime());
}
fmt.applyPattern("HH:mm");
Date d = fmt.parse(startTime);
c.set(Calendar.HOUR_OF_DAY, d.getHours());
c.set(Calendar.MINUTE, d.getMinutes());
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
} catch (Exception e) {
e.printStackTrace();
}
long nextTime = 0;
if (Task.DATE_MODE_FIX == dateMode) { // 按指定日期
nextTime = c.getTimeInMillis();
// 指定日期已过
if (now >= nextTime) nextTime = 0;
} else if (Task.DATE_MODE_WEEK == dateMode) { // 按周
final long[] checkedWeeks = parseDateWeeks(dateValue);
if (null != checkedWeeks) {
for (long week : checkedWeeks) {
c.set(Calendar.DAY_OF_WEEK, (int) (week + 1));
long triggerAtTime = c.getTimeInMillis();
if (triggerAtTime <= now) { // 下周
triggerAtTime += AlarmManager.INTERVAL_DAY * 7;
}
// 保存最近闹钟时间
if (0 == nextTime) {
nextTime = triggerAtTime;
} else {
nextTime = Math.min(triggerAtTime, nextTime);
}
}
}
} else if (Task.DATE_MODE_MONTH == dateMode) { // 按月
final long[][] items = parseDateMonthsAndDays(dateValue);
final long[] checkedMonths = items[0];
final long[] checkedDays = items[1];
if (null != checkedDays && null != checkedMonths) {
boolean isAdd = false;
for (long month : checkedMonths) {
c.set(Calendar.MONTH, (int) (month - 1));
for (long day : checkedDays) {
c.set(Calendar.DAY_OF_MONTH, (int) day);
long triggerAtTime = c.getTimeInMillis();
if (triggerAtTime <= now) { // 下一年
c.add(Calendar.YEAR, 1);
triggerAtTime = c.getTimeInMillis();
isAdd = true;
} else {
isAdd = false;
}
if (isAdd) {
c.add(Calendar.YEAR, -1);
}
// 保存最近闹钟时间
if (0 == nextTime) {
nextTime = triggerAtTime;
} else {
nextTime = Math.min(triggerAtTime, nextTime);
}
}
}
}
}
return nextTime;
}
public static long[] parseDateWeeks(String value) {
long[] weeks = null;
try {
final String[] items = value.split(",");
weeks = new long[items.length];
int i = 0;
for (String s : items) {
weeks[i++] = Long.valueOf(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return weeks;
}
public static long[][] parseDateMonthsAndDays(String value) {
long[][] values = new long[2][];
try {
final String[] items = value.split("\\|");
final String[] monthStrs = items[0].split(",");
final String[] dayStrs = items[1].split(",");
values[0] = new long[monthStrs.length];
values[1] = new long[dayStrs.length];
int i = 0;
for (String s : monthStrs) {
values[0][i++] = Long.valueOf(s);
}
i = 0;
for (String s : dayStrs) {
values[1][i++] = Long.valueOf(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return values;
}
1、异常处理类,代码如下:
转载请注明地址: http://orgcent.com/android-dpsppx-unit-conversion/
如果以像素设置大小,会导致不同分辨率下出现不同的效果。那么,如何将应用中所有大小的单位都设置为’dp’呢?
实际上TextView.setTextSize()重载了根据单位设置大小的方法。
笔者在此基础上实现了以下方法:
Java代码
/**
* 获取当前分辨率下指定单位对应的像素大小(根据设备信息)
* px,dip,sp -> px
*
* Paint.setTextSize()单位为px
*
* 代码摘自:TextView.setTextSize()
*
* @param unit TypedValue.COMPLEX_UNIT_*
* @param size
* @return
*/
public float getRawSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
return TypedValue.applyDimension(unit, size, r.getDisplayMetrics());
}
下面是网友提供的方法:
Java代码
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
Android使用BitmapFactory.Options获取图片文件类型(mime)
Android系统中在读取图片时可通过BitmapFactory.Options的outMimeType来直接读取其图片类型。如果要知道一个文件的类型,最好方式是直接读取文件头信息,可查看Android中Java根据文件头获取文件类型。
参考代码:
Java代码
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true; //确保图片不加载到内存
BitmapFactory.decodeResource(getResources(), R.drawable.a, opts);
System.out.println(opts.outMimeType);
Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。
1、异常处理类,代码如下:
Java代码
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE = new CrashHandler();
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// if (!handleException(ex) && mDefaultHandler != null) {
// mDefaultHandler.uncaughtException(thread, ex);
// } else {
// android.os.Process.killProcess(android.os.Process.myPid());
// System.exit(10);
// }
System.out.println("uncaughtException");
new Thread() {
@Override
public void run() {
Looper.prepare();
new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)
.setMessage("程序崩溃了...").setNeutralButton("我知道了", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
})
.create().show();
Looper.loop();
}
}.start();
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
// new Handler(Looper.getMainLooper()).post(new Runnable() {
// @Override
// public void run() {
// new AlertDialog.Builder(mContext).setTitle("提示")
// .setMessage("程序崩溃了...").setNeutralButton("我知道了", null)
// .create().show();
// }
// });
return true;
}
}
2、线程绑定异常处理类
Java代码
public class CrashHandlerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this); //传入参数必须为Activity,否则AlertDialog将不显示。
// 创建错误
throw new NullPointerException();
}
}
TextView属性android:ellipsize实现跑马灯效果
Android系统中TextView实现跑马灯效果,必须具备以下几个条件:
1、android:ellipsize=”marquee”
2、TextView必须单行显示,即内容必须超出TextView大小
3、TextView要获得焦点才能滚动
XML代码:
Java代码
android:ellipsize="marquee", android:singleLine="true"
1 | android:ellipsize="marquee", android:singleLine="true" |
Java代码
mTVText.setText("哼唱接撒砥砺风节雷锋精神http://orgcent.com/,很长很长很长很长很长很长的数据");
mTVText.setSingleLine(true);
mTVText.setEllipsize(TruncateAt.MARQUEE);
1 2 3 | mTVText.setText("哼唱接撒砥砺风节雷锋精神http://orgcent.com/,很长很长很长很长很长很长的数据"); mTVText.setSingleLine(true); mTVText.setEllipsize(TruncateAt.MARQUEE); |
TextView还可以设置跑马灯效果的滚动次数,如下:
XML代码设置:
Java代码
android:marqueerepeatlimit="1"。1代表1次,-1代表无限循环。
1 | android:marqueerepeatlimit="1"。1代表1次,-1代表无限循环。 |
1 | mTVText.setMarqueeRepeatLimit(-1); |
mTVText.setMarqueeRepeatLimit(-1);
Android闹钟程序周期循环提醒源码(AlarmManager)
Android系统提供了AlarmManager类来管理闹钟定时提醒任务。通过AlarmManager实现定时提醒及定时循环提醒。那么,AlarmManager类可以应用到以下场景:
1、定时循环启动组件(Component,如Activity、BroadcastReceiver),这样能替代在后台启动Service进行定时提醒任务
2、实现闹钟的按小时、天、周等形式的定时循环提醒功能。
定时启动组件很简单,下面贴出闹钟按天、周形式的定时循环提醒功能的核心代码。此功能核心的是计算出下一次闹钟提醒时间,代码如下:
Java代码
/**
* 闹钟三种设置模式(dateMode):
* 1、DATE_MODE_FIX:指定日期,如20120301 , 参数dateValue格式:2012-03-01
* 2、DATE_MODE_WEEK:按星期提醒,如星期一、星期三 , 参数dateValue格式:1,3
* 3、DATE_MODE_MONTH:按月提醒,如3月2、3号,4月2、3号, 参数dateValue格式:3,4|2,3
*
* startTime:为当天开始时间,如上午9点, 参数格式为09:00
*/
public static long getNextAlarmTime(int dateMode, String dateValue,
String startTime) {
final SimpleDateFormat fmt = new SimpleDateFormat();
final Calendar c = Calendar.getInstance();
final long now = System.currentTimeMillis();
// 设置开始时间
try {
if(Task.DATE_MODE_FIX == dateMode) {
fmt.applyPattern("yyyy-MM-dd");
Date d = fmt.parse(dateValue);
c.setTimeInMillis(d.getTime());
}
fmt.applyPattern("HH:mm");
Date d = fmt.parse(startTime);
c.set(Calendar.HOUR_OF_DAY, d.getHours());
c.set(Calendar.MINUTE, d.getMinutes());
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
} catch (Exception e) {
e.printStackTrace();
}
long nextTime = 0;
if (Task.DATE_MODE_FIX == dateMode) { // 按指定日期
nextTime = c.getTimeInMillis();
// 指定日期已过
if (now >= nextTime) nextTime = 0;
} else if (Task.DATE_MODE_WEEK == dateMode) { // 按周
final long[] checkedWeeks = parseDateWeeks(dateValue);
if (null != checkedWeeks) {
for (long week : checkedWeeks) {
c.set(Calendar.DAY_OF_WEEK, (int) (week + 1));
long triggerAtTime = c.getTimeInMillis();
if (triggerAtTime <= now) { // 下周
triggerAtTime += AlarmManager.INTERVAL_DAY * 7;
}
// 保存最近闹钟时间
if (0 == nextTime) {
nextTime = triggerAtTime;
} else {
nextTime = Math.min(triggerAtTime, nextTime);
}
}
}
} else if (Task.DATE_MODE_MONTH == dateMode) { // 按月
final long[][] items = parseDateMonthsAndDays(dateValue);
final long[] checkedMonths = items[0];
final long[] checkedDays = items[1];
if (null != checkedDays && null != checkedMonths) {
boolean isAdd = false;
for (long month : checkedMonths) {
c.set(Calendar.MONTH, (int) (month - 1));
for (long day : checkedDays) {
c.set(Calendar.DAY_OF_MONTH, (int) day);
long triggerAtTime = c.getTimeInMillis();
if (triggerAtTime <= now) { // 下一年
c.add(Calendar.YEAR, 1);
triggerAtTime = c.getTimeInMillis();
isAdd = true;
} else {
isAdd = false;
}
if (isAdd) {
c.add(Calendar.YEAR, -1);
}
// 保存最近闹钟时间
if (0 == nextTime) {
nextTime = triggerAtTime;
} else {
nextTime = Math.min(triggerAtTime, nextTime);
}
}
}
}
}
return nextTime;
}
public static long[] parseDateWeeks(String value) {
long[] weeks = null;
try {
final String[] items = value.split(",");
weeks = new long[items.length];
int i = 0;
for (String s : items) {
weeks[i++] = Long.valueOf(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return weeks;
}
public static long[][] parseDateMonthsAndDays(String value) {
long[][] values = new long[2][];
try {
final String[] items = value.split("\\|");
final String[] monthStrs = items[0].split(",");
final String[] dayStrs = items[1].split(",");
values[0] = new long[monthStrs.length];
values[1] = new long[dayStrs.length];
int i = 0;
for (String s : monthStrs) {
values[0][i++] = Long.valueOf(s);
}
i = 0;
for (String s : dayStrs) {
values[1][i++] = Long.valueOf(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return values;
}
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); |
相关文章推荐
- android XML解析之DOM解析方式
- android 编译系统
- 《第一行代码Android》学习日记9
- 自学JAVA编程及android编程第一个月总结及下一个月思路
- Android学习笔记——国际化
- Android常用组件
- Android 学习笔记之Volley开源框架解析(五)
- 《第一行代码Android》学习日记8
- Android ANR
- Caused by: android.os.NetworkOnMainThreadException
- Android下HelloWorld项目的R.java文件介绍
- Android PopupWindow的使用和分析
- 《第一行代码Android》学习日记7
- android color.xml
- Android 的消息机制(Handler消息传递机制)
- Android编码规范03
- Android开发-控件
- AIDL 的理解与使用(一种android内部进程通信接口的描述语言)
- Android sdk配置
- Android学习(1)——接收和发送短信