将触摸事件从对话框片段传递到右下方的视图(在父级 activity 内)
Pass touch event from dialog fragment to View right below (inside the parent activity)
如图所示,红色边框矩形是父级 activity。蓝色的是对话片段。圆圈表示视图,下面的矩形是描述。我希望将圆圈上的点击传递给按钮。到目前为止我已经试过了
1. 覆盖 Circle View 中的 onTouchEvent 和 return false
2. 在圆形视图上设置OntouchListener 并调用activity.dispatchTouchListener 和return false
3. 将dialog frgament和circle view标记为clickable/focusable false.
上面的 None 似乎在调用下面按钮的 onCLickListener 。不过,我可以看到在 Activity 的 onIterceptTouch() 中收到了触摸事件。请帮助
Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val viewTreeObserver = button2.viewTreeObserver
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {MainFragment.newInstance(button2).show(supportFragmentManager, "dialog")
button1.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
container.setOnClickListener {
Log.d("Test","Activity clicked")
}
button.setOnClickListener {
Log.d("Test","Button Clicked")
}
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
Log.d("Test","Activity onTouchEvent")
return super.onTouchEvent(event)
}
}
对话框片段
class MainFragment : DialogFragment() {
companion object {
fun newInstance(view: View?) : MainFragment {
val args = Bundle()
val point = getRippleLocation(getViewCenterLocation(view))
args.putInt("X", point.x)
args.putInt("Y", point.y)
val frag = MainFragment()
frag.arguments = args
return frag
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
dialog.window!!.setGravity(Gravity.START or Gravity.TOP)
point.x = arguments!!.getInt("X")
point.y = arguments!!.getInt("Y")
params.x = point.x
params.y = (point.y - 50)
dialog.window!!.attributes = params
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
addRippleView(main, 0, 0)
}
private fun addCircleView(rootView: ViewGroup, leftMargin: Int, topMargin: Int) {
val rippleView = BaseCircleView(context, null)
rippleView.isClickable = false
rippleView.isFocusable = false
rippleView.setOnTouchListener(object : View.OnTouchListener{
override fun onTouch(p0: View?, p1: MotionEvent?): Boolean {
activity!!.dispatchTouchEvent(p1)
return false
}
})
configureRipple(rippleView)
context?.resources?.let { resources ->
rippleView.id = R.id.gather_ripple_view_id
val params = RelativeLayout.LayoutParams(resources.getDimensionPixelSize(R.dimen.gather_on_boarding_ripple_container_width),
resources.getDimensionPixelSize(R.dimen.gather_on_boarding_ripple_container_height))
params.leftMargin = leftMargin
params.topMargin = topMargin
rootView.addView(rippleView, params)
}
}
}
如果有人还在为此苦苦挣扎,这就是解决方法。
dialog?.window?.decorView?.setOnTouchListener { v, event ->
activity?.dispatchTouchEvent(event)
false
}
这将通过
传递触摸事件
设置 FLAG_NOT_TOUCH_MODAL 对我有用。
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
如图所示,红色边框矩形是父级 activity。蓝色的是对话片段。圆圈表示视图,下面的矩形是描述。我希望将圆圈上的点击传递给按钮。到目前为止我已经试过了 1. 覆盖 Circle View 中的 onTouchEvent 和 return false 2. 在圆形视图上设置OntouchListener 并调用activity.dispatchTouchListener 和return false 3. 将dialog frgament和circle view标记为clickable/focusable false.
上面的None 似乎在调用下面按钮的 onCLickListener 。不过,我可以看到在 Activity 的 onIterceptTouch() 中收到了触摸事件。请帮助
Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val viewTreeObserver = button2.viewTreeObserver
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {MainFragment.newInstance(button2).show(supportFragmentManager, "dialog")
button1.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
container.setOnClickListener {
Log.d("Test","Activity clicked")
}
button.setOnClickListener {
Log.d("Test","Button Clicked")
}
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
Log.d("Test","Activity onTouchEvent")
return super.onTouchEvent(event)
}
}
对话框片段
class MainFragment : DialogFragment() {
companion object {
fun newInstance(view: View?) : MainFragment {
val args = Bundle()
val point = getRippleLocation(getViewCenterLocation(view))
args.putInt("X", point.x)
args.putInt("Y", point.y)
val frag = MainFragment()
frag.arguments = args
return frag
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
dialog.window!!.setGravity(Gravity.START or Gravity.TOP)
point.x = arguments!!.getInt("X")
point.y = arguments!!.getInt("Y")
params.x = point.x
params.y = (point.y - 50)
dialog.window!!.attributes = params
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
addRippleView(main, 0, 0)
}
private fun addCircleView(rootView: ViewGroup, leftMargin: Int, topMargin: Int) {
val rippleView = BaseCircleView(context, null)
rippleView.isClickable = false
rippleView.isFocusable = false
rippleView.setOnTouchListener(object : View.OnTouchListener{
override fun onTouch(p0: View?, p1: MotionEvent?): Boolean {
activity!!.dispatchTouchEvent(p1)
return false
}
})
configureRipple(rippleView)
context?.resources?.let { resources ->
rippleView.id = R.id.gather_ripple_view_id
val params = RelativeLayout.LayoutParams(resources.getDimensionPixelSize(R.dimen.gather_on_boarding_ripple_container_width),
resources.getDimensionPixelSize(R.dimen.gather_on_boarding_ripple_container_height))
params.leftMargin = leftMargin
params.topMargin = topMargin
rootView.addView(rippleView, params)
}
}
}
如果有人还在为此苦苦挣扎,这就是解决方法。
dialog?.window?.decorView?.setOnTouchListener { v, event ->
activity?.dispatchTouchEvent(event)
false
}
这将通过
传递触摸事件设置 FLAG_NOT_TOUCH_MODAL 对我有用。
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);