`
longgangbai
  • 浏览: 7332192 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

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

/**
 * 获取当前分辨率下指定单位对应的像素大小(根据设备信息)
 * 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());
} 

 

 

下面是网友提供的方法:

/**
* 根据手机的分辨率从 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根据文件头获取文件类型

参考代码:

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、异常处理类,代码如下:

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、线程绑定异常处理类

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代码:

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);

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

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

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

 

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

Java代码设置:

 

1
mTVText.setMarqueeRepeatLimit(-1);
 mTVText.setMarqueeRepeatLimit(-1); 

 

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

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

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

/**
 * 闹钟三种设置模式(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/

分享到:
评论

相关推荐

    Android dp和px/sp等单位相互转换

    在Android开发中,理解并掌握dp、px、sp等单位之间的转换是非常重要的,因为它们直接影响到界面元素在不同分辨率和像素密度设备上的显示效果。dp(density-independent pixels)是独立像素,px(pixels)是像素,sp...

    Android像素转换dp转px或相反

    本文将深入探讨Android像素转换,包括dp转px以及px转dp的方法,并提供相关的实践示例。 一、Android屏幕密度 Android设备屏幕的分辨率和物理尺寸各异,为了确保应用界面在不同设备上呈现一致的效果,引入了密度...

    引用 Android上dip、dp、px、sp等单位说明

    在Android开发中,为了确保应用在不同分辨率和屏幕尺寸上的显示效果一致,开发者需要掌握几种关键的尺寸单位,包括dip(或dp)、px、sp以及它们之间的转换关系。 #### 1. dip(dp) **dip**(device-independent ...

    android布局单位sp,dp,pt,px的区别

    在Android开发中,为了确保应用在不同屏幕尺寸和密度下的适应性和一致性,使用了多种布局单位,其中最为常见的包括sp、dp(或dip)、pt和px。这些单位各有其特性和应用场景,理解它们之间的差异对于创建响应式和用户...

    dip, dp, px, sp区别 android

    "Android 中的 dip, dp, px, sp 单位区别" Android 中的单位系统是一个复杂的问题,对于开发人员来说,选择正确的单位是非常重要的。在 Android 中,我们常见的单位有 dip, dp, px, sp 等,这些单位都有其特点和...

    Android多分辨率适配

    Android开发中,我们通常使用dp(density-independent pixels,密度无关像素)作为单位,它是一种虚拟像素单位,可以自动根据设备的密度进行转换。1dp在mdpi屏幕上等于1px,其他密度屏幕会按比例缩放。此外,sp...

    Android-AndroidUnits用于在不同Android显示单位之间转换的工具类

    "AndroidUnits" 是一个专门为此目的设计的工具类,它提供了方便的方法来帮助开发者在像素(px)、密度独立像素(dp)、可缩放像素(sp)、点(pt)以及英寸(in)等单位之间进行转换。了解并掌握这个工具类的使用...

    Android中dip、dp、sp、pt和px的区别

    本文将详细解析Android中常见的五种尺寸单位:dip(设备独立像素)、dp(密度无关像素)、sp(可缩放像素)、pt(点)和px(像素),并探讨它们之间的关系和应用场景。 首先,我们来了解一下px(像素)。像素是屏幕...

    Android的计量单位px,in,mm,pt,dp,dip,sp

    7. **sp(scaled pixels)**:sp与dp类似,也是基于密度的抽象单位,但它还会根据用户设定的字体大小偏好进行缩放。因此,sp最适合用于设置文本的大小,确保在不同设备上都能获得良好的阅读体验。 在处理不同屏幕...

    Androd px转dip和sp

    `px`(像素)是设备独立像素,而`dip`(设备独立像素,也称为dp)和`sp`(可缩放像素,主要用于字体大小)是Android系统为了适应不同分辨率屏幕而引入的概念。这些单位有助于创建适应多种屏幕尺寸的应用。 `px`...

    Android-选择分辨率并自动生成对应的dimen.xml文件

    - **使用比例单位(dp和sp)**:dp(density-independent pixels)用于尺寸,sp(scale-independent pixels)用于字体大小,这两个单位会根据设备的像素密度进行自动缩放。 - **使用Android Studio的预览功能**:...

    基于Android中dp和px之间进行转换的实现代码

    此外,sp(Scale-independent Pixel)单位则用于文本大小,它与dp类似,但会根据用户的字体缩放设置进行自动调整。 总的来说,理解和熟练运用dp与px之间的转换是Android开发者必备的技能之一,这有助于创建适应性强...

    7. android屏幕适配px工具类

    当转换dp到px时,我们会基于设备的密度与基准密度的比例进行调整。例如,对于2倍密度的设备(如iPhone 5s),1dp等于2px。 此外,还可以扩展`PxUtils`类,添加更多辅助方法,比如: 3. `sp2px(Context context, ...

    Android-gendpi根据屏幕密度生成适配的px尺寸

    2. 使用比例尺寸单位(如dp或sp)而不是像素(px)来定义尺寸,因为dp和sp会根据屏幕密度自动调整。 3. 提供矢量图形资源(VectorDrawable)以适应任意分辨率,避免因分辨率提高导致的图片模糊。 4. 为重要的图标和...

    android屏幕适配px工具类

    3. **sp转px**和**px转sp**: sp(scaled pixel)是用于文本大小的单位,它会根据用户的字体大小设置进行缩放。转换公式与dp类似,但需要考虑`displayMetrics.scaledDensity`。 4. **屏幕尺寸获取**: 提供方法获取...

    Android多屏幕适配及样式-设计开发指导书

    4. **单位转换**:为了更好地适应不同屏幕尺寸和密度的设备,Android系统引入了dp (density-independent pixels) 和 sp (scalable pixels) 两个相对单位。dp用于描述尺寸和间距,sp用于描述字号和行距。这些单位能够...

    Android 图片切换器(dp、sp、px) 的单位转换器

    在Android开发中,UI设计和布局是至关重要的部分,其中涉及到不同的尺寸单位,如dp、sp、px等。这些单位在不同的场景下有着不同的应用,理解它们之间的转换对于适配不同屏幕尺寸和分辨率的设备至关重要。 1. dp ...

    java_android_常用像素单位转换的辅助类的标准代码

    根据手机的分辨率从 dip 的单位 转成为 px(像素) 根据手机的分辨率从 px(像素) 的单位 转成为 dp dp转px sp转px px转dp px转sp

    Android 自适应分辨率

    例如,可以计算出dp和px的转换比例,然后根据这个比例来设置控件的大小。 最后,Android的碎片(Fragment)机制也是实现自适应分辨率的重要工具。碎片可以在多个屏幕配置下重用,使得同一界面在手机和平板等不同...

Global site tag (gtag.js) - Google Analytics