主要目的是想实现多窗口的切换,掌握activity的切换,正好按照官网教程,实现words的app。
1 words 功能
Words 应用是一个简单的字典应用,其中包含字母列表、每个字母对应的单词,还能够在浏览器中查找每个单词的定义。
具体布局和功能导航如下。
2 Code
主要使用RecyclerView 和button来显示A-Z的字母,以及显示list中的字母。
color, theme,以及bindingview的设置 等请参考之前的例子
2.1Resource
在src->Values 增加一个 Array.xml ,用于存放words列表。
<?xml version="1.0" encoding="utf-8"?>
<!--
-->
<resources>
<string-array name="words">
<item>aargh</item>
<item>about</item>
<item>acidic</item>
<item>acne</item>
<item>acrid</item>
<item>acute</item>
<item>alphabet</item>
<item>anchor</item>
<item>anecdote</item>
<item>animal</item>
<item>automobile</item>
<item>awesome</item>
<item>back</item>
<item>balloon</item>
<item>basket</item>
<item>bench</item>
<item>best</item>
<item>birthday</item>
<item>books</item>
<item>brief</item>
<item>business</item>
<item>buy</item>
<item>camera</item>
<item>catapult</item>
<item>center</item>
<item>children</item>
<item>city</item>
<item>class</item>
<item>click</item>
<item>coffee</item>
<item>comment</item>
<item>company</item>
<item>contact</item>
<item>copyright</item>
<item>creative</item>
<item>data</item>
<item>day</item>
<item>details</item>
<item>development</item>
<item>dine</item>
<item>dream</item>
<item>dusk</item>
<item>each</item>
<item>education</item>
<item>electric</item>
<item>elephant</item>
<item>email</item>
<item>emerald</item>
<item>event</item>
<item>every</item>
<item>family</item>
<item>file</item>
<item>find</item>
<item>first</item>
<item>flair</item>
<item>flight</item>
<item>follow</item>
<item>forum</item>
<item>fox</item>
<item>free</item>
<item>frequent</item>
<item>full</item>
<item>game</item>
<item>general</item>
<item>glass</item>
<item>good</item>
<item>gram</item>
<item>gray</item>
<item>great</item>
<item>green</item>
<item>group</item>
<item>guide</item>
<item>guitar</item>
<item>haircut</item>
<item>health</item>
<item>hearsay</item>
<item>help</item>
<item>here</item>
<item>home</item>
<item>honey</item>
<item>hundred</item>
<item>hurried</item>
<item>ice</item>
<item>icon</item>
<item>inbox</item>
<item>incomplete</item>
<item>information</item>
<item>investment</item>
<item>item</item>
<item>jackal</item>
<item>january</item>
<item>job</item>
<item>join</item>
<item>joke</item>
<item>journal</item>
<item>july</item>
<item>jump</item>
<item>june</item>
<item>kangaroo</item>
<item>keep</item>
<item>keyboard</item>
<item>kind</item>
<item>kingdom</item>
<item>knowledge</item>
<item>known</item>
<item>koala</item>
<item>landscape</item>
<item>last</item>
<item>late</item>
<item>laugh</item>
<item>lemon</item>
<item>letter</item>
<item>lily</item>
<item>link</item>
<item>list</item>
<item>local</item>
<item>long</item>
<item>madeleine</item>
<item>magazine</item>
<item>make</item>
<item>many</item>
<item>marine</item>
<item>maze</item>
<item>meditate</item>
<item>message</item>
<item>momentum</item>
<item>moon</item>
<item>more</item>
<item>most</item>
<item>mountain</item>
<item>music</item>
<item>name</item>
<item>need</item>
<item>negotiate</item>
<item>news</item>
<item>next</item>
<item>night</item>
<item>north</item>
<item>not</item>
<item>now</item>
<item>number</item>
<item>number</item>
<item>oak</item>
<item>octopus</item>
<item>online</item>
<item>only</item>
<item>opposite</item>
<item>order</item>
<item>other</item>
<item>pack</item>
<item>page</item>
<item>painting</item>
<item>people</item>
<item>pillow</item>
<item>pizza</item>
<item>podcast</item>
<item>polar</item>
<item>policy</item>
<item>post</item>
<item>presentation</item>
<item>price</item>
<item>product</item>
<item>public</item>
<item>puppy</item>
<item>puzzle</item>
<item>quality</item>
<item>quantity</item>
<item>query</item>
<item>quest</item>
<item>question</item>
<item>quick</item>
<item>quince</item>
<item>quite</item>
<item>quotation</item>
<item>read</item>
<item>real</item>
<item>recipe</item>
<item>report</item>
<item>research</item>
<item>restaurant</item>
<item>review</item>
<item>revolve</item>
<item>rewind</item>
<item>right</item>
<item>search</item>
<item>secret</item>
<item>see</item>
<item>seed</item>
<item>service</item>
<item>ship</item>
<item>should</item>
<item>site</item>
<item>skill</item>
<item>stargaze</item>
<item>state</item>
<item>style</item>
<item>sunrise</item>
<item>taxi</item>
<item>tidy</item>
<item>time</item>
<item>together</item>
<item>tourist</item>
<item>trailer</item>
<item>travel</item>
<item>truck</item>
<item>under</item>
<item>unicorn</item>
<item>uniform</item>
<item>unique</item>
<item>united</item>
<item>university</item>
<item>uplife</item>
<item>useful</item>
<item>value</item>
<item>various</item>
<item>vase</item>
<item>version</item>
<item>very</item>
<item>video</item>
<item>view</item>
<item>violin</item>
<item>vision</item>
<item>visit</item>
<item>volume</item>
<item>walrus</item>
<item>wander</item>
<item>well</item>
<item>whirlwind</item>
<item>winter</item>
<item>world</item>
<item>would</item>
<item>xanthin</item>
<item>xenial</item>
<item>xenolith</item>
<item>xenon</item>
<item>xiphoid</item>
<item>yacht</item>
<item>year</item>
<item>yield</item>
<item>yoga</item>
<item>yogurt</item>
<item>young</item>
<item>your</item>
<item>zein</item>
<item>zero</item>
<item>zigzag</item>
<item>zine</item>
<item>zone</item>
<item>zoo</item>
<item>zouk</item>
</string-array>
</resources>
2.2 layout
acitivity_main.xml
用于显示A-Z
<?xml version="1.0" encoding="utf-8"?><!--
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="16dp" />
</FrameLayout>
acitivity_detail.xml
用于显示words
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".DetailActivity">
<!--tools:listitem="@layout/word_item_view"-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="16dp"
android:scrollbars="vertical"
app:layoutManager="GridLayoutManager"
app:spanCount="4"
/>
</FrameLayout>
item_view.xml
用button来显示words和a-z字母,被RecyclerView调用
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:padding="8dp" />
2.3 Code
启动为MainActivity(a-z), letterAdaper 为mainactivity服务,
DetailActivity 是用于显示words的。
都是class
窗口切换使用intent来实现的。
Activity启动过程
Activity的启动过程主要包含以下几个步骤:
- Intent的解析(Intent可能是隐式的:关于Intents and Intent Filters)
- Activity的匹配(符合Intent的Activity可能会有多个)
- 应用进程的创建
- Task,Stack的获取或者创建
- Activity窗口的创建
- Activity生命周期的调度(onCreate,onResume等)
图中activity的说明:
-
LetterAdapter
由MainActivity
中的RecyclerView
使用。每个字母都是一个具有onClickListener
的按钮,该监听器目前为空。您将在此监听器中处理按下按钮的操作,以导航到DetailActivity
。 -
WordAdapter
由DetailActivity
中的RecyclerView
使用,以显示单词列表。尽管您还无法导航到此屏幕,但要知道,每个单词还有一个相应的具有onClickListener
的按钮。您将在此监听器中添加能够导航到浏览器的代码,以便显示相应单词的定义。 -
MainActivity
,您将通过实现选项菜单来显示按钮,从而使用户能够在列表和网格布局之间进行切换。
RecyclerView:
第一次使用会难以理解它的作用,
RecyclerView
不会直接与列表项视图交互,而是处理 ViewHolders
。一个 ViewHolder
代表 RecyclerView
中的一个列表项视图,可根据需要对其重复使用。ViewHolder
实例存储着对列表项布局中各个视图的引用(因此被命名为“view holder”,意思是视图存储器)。
如LetterAdapter 用于显示a-z字母,定义以下的类。
class LetterAdapter :
RecyclerView.Adapter<LetterAdapter.LetterViewHolder>() {
//首先需要什么引用的对象
//由于是要有交互作用,因此使用button来做,这里 就有一个LetterViewHolder,view
参数传入父类构造函数
class LetterViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val button = view.findViewById<Button>(R.id.button_item)
}
}
然后补充如下函数
getItemCount(Int):getItemCount() 方法需要返回数据集的大小。
onCreateViewHolder(parent: ViewGroup, viewType: Int): LetterViewHolder
方法由布局管理器调用,用于为 RecyclerView
创建新的 ViewHolder(如果不存在可重复使用的 ViewHolder)。请注意,一个 ViewHolder 代表一个列表项视图。接受两个参数并返回一个新的 ViewHolder
。
-
parent
参数,即新列表项视图将作为子视图附加到的视图组。父项是RecyclerView
。 -
viewType
参数,当同一个RecyclerView
中存在多种列表项视图类型时,此参数可发挥重要作用。如果在RecyclerView
内显示不同的列表项布局,就会有不同的列表项视图类型。您只能循环使用列表项视图类型相同的视图。针对您的情况而言,只有一个列表项布局和一个列表项视图类型,因此您不必担心此参数。 - 在
onCreateViewHolder()
方法中,从提供的上下文(parent
的context
)中获取LayoutInflater
的实例。布局膨胀器知道如何将 XML 布局膨胀为视图对象的层次结构。 - 获取
LayoutInflater
对象实例后,添加一个句点,后跟另一个方法调用以膨胀实际的列表项视图。传入 XML 布局资源 IDR.layout.list_item
和parent
视图组。第三个布尔值参数是attachToRoot
。此参数需为false
,因为RecyclerView
会在需要的时候替您将此列表项添加到视图层次结构中。
val layout = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_view, parent, false)
onBindViewHolder()
此方法由布局管理器调用,以便替换列表项视图的内容。
onBindViewHolder(holder: LetterViewHolder, position: Int)
有两个参数:其一是先前由 onCreateViewHolder()
方法创建的 LetterViewHolder,其二是一个 int
,它代表当前列表项的 position
。在此方法中,您将根据位置从数据集中找到正确的button对象。
val item = list.get(position)
holder.button.text = item.toString() 返回对应的字符串
由于按键字母或者word都需要转换页面,所以 需要onclick事件,通过该事件的intent实现页面的跳转。
这是个人理解,如果不正确,请大家指正!
把主要的内容说完,直接上代码,比较枯燥。
MainActivity
/*
*
*/
package com.example.wordsapp
import android.content.Context
import android.os.Bundle
import android.os.PersistableBundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.wordsapp.databinding.ActivityMainBinding
var isLinearLayoutManager = true // 在外面可以保存 布局。
/**
* Main Activity and entry point for the app. Displays a RecyclerView of letters.
*/
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
//最好创建一个属性来跟踪应用所处的布局状态。这样可以简化切换布局按钮的操作。将默认值设置为 true,因为系统将默认使用线性布局管理器。
//原始 Activity 实例将触发 onPause()、onStop() 和 onDestroy() 回调。系统将创建新的 Activity 实例,并触发 onCreate()、onStart() 和 onResume() 回调。
//当用户从应用 A 切换到应用 B 时,系统会对应用 A 调用 onPause(),对应用 B 调用 onResume()。每当用户在应用之间切换时,系统就会在这两种方法之间切换。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
recyclerView = binding.recyclerView // binding 调用控件,后面对控件操作 就是 这个变量了。
// Sets the LinearLayoutManager of the recyclerview
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = LetterAdapter() //A to Z
chooseLayout() // 选择布局
//setIcon(item)// 选择icon.
}
//当用户切换按钮时,您需要将项列表转换为项网格。
/**
* 选择布局,将布局变量放在全局变量,返回时可以保持原来的值。
*/
private fun chooseLayout(){
if (isLinearLayoutManager){
recyclerView.layoutManager= LinearLayoutManager(this)
}else{
recyclerView.layoutManager= GridLayoutManager(this,4)
}
recyclerView.adapter= LetterAdapter()
}
/**
* setIcon 就是改变item的图标显示用
* ResourcesCompat 和 ContextCompat 都可设置 图标
*/
private fun setIcon(menuItem:MenuItem?){
if(menuItem==null) return
menuItem.icon=
if(isLinearLayoutManager) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_linear_layout, null); //ContextCompat.getDrawable(this,R.drawable.ic_linear_layout)
else ContextCompat.getDrawable(this,R.drawable.ic_grid_layout)
}
/**
* 如需为 Activity 指定选项菜单,请替换 onCreateOptionsMenu()
*/
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.layout_menu,menu)
val layoutButton = menu?.findItem(R.id.action_switch_layout)// item
setIcon(layoutButton)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when(item.itemId){
R.id.action_switch_layout -> {
// Sets isLinearLayoutManager (a Boolean) to the opposite value
isLinearLayoutManager = !isLinearLayoutManager
// Sets layout and icon
chooseLayout() // 选择布局
setIcon(item)// 选择icon.
return true
}
else -> super.onOptionsItemSelected(item)
}
}
//由于布局管理器和适配器现在是在 chooseLayout() 中设置的,您应替换 onCreate() 中的相应代码以调用新的方法
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
val binding = ActivityMainBinding.inflate(layoutInflater) // 自动生成的layout报错?
setContentView(binding.root)
// Sets the LinearLayoutManager of the recyclerview
chooseLayout()
}
}
LetterAdapter
/*
*/
package com.example.wordsapp
import android.content.Intent
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Button
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
/**
* Adapter for the [RecyclerView] in [MainActivity].
*/
class LetterAdapter :
RecyclerView.Adapter<LetterAdapter.LetterViewHolder>() {
// Generates a [CharRange] from 'A' to 'Z' and converts it to a list
private val list = ('A').rangeTo('Z').toList() //A to z 的列表
/**
* Provides a reference for the views needed to display items in your list.
*/
class LetterViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val button = view.findViewById<Button>(R.id.button_item)
}
override fun getItemCount(): Int {
return list.size
}
/**
* Creates new views with R.layout.item_view as its template
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LetterViewHolder {
val layout = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_view, parent, false)
// Setup custom accessibility delegate to set the text read
layout.accessibilityDelegate = Accessibility
return LetterViewHolder(layout)
}
/**
* Replaces the content of an existing view with new data
*/
override fun onBindViewHolder(holder: LetterViewHolder, position: Int) {
val item = list.get(position)
holder.button.text = item.toString()
holder.button.setOnClickListener {
val context=holder.view.context
// detailAcitivity 在后运行
val intent = Intent(context,DetailActivity::class.java)
//调用 putExtra 方法,并传入“letter”作为第一个参数,传入按钮文本作为第二个参数。
intent.putExtra(DetailActivity.LETTER,holder.button.text.toString())
/**
* 什么是 extra?请记住,intent 只是一组指令,
* 目前还没有目标 activity 的实例。而 extra 是一段数据(例如一个数字或一个字符串),
* 系统会为其指定名称,以便日后检索。这类似于在调用函数时传递参数。
* 由于 DetailActivity 可以针对任何字母显示,您需要告知它显示哪个字母。
*/
//对 context 对象调用 startActivity() 方法,并传入 intent。
context.startActivity(intent) //这里切换到 Detail Activity 了。
}
}
// Setup custom accessibility delegate to set the text read with
// an accessibility service
companion object Accessibility : View.AccessibilityDelegate() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onInitializeAccessibilityNodeInfo(
host: View?,
info: AccessibilityNodeInfo?
) {
super.onInitializeAccessibilityNodeInfo(host, info)
// With `null` as the second argument to [AccessibilityAction], the
// accessibility service announces "double tap to activate".
// If a custom string is provided,
// it announces "double tap to <custom string>".
val customString = host?.context?.getString(R.string.look_up_words)
val customClick =
AccessibilityNodeInfo.AccessibilityAction(
AccessibilityNodeInfo.ACTION_CLICK,
customString
)
info?.addAction(customClick)
}
}
}
DetailActivity
/*
*/
package com.example.wordsapp
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.wordsapp.databinding.ActivityDetailBinding
class DetailActivity : AppCompatActivity() {
companion object {
const val LETTER = "letter"
// you may not has access to google,instead, using bing
val SEARCH_PREFIX = "https://cn.bing.com/search?q=" //"https://www.google.com/search?q="
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Retrieve a binding object that allows you to refer to views by id name
// Names are converted from snake case to camel case.
// For example, a View with the id word_one is referenced as binding.wordOne
val binding =ActivityDetailBinding.inflate(layoutInflater) // no space between = and Activity..
setContentView(binding.root)
// Retrieve the LETTER from the Intent extras
// intent.extras.getString returns String? (String or null)
// so toString() guarantees that the value will be a String
// val letterId = "A"
/**
* intent 属性来自哪里?它不是 DetailActivity 的属性,
* 相反,它可以是任意 activity 的属性。它会保留对用于启动相应 activity 的 intent 的引用。
* extra 属性为 Bundle 类型,它提供了一种访问传入相应 intent 的所有 extra 的方式。
* 为了安全地访问此值,可以在名称后添加“?”。如果 intent 为 null,
* 您的应用甚至不会尝试访问 extra 属性;如果 extras 为 null,您的代码甚至不会尝试调用 getString()。
*/
val letterId=intent?.extras?.getString(LETTER).toString()
val recyclerView = binding.recyclerView
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = WordAdapter(letterId, this) // 调用WordAdapter类,并赋值,怎么不先申明一下?
// WordAdapter 类类有intent切换
// Adds a [DividerItemDecoration] between items
recyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
)
title = getString(R.string.detail_prefix) + " " + letterId
// binding holder
}
}
WordAdapter
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.wordsapp
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Button
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import java.net.URI
/**
* Adapter for the [RecyclerView] in [DetailActivity].
*/
class WordAdapter(private val letterId: String, context: Context) :
RecyclerView.Adapter<WordAdapter.WordViewHolder>() {
private val filteredWords: List<String>
init {
// Retrieve the list of words from res/values/arrays.xml
// 把预定义的参数 转为 list列表 并给words
val words = context.resources.getStringArray(R.array.words).toList()
filteredWords = words //进一步赋值,并用lamda
// Returns items in a collection if the conditional clause is true,
// in this case if an item starts with the given letter,
// ignoring UPPERCASE or lowercase.
.filter { it.startsWith(letterId, ignoreCase = true) }
// Returns a collection that it has shuffled in place
.shuffled()
// Returns the first n items as a [List]
.take(5)
// Returns a sorted version of that [List]
.sorted()
}
class WordViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val button = view.findViewById<Button>(R.id.button_item)
}
override fun getItemCount(): Int = filteredWords.size //列表的数量
/**
* Creates new views with R.layout.item_view as its template
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder {
val layout = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_view, parent, false)
// Setup custom accessibility delegate to set the text read
layout.accessibilityDelegate = Accessibility
return WordViewHolder(layout)
}
/**
* Replaces the content of an existing view with new data
*/
override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
val item = filteredWords[position]
// Needed to call startActivity
val context = holder.view.context
// Set the text of the WordViewHolder
holder.button.text = item
//首先,为搜索查询创建一个 URI。当调用 parse() 以从某个 String 创建 URI 时,您需要使用字符串格式,以便将单词附加到 SEARCH_PREFIX。
holder.button.setOnClickListener {
val qurURL: Uri = Uri.parse("${DetailActivity.SEARCH_PREFIX}${item}")
//定义 queryUrl 后,初始化新的 intent 对象 Intent.ACTION_VIEW 与 URI 一同传入,而不是传入 context 和 activity。
val intent=Intent(Intent.ACTION_VIEW,qurURL)
//即使您不启动应用中的任何特定 activity,您也需要通过调用 startActivity() 并传入 intent 来告知系统启动其他应用。
context.startActivity(intent) // 通过intent 来切换 窗口. 这里会切换到网页窗口
}
}
// Setup custom accessibility delegate to set the text read with
// an accessibility service
companion object Accessibility : View.AccessibilityDelegate() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onInitializeAccessibilityNodeInfo(
host: View?,
info: AccessibilityNodeInfo?
) {
super.onInitializeAccessibilityNodeInfo(host, info)
// With `null` as the second argument to [AccessibilityAction], the
// accessibility service announces "double tap to activate".
// If a custom string is provided,
// it announces "double tap to <custom string>".
val customString = host?.context?.getString(R.string.look_up_word)
val customClick =
AccessibilityNodeInfo.AccessibilityAction(
AccessibilityNodeInfo.ACTION_CLICK,
customString
)
info?.addAction(customClick)
}
}
}
3 Result
可以实现 A-Z字母的导航,显示对应字母开头的words,然后通过bing来显示word的含义。
目前不知道如何调用百度的引擎,查阅words含义。
- 显式 intent 用于导航到应用中的特定 activity。
- 隐式 intent 对应于特定的操作(例如打开链接或共享图片),并让系统来确定执行相应 intent 的方式。
- 借助菜单选项,您可以向应用栏添加按钮和菜单。
- 伴生对象提供了一种将可重复使用的常量与某种类型(而不是该类型的实例)相关联的方式。
执行 intent 的方法如下:
- 获取对 context 的引用。
- 创建一个
Intent
对象,并提供 activity 或 intent 类型(具体取决于是显式还是隐式)。 - 通过调用
putExtra()
传递任何需要的数据。 - 调用
startActivity()
,同时传入intent
对象。