您的位置:首页 > 移动开发 > Android开发

【转】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"

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

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);
PS: TextView.setHorizontallyScrolling(true); //让文字可以水平滑动

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

XML代码设置:

Java代码


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

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

1mTVText.setMarqueeRepeatLimit(-1);
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、异常处理类,代码如下:
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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: