Android常用的八种工具类,快看看有没有你还没用上的

Posted 宾有为

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android常用的八种工具类,快看看有没有你还没用上的相关的知识,希望对你有一定的参考价值。

目录

Glide 图片加载

需要添加Glide依赖implementation 'com.github.bumptech.glide:glide:4.13.0'annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'

/**
 * Glide 图片加载
 * 图片的url,此处采用本地路径加服务器地址的方式拼接,直接采用全部路径
 */
class ImageLoadUtils private constructor()

    companion object 
        // 单例模式
        val instance: ImageLoadUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  ImageLoadUtils() 
    
    
    /**
     * 获取默认的图片
     *
     * glide 默认使用缓存机制,但是加载Gif 图片时会造成oom,所以要关闭缓存机制
     * @return
     */
    fun getDefaultOptions(): RequestOptions? 
        return getOptions(R.drawable.ic_image_holder, R.drawable.ic_image_error)
    

    fun getOptions(@DrawableRes holderRes: Int, @DrawableRes errorRes: Int): RequestOptions? 
        return RequestOptions().centerCrop().error(errorRes).placeholder(holderRes)
    

    /**
     * 加载原图
     */
    fun load(context: Context, url: String, iv: ImageView) 
        if (objectNull(context, url, iv)) return
        Glide.with(context)
            .load(url)
            .apply(getDefaultOptions())
            .into(iv)
    

    /**
     * 加载圆形的图片
     */
    fun loadCircle(context: Context, url: String?, iv: ImageView) 
        Glide.with(context)
            .load(url)
            .apply(RequestOptions.bitmapTransform(CircleCrop()).apply(getDefaultOptions()))
            .into(iv)
    

    /**
     * 加载圆角图片
     */
    fun loadCorner(context: Context, url: String, iv: ImageView, size: Int) 
        if (objectNull(context, url, iv)) return
        Glide.with(context)
            .load(url)
            .skipMemoryCache(true) //圆角半径
            .apply(RequestOptions.bitmapTransform(RoundedCorners(50)))
            .into(iv)
    

    /**
     * 判断图片路径是否为空和是否符合规则
     */
    private fun objectNull(context: Context?, path: String, imageView: ImageView?): Boolean 
        return context == null || TextUtils.isEmpty(path) || imageView == null
    

SharedPreferences 本地缓存

class PreferenceUtil private constructor() 

    companion object 
        // 单例模式
        val instance: PreferenceUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  PreferenceUtil() 
    
    
    private val context: Context = MyApplication.getContext()
    val FILE_NAME = "leo_pro"

    /**
     * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
     *
     * @param key
     * @param obj
     */
    fun put(key: String?, obj: Any) 
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()
        when (obj) 
            is String -> 
                editor.putString(key, obj)
            
            is Int -> 
                editor.putInt(key, obj)
            
            is Boolean -> 
                editor.putBoolean(key, obj)
            
            is Float -> 
                editor.putFloat(key, obj)
            
            is Long -> 
                editor.putLong(key, obj)
            
            else -> 
                editor.putString(key, obj.toString())
            
        
        SharedPreferencesCompat.apply(editor)
    

    /**
     * 得到保存数据的方法,根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     *
     * @param key
     * @param defaultObject
     * @return
     */
    fun get(key: String?, defaultObject: Any?): Any? 
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        when (defaultObject) 
            is String -> 
                return sp.getString(key, defaultObject as String?)
            
            is Int -> 
                return sp.getInt(key, (defaultObject as Int?)!!)
            
            is Boolean -> 
                return sp.getBoolean(key, (defaultObject as Boolean?)!!)
            
            is Float -> 
                return sp.getFloat(key, (defaultObject as Float?)!!)
            
            is Long -> 
                return sp.getLong(key, (defaultObject as Long?)!!)
            
            else -> return null
        
    

    /**
     * 移除某个key值以及对应的值
     *
     * @param key
     */
    fun remove(key: String?) 
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.remove(key)
        SharedPreferencesCompat.apply(editor)
    

    /**
     * 清除所有数据
     */
    fun clear() 
        val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.clear()
        SharedPreferencesCompat.apply(editor)
    

    /**
     * 查询某个key是否已经存在
     *
     * @param key 查询的值
     */
    operator fun contains(key: String?): Boolean 
        val sp = context.getSharedPreferences(
            FILE_NAME,
            Context.MODE_PRIVATE
        )
        return sp.contains(key)
    

    /**
     * 返回所有的键值对
     */
    fun getAll(): Map<String?, *>? 
        val sp = context.getSharedPreferences(
            FILE_NAME,
            Context.MODE_PRIVATE
        )
        return sp.all
    

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private object SharedPreferencesCompat 
        private val sApplyMethod = findApplyMethod()

        /**
         * 反射查找apply的方法
         */
        private fun findApplyMethod(): Method? 
            try 
                val clz: Class<*> = SharedPreferences.Editor::class.java
                return clz.getMethod("apply")
             catch (e: NoSuchMethodException) 
            
            return null
        

        /**
         * 如果找到则使用apply执行,否则使用commit
         */
        fun apply(editor: SharedPreferences.Editor) 
            try 
                if (sApplyMethod != null) 
                    sApplyMethod.invoke(editor)
                    return
                
             catch (e: IllegalArgumentException) 
             catch (e: IllegalAccessException) 
             catch (e: InvocationTargetException) 
            
            editor.commit()
        
    


Toast & Snackbar 消息展示

Toastandroid 12 及以上的Android版本Toast将会被限制使用,当应用处于前台时,应首选Snackbar,但Toast很多Application低版本的Android还在使用,这里封装类也加上Toast

/**
 * 防止重复点击toast,一直显示未隐藏
 */
class ShowMessage private constructor()
    private val context: Context = MyApplication.getContext()
    // 之前显示的内容
    private var oldMsg: String? = null
    // Toast对象
    private var toast: Toast? = null
    // Toast对象
    private var snackbar: Snackbar? = null
    // 第一次时间
    private var oneTime: Long = 0
    // 第二次时间
    private var twoTime: Long = 0

    companion object 
        // 单例模式
        val instance: ShowMessage by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  ShowMessage() 
    

    /**
     * 显示Toast
     * @param message
     */
    fun showToast(message: String) 
        if (toast == null) 
            toast = Toast.makeText(context, message, Toast.LENGTH_SHORT)
            toast!!.show()
            oneTime = System.currentTimeMillis()
         else 
            twoTime = System.currentTimeMillis()
            if (message == oldMsg) 
                if (twoTime - oneTime > Toast.LENGTH_SHORT) 
                    toast!!.show()
                
             else 
                oldMsg = message
                toast!!.setText(message)
                toast!!.show()
            
        
        oneTime = twoTime
    

    /**
     * 显示Snackbar
     * @param view
     * @param message
     */
    fun showSnackbar(view : View, message: String) 
        if (snackbar == null) 
            snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT)
            snackbar!!.show()
            oneTime = System.currentTimeMillis()
         else 
            twoTime = System.currentTimeMillis()
            if (message == oldMsg) 
                if (twoTime - oneTime > Toast.LENGTH_SHORT) 
                    snackbar!!.show()
                
             else 
                oldMsg = message
                snackbar!!.setText(message)
                snackbar!!.show()
            
        
        oneTime = twoTime
    

Log日志打印

Android自带的Log日志打印超出一定长度时会自动截断日志内容,后面的那一段日志内容不会打印出来,在此也做一个封装,如果没打印完日志,则换行继续打印。

打包发布APK时,将isPrintLog设置为false,日志不会再打印,这样就不用经常添加、删除Log打印日志的代码啦!

/**
 * 日志打印
 * */
class LogUtils private constructor() 
    private var isPrintLog = true
    private val LOG_MAXLENGTH = 4000
    private val MIDDLE_DIVIDER = "----------- 换行 ------------\\n"
    private val TOP_DIVIDER = "┌────────────────────────────────────────────────────────"
    private val BOTTOM_DIVIDER = "└────────────────────────────────────────────────────────"
    private val TAG = LogUtils::class.java.getSimpleName();

    companion object 
        // 单例模式
        val instance: LogUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  LogUtils() 
    

    /**
     * 控制是否打印日志
     */
    fun isPrintLog(pring : Boolean) 
        this.isPrintLog = pring
    

    /**
     * 使用默认的Tag打印日志
     *
     * msg : String 需要打印的消息
     */
    fun v(msg: String) 
        v(TAG, msg)
    

    /**
     * 使用自定义的tag打印日志
     *
     * tag :String 打印日志使用的标签
     * msg : String 需要打印的消息
     */
    fun v(tag: String, msg: String) 
        if (isPrintLog) 
            if (msg == null) 
                Log.v(tag, "null")
                return
            
            var strLength = msg.length
            var start = 0
            var end = LOG_MAXLENGTH
            if (strLength > end) 
                val sbf = StringBuffer()
                sbf.append("\\n" + TOP_DIVIDER).append(msg)
                val trueMsg = sbf.toString()
                strLength = trueMsg.length
                while (strLength > end) 
                    if (start == 0) 
                        Log.v(tag, trueMsg.substring(start, end))
                        start = end
                        end += LOG_MAXLENGTH
                     else 
                        end -= MIDDLE_DIVIDER.length
                        Log.v(tag, MIDDLE_DIVIDER + trueMsg.substring(start, end))
                        start = end
                        end += LOG_MAXLENGTH
                    
                
                Log.v(tag, trueMsg.substring(start, strLength))
                Log.v(tag, "\\n" + BOTTOM_DIVIDER)
             else 
                Log.v(tag, msg)
            
        
    

Json & 对象互转

依赖Goole的gson库,需导入implementation 'com.google.code.gson:gson:2.9.0'或其它版本。

/**
 * Gson与对象互转
 *
 * 需导入 implementation 'com.google.code.gson:gson:2.9.0'
 */
class GsonUtil private constructor() 

    companion object
        // 单例模式
        val instance : GsonUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  GsonUtil() 
    

    /**
     * 返回一个JSON对象
     */
    private fun getGsonObject(): Gson 
        return GsonBuilder().serializeNulls().create()
    

    /**
     * 对象转Gson字符串
     *
     * @param obj
     * @return
     */
    fun <T : Any?> ser(obj: T): String? 
        return getGsonObject().toJson(obj)
    

    /**
     * Gson字符串转可序列化对象
     *
     * @param obj gson字符串
     * @param type 接口 
     * @return
     */
    fun <T : Any?> deser(obj: String?, type: Type?): T? 
        return try 
            getGsonObject().fromJson(obj, type)
         catch (e: Exception) 
            null
        
    

    /**
     * Gson字符串转可序列化对象
     *
     * @param obj json字符串
     * @param clazz 转化的序列化对象
     * @return
     */
    fun <T : Any?> deserBequiet(obj: String?, clazz: Class<T>?): T? 
        return try 
            getGsonObject().fromJson(obj, clazz)
         catch (e: Exception) 
            null
        
    

屏幕单位转换

/**
 * 屏幕单位转换
 */
class DisplayUtils private constructor()

    companion object
        // 单例模式
        val instant: DisplayUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED)  DisplayUtils() 
    

    /**
     * 获取屏幕的高度
     */
    fun getWindowHeight(activity: Activity): Int
        val dm : DisplayMetrics = DisplayMetrics();
        activity.windowManager.defaultDisplay.getMetrics(dm)
        return dm.heightPixels;
    

    /**
     * 获取屏幕的宽度
     */
    fun getWindowWidth(activity: Activity): Int
        val dm : DisplayMetrics = DisplayMetrics(Android常用的九种工具类,快看看有没有你还没用上的

Selenium Webdriver元素定位的八种常用方式

Selenium Webdriver元素定位的八种常用方式

Selenium Webdriver元素定位的八种常用方式

Selenium Webdriver元素定位的八种常用方式

胡楠宇推荐Selenium Webdriver元素定位的八种常用方式详解