本篇主要收录一些Android小技巧,方便查询,不用以后每次都百度或者谷歌了。持续更新ing。。。

1、checkBox勾选框颜色

android:buttonTint="@color/colorAccent"

2、控件点击实现模拟back键功能
方法一(注意要在非主线程使用)

Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

方法二

Runtime runtime = Runtime.getRuntime();
runtime.exec("input keyevent " + KeyEvent.KEYCODE_BACK);

3、图片压缩方法(先改尺寸,再减质量)
//压尺寸reqWidth:Int 期望的宽 reqHeight:Int 期望的高

object ImageZip {
    fun decodeSampledBitmapFromFile(pathName:String,reqWidth:Int,reqHeight:Int):Bitmap{
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFile(pathName,options)
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
        options.inJustDecodeBounds = false
        val src = BitmapFactory.decodeFile(pathName,options)
        return src
    }

	   private  fun calculateInSampleSize(options: BitmapFactory.Options,reqWidth: Int,reqHeight: Int):Int{
        // 源图片的高度和宽度
        val height = options.outHeight
        val width = options.outWidth
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
        val halfHeight = height / 2
        val halfWidth = width / 2
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while (halfHeight / inSampleSize > reqHeight && halfWidth / inSampleSize > reqWidth) {
            inSampleSize *= 2
            }
        }
        return inSampleSize
    }
}

使用

fun pathTOStringBtmap(path:String):String{
        //压缩图片尺寸
       val bt =ImageZip.decodeSampledBitmapFromFile(path,300,300)
       val bs:ByteArrayOutputStream  = ByteArrayOutputStream()
        //设置图片质量 50(100满)
        bt.compress(Bitmap.CompressFormat.JPEG,50,bs)
        val bytes = bs.toByteArray()
        val str:String = Base64.encodeToString(bytes,Base64.DEFAULT)
        return str
    }

4、recyclerView删除item后刷新position

items.removeAt(position)
    notifyItemRemoved(position)//这样会有删除动画
    notifyItemRangeRemoved(position, items.size)//更新position,不然会出现IndexOutOfBoundsException异常

5、多个editext共存时,指定某个获取焦点,获取焦点时全选内容

所有控件xml中添加
	android:focusable="true"
    android:selectAllOnFocus="true"
	需要获取焦点的控件代码里动态编写:
	XXX.requestFocus()

6、页面finish关闭后软键盘不关闭的解决办法
关闭后打开的页面设置为

android:windowSoftInputMode="stateUnspecified"

7、点击空白处隐藏软键盘的方法(空白处是listview/recylerview 无效)

override fun onTouchEvent(event: MotionEvent): Boolean {
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    if (event.action == MotionEvent.ACTION_DOWN) {
        if (this.currentFocus != null) {
            if (this.currentFocus.windowToken != null) {
                imm.hideSoftInputFromWindow(this.currentFocus.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
            }
        }
    }
    return super.onTouchEvent(event)
}

点击列表隐藏打开的软键盘

recyclerView_chat.setOnTouchListener(new View.OnTouchListener() {  
        @Override  
        public boolean onTouch(View view, MotionEvent motionEvent) {  
            hideSoftInput(MainActivity.this, editText_message);  
            return false;  
        }  
    })

public static void hideSoftInput(Context context, View view) {  
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);  
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);  

}

8、主动显隐软键盘

/**隐藏键盘  */
protected fun hideInputKeyboard(v: View) {
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(v.windowToken, 0)
}

/**弹起键盘  */
private fun showInputKeyboard(v: View) {
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(v, 0)
}

9、SoundPool的stop方法传入的值是play方法的返回值

10、对于json格式的传输,如果其中value也是json且其key的name 和数量都不确定,可以把不确定的json设为map进行然后把包含map的对象转换为json:
例如:要传送如下格式的json给服务端

{ 
"speed":{ //速度时长 (速度:秒数)
  "30":"12",
  "40":"345",
  "60":"234"
},
"hand":{ //左右手时长
  "left":"1.2",
  "right":"0.4",
  "lr_hand":"1" //左右手
},
"sections":{ //小节 (小节号:是否正确 0正确 1 错误)
  "1":"1", 
  "2":"0",
  "3":"1",
  "4":"0",
  "5":"1"
},
  "total_section":"100", //总小节
  "total_duration":"12" //总时长(秒数)

}

这个json的特点有 speed 和 sections的 key数量和名称不确定,hand的key名称确定但数量不确定

这时可以创建一个对象承载这样的数据

public class PlayDetailData {
private Map speed;
private Map hand;
private Map sections;
private String total_section;//总小节
private String total_duration;//总时长

然后赋值

PlayDetailData playDetailData = new PlayDetailData();
    playDetailData.setHand(mHandSelectionMap);
    playDetailData.setSections(mSectionsSelectionMap);
    playDetailData.setSpeed(mSpeedSelectionMap);
    playDetailData.setTotal_duration(totalDuration + "");
    playDetailData.setTotal_section((maxMeasureNo + 1) + "");

把赋值的对象转换为json

String toJson = new Gson().toJson(playDetailData);

最终传给服务端的json为

{"hand":{"lr_hand":"7.5"},"sections":{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0"},"speed":{"120.0":"7.5"},"total_duration":"7.5","total_section":"8"}