API_node_android
把module用到的API做一个总结吧
1、软键盘
Handle keyboard input |Android Developers
调出软键盘
AddWordFragment
//弹出软键盘(弹出软键盘需要控件拿到焦点)
fun showSoftKeyboard(view: View) {
if (view.requestFocus()) {
val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
}
//editText控件获取焦点
edEnglish.requestFocus()
showSoftKeyboard(edEnglish)
隐藏软键盘
WordFragment
//隐藏软键盘
fun hideSoftKeyboard(){
val imm =requireActivity()?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view?.windowToken, 0)
}
//Fragment执行onResume生命周期方法时候隐藏软键盘
override fun onResume() {
super.onResume()
hideSoftKeyboard()
}
2、监听editText文本改变
实现效果: 当输入了单词中文和英文单词, 提交按钮设为可用
AddWordFragment
//TextWatcher监听, 当edEnglish和edChinese内都有内容时候隐藏软键盘
val textWatcher:TextWatcher = object :TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val english = edEnglish.text.toString().trim()
val chinese = edChinese.text.toString().trim()
floatActionButtonAdd.isEnabled = !english.isEmpty() && !chinese.isEmpty()
}
}
//给两个控件添加监听
edEnglish.addTextChangedListener(textWatcher)
edChinese.addTextChangedListener(textWatcher)
}
3、ActionBar回退键
设置导航后Action bar显示向上箭头
WordFragment
//Fragment初始化的时候设置支持回退键
private fun initEvent() {
//支持导航到AddFragment碎片时, 回退键头出现
val navController = findNavController()
NavigationUI.setupActionBarWithNavController(activity as AppCompatActivity, navController)
...
}
回退键事件监听
MainActivity
//监听点击action bar回退按钮操作
override fun onSupportNavigateUp(): Boolean {
/*
* @ param R.id.nav_word: 指放nav_graph的viewGroup的id
* */
return Navigation.findNavController(findViewById(R.id.nav_word)).navigateUp() or super.onSupportNavigateUp()
}
4、手机自带的回退键的导航出栈
MainActivity
//当按下手机自带导航栏的回退键时候, 需要出栈处理
override fun onBackPressed() {
super.onBackPressed()
Navigation.findNavController(findViewById(R.id.nav_word)).navigateUp()
}
5、OptionMenu中searchView的文本监听
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
val viewItemWord = inflater.inflate(R.menu.menu_word, menu)
// Get the SearchView and set the searchable configuration
val searchManager = requireActivity().getSystemService(Context.SEARCH_SERVICE) as SearchManager
(menu.findItem(R.id.search_word_menu).actionView as SearchView).apply {
//设置searchView的最大宽度
maxWidth = 800
//searchView文本监听
setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
//当搜索框内文本发生改变时后台进行数据获取
override fun onQueryTextChange(newText: String?): Boolean {
newText?.run{
words?.removeObservers(viewLifecycleOwner)
words = wordViewModel.getSearchWords(newText)
//因为requireActivity作为owner的时候,之前的activity也没有删除掉,所以每次都会叠加新的activity作为owner,但是实际要求应该是只有一个owner
words?.observe(viewLifecycleOwner) { list ->
wordAdapter.submitList(list)
}
}
return true
}
})
//点击软键盘右上角收起(软键盘)键, 同时需要将搜索框变为搜索图标
/*setOnKeyListener { v, keyCode, event ->
if(keyCode == KeyEvent.){}
}*/
}
}
6、RecyclerView的序号问题处理
WordFragment
//初始化RecyclerView
private fun initRecyclerView() {
wordAdapter = WordAdapter(wordViewModel)
//rv: 拿到的RecyclerView
rv?.run{
adapter = wordAdapter
//layoutManagerr(linearLayout(requireActivity()
layoutManager = LinearLayoutManager(requireActivity())
// layoutManager = StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL)
//RecyclerView显示数据(动画)结束后, 执行
itemAnimator = object : DefaultItemAnimator() {
override fun onAnimationFinished(viewHolder: RecyclerView.ViewHolder) {
super.onAnimationFinished(viewHolder)
//插入一个item动画结束后, 更新数据(序号)
val linnerLayoutManager: LinearLayoutManager = rv?.layoutManager as LinearLayoutManager
val first: Int = linnerLayoutManager.findFirstVisibleItemPosition()
val last: Int = linnerLayoutManager.findLastVisibleItemPosition()
for(i in first..last){
val holder = rv?.findViewHolderForAdapterPosition(i) as? WordAdapter.WordViewHolder
holder?.let{ it.tvId.text = (i+1).toString()}
}
}
}
}
7、RecyclerView删除列表的某一项
WordFragment
//rv的item滑动删除某一项处理
object: ItemTouchHelper(object: ItemTouchHelper.SimpleCallback(0,( ItemTouchHelper.START or ItemTouchHelper.END)) {
/*
* @param dragDirs: 允许拖动的方向, 0表示不支持拖动
* @param swipeDirs: 允许滑动的方向, ItemTouchHelper.START: 从左向右开始滑动 ItemTouchHelper.END: 从右向左开始滑动
* */
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
//拿到要删除的item对应的WordEntity
val wordItemDelete: WordEntity? = words?.value?.get(viewHolder.adapterPosition)//words.value调用get方法很可能不能实时返回结果, 尤其是当正在异步查询的时候
wordItemDelete?.run{
wordViewModel.deleteWords(this)
}
//误删除数据的撤销处理
Snackbar.make(binding.rvWordfragmentContent, "您删除了一条数据", Snackbar.LENGTH_SHORT)
.setAction("撤销") { v ->
wordViewModel.insertWords(wordItemDelete!!)
}.show()
}
}){}.attachToRecyclerView(rv)
删除数据后的撤销处理
//误删除数据的撤销处理
Snackbar.make(binding.rvWordfragmentContent, "您删除了一条数据", Snackbar.LENGTH_SHORT)
.setAction("撤销") { v -> wordViewModel.insertWords(wordItemDelete!!)
}.show()
8、SwitchView开关打开和关闭的监听
WordAdapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder {
val inflater: LayoutInflater = LayoutInflater.from(parent.context)
val binding:WordItemContentBinding = DataBindingUtil.inflate(inflater, R.layout.word_item_content, parent, false)
val holder:WordViewHolder = WordViewHolder(binding)
//**** 注意: 将view的事件监听放入刚刚创建的viewHolder中, 这样就不用每一次点击的时候都要去new一个匿名内部类了
//整体的卡片式的布局设置监听, 打开百度翻译
holder.cartView.setOnClickListener(){ v ->
//当点击事件发生的时候先拿到holder下的这个数据, 拿到的是一个Object类型需要强转
//val word: WordEntity = holder.cartView.getTag(R.id.id_holder_word_for_view) as WordEntity
val uri: Uri = Uri.parse("https://fanyi.baidu.com/?aldtype=85#zh/en/${holder.tvEnglish.text}")
//Log.d("test_english", word.englishMean)
val intent = Intent(Intent.ACTION_VIEW, uri)
holder.cartView.context.startActivity(intent)
}
//点击开关控件隐藏和显示中文
holder.switchHideChinese.setOnCheckedChangeListener(){switchView, isChecked->
//当点击事件发生的时候先拿到holder下的这个数据, 拿到的是一个Object类型需要强转
val word: WordEntity = holder.cartView.getTag(R.id.id_holder_word_for_view) as WordEntity
if(isChecked){
holder.tvChinese.visibility = View.GONE
word?.isHideChineseMean = true
word?.run{
wordViewModel.updateWords(this)
}
}else{
holder.tvChinese.visibility = View.VISIBLE
word?.isHideChineseMean = false
word?.run{
wordViewModel.updateWords(this)
}
}
}
return holder
9、RecyclerView viewHolder下的控件不重复监听的优化技巧
原理:View.setTag
View.getTag
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder {
val inflater: LayoutInflater = LayoutInflater.from(parent.context)
val binding:WordItemContentBinding = DataBindingUtil.inflate(inflater, R.layout.word_item_content, parent, false)
val holder:WordViewHolder = WordViewHolder(binding)
//**** 注意: 将view的事件监听放入刚刚创建的viewHolder中, 这样就不用每一次点击的时候都要去new一个匿名内部类了
//整体的卡片式的布局设置监听, 打开百度翻译
holder.cartView.setOnClickListener(){ v ->
//当点击事件发生的时候先拿到holder下的这个数据, 拿到的是一个Object类型需要强转
//val word: WordEntity = holder.cartView.getTag(R.id.id_holder_word_for_view) as WordEntity
val uri: Uri = Uri.parse("https://fanyi.baidu.com/?aldtype=85#zh/en/${holder.tvEnglish.text}")
//Log.d("test_english", word.englishMean)
val intent = Intent(Intent.ACTION_VIEW, uri)
holder.cartView.context.startActivity(intent)
}
//点击开关控件隐藏和显示中文
holder.switchHideChinese.setOnCheckedChangeListener(){switchView, isChecked->
//当点击事件发生的时候先拿到holder下的这个数据, 拿到的是一个Object类型需要强转
val word: WordEntity = holder.cartView.getTag(R.id.id_holder_word_for_view) as WordEntity
if(isChecked){
holder.tvChinese.visibility = View.GONE
word?.isHideChineseMean = true
word?.run{
wordViewModel.updateWords(this)
}
}else{
holder.tvChinese.visibility = View.VISIBLE
word?.isHideChineseMean = false
word?.run{
wordViewModel.updateWords(this)
}
}
}
return holder
}
override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
val word: WordEntity = getItem(position)
//存储word
holder.cartView.setTag(R.id.id_holder_word_for_view, word)
...
}