安卓校园六层导航项目activity_image_display空白问题求助
校园导航项目中activity_image_display页面空白排查与修复
我正在开发一个校园导航项目,针对六层单楼层设置了13个闭环结构的点位。通过获取用户输入的当前位置和目的地,采用A*算法寻找最短路径,并仿谷歌街景以图片形式引导用户。但运行应用时,activity_image_display页面完全空白,无法排查原因。以下是相关代码:
Main Activity
package com.example.collegeroamer import android.content.Intent import android.os.Bundle import android.widget.ImageButton import android.widget.Spinner import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var navigateButton: ImageButton private lateinit var currentLocationSpinner: Spinner private lateinit var destinationSpinner: Spinner override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navigateButton = findViewById(R.id.navigateButton) currentLocationSpinner = findViewById(R.id.currentLocationSpinner) destinationSpinner = findViewById(R.id.destinationSpinner) navigateButton.setOnClickListener { val startingLocation = currentLocationSpinner.selectedItem.toString() val destination = destinationSpinner.selectedItem.toString() val intent = Intent(this, NavigationDisplayActivity::class.java) intent.putExtra("starting_location", startingLocation) intent.putExtra("destination", destination) startActivity(intent) } } }
NavigationDisplayActivity.kt
package com.example.collegeroamer import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.* import java.util.* import kotlin.collections.HashMap import kotlin.coroutines.CoroutineContext class NavigationDisplayActivity : AppCompatActivity(), CoroutineScope { private lateinit var job: Job override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job private lateinit var pathImageView: ImageView // 点位与对应图片的映射 private val locationImages = mapOf( "Class 601" to R.drawable.sixthfloor_class601, "Class 602" to R.drawable.sixthfloor_class602, "Class 603" to R.drawable.sixthfloor_class603, "Class 604" to R.drawable.sixthfloor_class604, "Class 605" to R.drawable.sixthfloor_class605, "Class 606" to R.drawable.sixthfloor_class606, "Class 607" to R.drawable.sixthfloor_class607, "Class 608" to R.drawable.sixthfloor_class608, "Class 609" to R.drawable.sixthfloor_class609, "Class 610" to R.drawable.sixthfloor_class610, "Class 611" to R.drawable.sixthfloor_class611, "Class 612" to R.drawable.sixthfloor_class612, "NSS Unit and DLLE Room" to R.drawable.sixthfloor_nssroom ) // 点位连接关系表 private val adjacencyList = mapOf( "Class 601" to listOf("Class 602"), "Class 602" to listOf("Class 601", "Class 603"), "Class 603" to listOf("Class 602", "Class 604"), "Class 604" to listOf("Class 603", "Class 605"), "Class 605" to listOf("Class 604", "Class 606"), "Class 606" to listOf("Class 605", "NSS Unit and DLLE Room"), "NSS Unit and DLLE Room" to listOf("Class 606", "Class 607"), "Class 607" to listOf("NSS Unit and DLLE Room", "Class 608"), "Class 608" to listOf("Class 607", "Class 609"), "Class 609" to listOf("Class 608", "Class 610"), "Class 610" to listOf("Class 609", "Class 611"), "Class 611" to listOf("Class 610", "Class 612"), "Class 612" to listOf("Class 611", "Class 601") ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_image_display) job = Job() pathImageView = findViewById(R.id.pathImageView) val startingLocation = intent.getStringExtra("starting_location") ?: "" val destination = intent.getStringExtra("destination") ?: "" launch { val shortestPath = findShortestPath(startingLocation, destination) displayPathImages(shortestPath) } } override fun onDestroy() { super.onDestroy() job.cancel() } private suspend fun findShortestPath( startingPoint: String, destinationPoint: String ): List<String> = withContext(Dispatchers.Default) { val queue = PriorityQueue<Node>() val visited = mutableSetOf<String>() val parentMap = HashMap<String, String>() queue.add(Node(startingPoint, 0)) while (queue.isNotEmpty()) { val current = queue.poll() if (current.location == destinationPoint) { // 重构路径 val path = mutableListOf<String>() var node = current.location while (node != startingPoint) { path.add(node) node = parentMap[node] ?: break } path.add(startingPoint) return@withContext path.reversed() } if (current.location !in visited) { visited.add(current.location) for (neighbor in adjacencyList[current.location] ?: emptyList()) { if (neighbor !in visited) { val cost = current.cost + 1 // 每步成本设为1 queue.add(Node(neighbor, cost)) parentMap[neighbor] = current.location } } } } return@withContext emptyList() } private fun displayPathImages(path: List<String>) { // 获取路径对应图片ID列表 val imageIds = path.map { locationImages[it] ?: 0 } // 注释掉了实际加载图片的代码 // Example: pathImageView.setImageResource(imageIds.firstOrNull() ?: 0) } private data class Node(val location: String, val cost: Int) : Comparable<Node> { override fun compareTo(other: Node): Int = cost.compareTo(other.cost) } }
问题排查与修复方案
1. 核心问题:图片加载逻辑未生效
displayPathImages方法仅生成了图片ID列表,但关键的setImageResource代码被注释,导致ImageView没有加载任何内容,页面空白。
修复代码:
private fun displayPathImages(path: List<String>) { if (path.isEmpty()) { // 路径为空时可显示提示文本或默认图 return } // 加载路径中第一个点位的图片,若需要轮播可添加定时器逻辑 val targetImageId = locationImages[path.first()] ?: 0 if (targetImageId != 0) { pathImageView.setImageResource(targetImageId) } }
2. A*算法实现修正
当前代码实际是Dijkstra算法,缺少A核心的启发式函数。若要实现真正的A,需添加启发函数(比如曼哈顿距离,需先定义各点位坐标):
// 定义各点位坐标(示例) private val locationCoordinates = mapOf( "Class 601" to Pair(0,0), "Class 602" to Pair(1,0), "Class 603" to Pair(2,0), "Class 604" to Pair(3,0), "Class 605" to Pair(4,0), "Class 606" to Pair(5,0), "NSS Unit and DLLE Room" to Pair(6,0), "Class 607" to Pair(7,0), "Class 608" to Pair(8,0), "Class 609" to Pair(9,0), "Class 610" to Pair(10,0), "Class 611" to Pair(11,0), "Class 612" to Pair(12,0) ) // 曼哈顿距离启发函数 private fun heuristic(current: String, target: String): Int { val (x1, y1) = locationCoordinates[current] ?: Pair(0,0) val (x2, y2) = locationCoordinates[target] ?: Pair(0,0) return Math.abs(x1 - x2) + Math.abs(y1 - y2) } // 修改findShortestPath中的入队逻辑 queue.add(Node(neighbor, cost + heuristic(neighbor, destinationPoint)))
3. 空路径与异常处理
当起点终点相同、路径查找失败时,findShortestPath会返回空列表,需在displayPathImages中处理该场景,避免页面无内容。
4. 资源文件校验
确认locationImages中对应的R.drawable.xxx资源文件存在于res/drawable目录,文件名和大小写完全匹配,否则会因资源找不到导致ImageView空白。
5. 协程初始化优化
将job = Job()移至setContentView之前,避免潜在的协程初始化异常:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) job = Job() setContentView(R.layout.activity_image_display) // 后续代码... }
内容的提问来源于stack exchange,提问作者Bhushan Savaratkar
相关产品推荐
相关产品推荐

