我正在android studio中的一个项目上执行特定任务,并且遇到了以下问题。我试图设置一个菜单项的onClick属性,并且要使其按我的意愿工作,我需要访问另一类中的私有函数。我知道这是一个很大的编程禁忌,并消除了整个函数的私有性。
我试图扩展我试图访问其私有方法并在其中定义菜单项功能的类,但是我发现该类是最终的,无法进一步扩展。
我尝试创建该类的实例,该类在定义其他按钮功能的类中需要我的私有功能。我已经成功完成了此操作,但是通过这样做,程序提示我初始化一个引发WeakReference异常的回调函数。我已经得出结论,他的设计是不可能的。
当前,我正在尝试通过同一类中的伴随对象访问私有函数,但是我尝试过的任何方法都没有用。我有办法实现这一目标吗?实现这一点是不可能的,还是没有意义,就像从另一个类访问私有方法一样?
为简化我正在尝试做的事情: 我有一个包含多个项目的菜单栏:搜索项目和配置项目(用于更改样式,大小等),等等。我被要求添加另一个项目,当单击该项目时,它会自动从当前显示的内容中选择一部分文本网络视图。从失败的尝试来看,我开始觉得这样的按钮不属于菜单,应该在其他地方实现。
功能,用于设置项目的onclick事件: (我需要初始化itemBookmark)
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//Log.d(LOG_TAG, "-> onOptionsItemSelected -> " + item.getItemId());
val itemId = item.itemId
if (itemId == android.R.id.home) {
Log.v(LOG_TAG, "-> onOptionsItemSelected -> drawer")
startContentHighlightActivity()
return true
} else if (itemId == R.id.itemSearch) {
Log.v(LOG_TAG, "-> onOptionsItemSelected -> " + item.title)
if (searchUri == null)
return true
val intent = Intent(this, SearchActivity::class.java)
intent.putExtra(SearchActivity.BUNDLE_SPINE_SIZE, spine?.size ?: 0)
intent.putExtra(SearchActivity.BUNDLE_SEARCH_URI, searchUri)
intent.putExtra(SearchAdapter.DATA_BUNDLE, searchAdapterDataBundle)
intent.putExtra(SearchActivity.BUNDLE_SAVE_SEARCH_QUERY, searchQuery)
startActivityForResult(intent, RequestCode.SEARCH.value)
return true
} else if (itemId == R.id.itemConfig) {
Log.v(LOG_TAG, "-> onOptionsItemSelected -> " + item.title)
showConfigBottomSheetDialogFragment()
return true
} else if (itemId == R.id.itemTts) {
Log.v(LOG_TAG, "-> onOptionsItemSelected -> " + item.title)
showMediaController()
return true
} else if (itemId == R.id.itemBookmark) {
// Should be initialized here
return true
}
return super.onOptionsItemSelected(item)
}
我是tryint的另一个类的私有函数可以访问:
private fun computeTextSelectionRect(currentSelectionRect: Rect) {
Log.v(LOG_TAG, "-> computeTextSelectionRect")
val viewportRect = folioActivityCallback.getViewportRect(DisplayUnit.PX)
Log.d(LOG_TAG, "-> viewportRect -> $viewportRect")
if (!Rect.intersects(viewportRect, currentSelectionRect)) {
Log.i(LOG_TAG, "-> currentSelectionRect doesn't intersects viewportRect")
uiHandler.post {
popupWindow.dismiss()
uiHandler.removeCallbacks(isScrollingRunnable)
}
return
}
Log.i(LOG_TAG, "-> currentSelectionRect intersects viewportRect")
if (selectionRect == currentSelectionRect) {
Log.i(
LOG_TAG, "-> setSelectionRect -> currentSelectionRect is equal to previous " +
"selectionRect so no need to computeTextSelectionRect and show popupWindow again"
)
return
}
Log.i(
LOG_TAG, "-> setSelectionRect -> currentSelectionRect is not equal to previous " +
"selectionRect so computeTextSelectionRect and show popupWindow"
)
selectionRect = currentSelectionRect
val aboveSelectionRect = Rect(viewportRect)
aboveSelectionRect.bottom = selectionRect.top - (8 * density).toInt()
val belowSelectionRect = Rect(viewportRect)
belowSelectionRect.top = selectionRect.bottom + handleHeight
//Log.d(LOG_TAG, "-> aboveSelectionRect -> " + aboveSelectionRect);
//Log.d(LOG_TAG, "-> belowSelectionRect -> " + belowSelectionRect);
// Priority to show popupWindow will be as following -
// 1. Show popupWindow below selectionRect, if space available
// 2. Show popupWindow above selectionRect, if space available
// 3. Show popupWindow in the middle of selectionRect
//popupRect initialisation for belowSelectionRect
popupRect.left = viewportRect.left
popupRect.top = belowSelectionRect.top
popupRect.right = popupRect.left + viewTextSelection.measuredWidth
popupRect.bottom = popupRect.top + viewTextSelection.measuredHeight
//Log.d(LOG_TAG, "-> Pre decision popupRect -> " + popupRect);
val popupY: Int
if (belowSelectionRect.contains(popupRect)) {
Log.i(LOG_TAG, "-> show below")
popupY = belowSelectionRect.top
} else {
// popupRect initialisation for aboveSelectionRect
popupRect.top = aboveSelectionRect.top
popupRect.bottom = popupRect.top + viewTextSelection.measuredHeight
if (aboveSelectionRect.contains(popupRect)) {
Log.i(LOG_TAG, "-> show above")
popupY = aboveSelectionRect.bottom - popupRect.height()
} else {
Log.i(LOG_TAG, "-> show in middle")
val popupYDiff = (viewTextSelection.measuredHeight - selectionRect.height()) / 2
popupY = selectionRect.top - popupYDiff
}
}
val popupXDiff = (viewTextSelection.measuredWidth - selectionRect.width()) / 2
val popupX = selectionRect.left - popupXDiff
popupRect.offsetTo(popupX, popupY)
//Log.d(LOG_TAG, "-> Post decision popupRect -> " + popupRect);
// Check if popupRect left side is going outside of the viewportRect
if (popupRect.left < viewportRect.left) {
popupRect.right += 0 - popupRect.left
popupRect.left = 0
}
// Check if popupRect right side is going outside of the viewportRect
if (popupRect.right > viewportRect.right) {
val dx = popupRect.right - viewportRect.right
popupRect.left -= dx
popupRect.right -= dx
}
}