Android API兼容,其他API,UI适配(------ 分割线 -----)

Android XML shape 标签使用详解- http://www.cnblogs.com/popfisher/p/6238119.html

shape写line虚线的时候发现4.0以上机型很多都没办法显示,后来在xml中 android:layerType="software"  
line.setLayerType(View.LAYER_TYPE_SOFTWARE, null);  

- GradientDrawable
GradientDrawable, API小于16的时候,需要使用GradientDrawable的带参构造函数;API大于16的时候,直接调用相关方法就行了。
//TODO:判断版本是否大于16  项目中默认的都是Linear散射 都是从左到右 都是只有开始颜色和结束颜色
        GradientDrawable drawable;
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            drawable=new GradientDrawable();
            drawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
            drawable.setColors(colors);
        }else{
            drawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
        }

/**
     *
     * @param drawable 生成的背景
     * @param view 需要添加背景的View
     */
    public static void setBackground(GradientDrawable drawable,View view)
    {
        //判断当前版本号,版本号大于等于16,使用setBackground;版本号小于16,使用setBackgroundDrawable。
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            view.setBackground(drawable);
        }else{
            view.setBackgroundDrawable(drawable);
        }
    }

-- gridView的getVerticalSpacing() getColumnWidth()
 一个流畅的拖动排序DragSortGridView,自动滚屏- https://blog.csdn.net/u013147734/article/details/51577246
gridView.getVerticalSpacing()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    totalHeight += listItem.getMeasuredHeight() + gridView.getVerticalSpacing(); // 统计所有子项的总高度
                } else {
                    totalHeight += listItem.getMeasuredHeight();
                }


public int getColumnWidth(){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return super.getColumnWidth();
        else{
            try{
                Field field = GridView.class.getDeclaredField("mColumnWidth");
                field.setAccessible(true);
                Integer value = (Integer) field.get(this);
                field.setAccessible(false);
                return value.intValue();
            }catch(NoSuchFieldException e){
                throw new RuntimeException(e);
            }catch(IllegalAccessException e){
                throw new RuntimeException(e);
            }
        }
    }

-- 横竖屏切换时候Activity的生命周期的总结- https://blog.csdn.net/wulianghuan/article/details/8603982
android:screenOrientation="landscape" 强制横屏;
android:screenOrientation="portrait" 强制竖屏;

- TaskStackBuilder  API level16(4.1);4.0对应API是:14.

— //MediaCodeC是Android 4.1(API16 ) 版本加入的一个新的音视频处理API
"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm) 
"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm) 
"video/avc" - H.264/AVC video 
"video/hevc" - H.265/HEVC video 
"video/mp4v-es" - MPEG4 video 
"video/3gpp" - H.263 video 
"audio/3gpp" - AMR narrowband audio 
"audio/amr-wb" - AMR wideband audio 
"audio/mpeg" - MPEG1/2 audio layer III 
"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!) 
"audio/vorbis" - vorbis audio 
"audio/g711-alaw" - G.711 alaw audio 
"audio/g711-mlaw" - G.711 ulaw audio

-- android音频 数据格式pcm流8位和16位的相互转换-https://blog.csdn.net/tklwj/article/details/80352065
  8位PCM 编码每个声音采样点用8bit来表示,16位PCM 编码每个声音采样点用16bit表示。因为16位PCM编码的采样精度更高,所以音质好一些,但8位PCM 编码所使用的数据量小一半,所以更容易存储和传输。
  8位PCM编码常用于电话等通讯电路,采样速率8k,节省传输带宽。16位PCM 编码常用于电脑多媒体声音文件,采样速率44.1K,音质好。
  为了提高信噪比,8位PCM编码动态压缩技术,也就是说非线性量化,对小信号采样级数更多,压缩方法有A率和u率两种,中国和欧洲用A率,美国用U率。8位PCM 编码播放的时候也要解压缩成16位pcm播放。

-- ||的使用
||,当使用||(短路或)时,若前面的表达式结果为真,则程序不会再执行后面的表达式,直接得出TRUE的结果。
捕获异常:try catch。

-- WifiP2pManager 4.0, 4.0以上。
Android WiFi P2P开发实践笔记-https://www.jianshu.com/p/e9a23dfda330
WifiP2p Service Discovery是安卓4.0增加的功能,只需要打开wifi就可以,不必要事先连接局域网或创建热点。
WifiP2pManager等类,建立连接后传输文件就用到Socket。

-- GradientDrawable
 arg1.setBackgroundColor(Color.parseColor("#87CEFA"));
 我们平常需要为一个控件设置background属性,直接用"控件.setBackground()"就可以了。但是有的时候会遇到这种情况:需要为控件动态的设置shape,你可以建立多个shape的drawable,这当然算是一种思路。这此我想提供另一种思路:
 GradientDrawable gd = textView.getBackground();
 gd.setColor(Color.parseColor("#333333");

//在代码中动态设置背景
//新建一个Drawable对象
GradientDrawable drawable=new GradientDrawable();
//设置背景色
drawable.setColor(Color.rgb(255,0,0));
//设置边框的厚度以及边框的颜色
drawable.setStroke(1,Color.rgb(0,0,0));
//设置圆角的半径  当然也是可以一个个设置圆角的半径
drawable.setCornerRadius(20);
//设置背景的形状,默认就是矩形,跟xml文件中类型android:shape的值保持一致,具体有:GradientDrawable.LINE  GradientDrawable.OVAL GradientDrawable.RECTANGLE  GradientDrawable.RING
drawable.setShape(GradientDrawable.RECTANGLE);

//实现背景渐变的效果
GradientDrawable drawable;
        //API大于等于16
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            drawable=new GradientDrawable();
            //俩设置方法其实就是对应着带参构造参数的那俩参数
            drawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
            drawable.setColors(colors);
        }else{
            drawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
        }

        drawable.setCornerRadii(radius);
        drawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);

— Android6.0+解决getColor()方法过时
public static final int getColor(Context context, @ColorRes int id) {
        final int version = Build.VERSION.SDK_INT;
        if (version >= 23) {
            return ContextCompatApi23.getColor(context, id);
        } else {
            return context.getResources().getColor(id);
        }
}
在Java代码中设置控件的Color时,通常这样写:
txtLabel.setTextColor(getResources().getColor(R.color.black));
但是getColor方法在Android 6.0即API 23中已经过时,替代方法为:
import android.support.v4.content.ContextCompat;
txtLabel.setTextColor(ContextCompat.getColor(context, R.color.black));
 
//判断当前版本号,版本号大于等于16,使用setBackground;版本号小于16,使用setBackgroundDrawable。
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
tvDrawable.setBackground(drawable);
}else{
tvDrawable.setBackgroundDrawable(drawable);
}

-- setBackgroundImage(convertView, )与getColor()兼容

ViewBackgroundCompatibleUtils.getInstance().setBackgroundImage(convertView, );

ViewBackgroundCompatibleUtils.getInstance().getColor(mContext,  )

/**
 *
得到颜色色值,适配不同的版本
 * @param context
 
* @param colorId
 
* @return
 
*/
public int getColor(Context context,  int colorId) {
    if (Build.VERSION.SDK_INT >= 23) {
        return ContextCompat.getColor(context, colorId);
    } else {
        return context.getResources().getColor(colorId);
    }
}

/**
 *
设置图片的背景,适配不同的版本
 * @param view
 
* @param drawable
 
*/
public void setBackgroundImage(View view,Drawable drawable) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        // Android系统大于等于API16,使用setBackground
       
view.setBackground(drawable);
    } else {
        // Android系统小于API16,使用setBackgroundDrawable
       
view.setBackgroundDrawable(drawable);
    }
}

-- 抛出异常

throw new IllegalArgumentException("Can't have a viewTypeCount < 1");

throw new IllegalArgumentException(“Illegal Array size or ArrayIndexOutOfBoundsException”);

throw new RuntimeException("state already added");

throw new IllegalStateException("ImageLoader must be invoked from the main thread.");

throw new NumberFormatException("无法将其转化为合适的数字");

throw new Error("null instance of <T extends DefaultHandler> passed to constructor");

throw new NullPointerException();

private void parseTime(String aTime) throws NumberFormatException {}

— ScriptIntrinsicBlur, Android api 17实现的虚化;
Android开发:高斯模糊blur效果兼容- https://www.pocketdigi.com/20150105/1412.html

— ListView在调用setAdapter()方法后再调用addHeaderView()方法会出现 Caused by: java.lang.IllegalStateException: Cannot add header view to list setAdapter has already been called.异常,意思是调用addHeaderView()方法在调用setAdapter()方法之后。android 4.4系统以前会有这个问题,在android 4.4及以后的版本修复了这个问题,不会报错.

— 使用String.substring时,未对字符串的长度进行检查,截取字符串时可能会发生越界而导致Crash

Android编程注意事项- https://blog.csdn.net/daipeng123456789/article/details/50977574
 
- API 21 ,MediaProjection;API 19, virtualDisplay;

- Android 屏幕各尺寸的获取- https://www.jianshu.com/p/a1ab688d7ef8
//API 17之后使用,获取的像素宽高包含虚拟键所占空间,在API 17之前通过反射获取  
context.getWindowManager().getDefaultDisplay().getRealMetrics(metric); 
//获取的像素宽高不包含虚拟键所占空间  
//context.getWindowManager().getDefaultDisplay().getMetrics(metric); 

-- Android手机底部有虚拟按键
屏幕高度是屏幕真是高度-虚拟按键的高度。所以有虚拟按键的情况获取屏幕的高度就是另一种方法了:
public static int getRealHeight(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); int screenHeight = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { DisplayMetrics dm = new DisplayMetrics(); display.getRealMetrics(dm); screenHeight = dm.heightPixels; //或者也可以使用getRealSize方法 // Point size = new Point(); // display.getRealSize(size); // screenHeight = size.y; } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { try { screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display); } catch (Exception e) { DisplayMetrics dm = new DisplayMetrics(); display.getMetrics(dm); screenHeight = dm.heightPixels; } } return screenHeight; }

虚拟按键高度
public static int getNavigationBarHeight(Context context) { int navigationBarHeight = -1; Resources resources = context.getResources(); int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android"); if (resourceId > 0) { navigationBarHeight = resources.getDimensionPixelSize(resourceId); } return navigationBarHeight; }

状态栏高度
1.public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
2.通过反射
Android的所有资源都会有惟一标识在R类中作为引用。我们也可以通过反射获取R类的实例域,然后找 status_bar_height。
    public void getStatusBarHeightByReflect() {
        int statusBarHeight2 = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusBarHeight2 = getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "状态栏高度-反射方式:" + statusBarHeight2);
    }

DisplayMetrics metric = new DisplayMetrics();

WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    activity.getWindowManager().getDefaultDisplay().getRealMetrics(metric);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
    try {
        screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
    } catch (Exception e) {
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        screenHeight = dm.heightPixels;
    }
}

-- ViewTreeObserver.removeOnGlobalLayoutListener兼容
if (Build.VERSION.SDK_INT < 16) {
   getViewTreeObserver().removeGlobalOnLayoutListener(this);//mOnGlobalLayoutListener
} else {
   getViewTreeObserver().removeOnGlobalLayoutListener(this);//mOnGlobalLayoutListener
}

Java-protected的使用范围-https://www.cnblogs.com/Victor-Han/p/4861412.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值