mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
feat: add custom IView implementation for UI Designer
This commit is contained in:
Binary file not shown.
+12
-7
@@ -22,11 +22,12 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.IViewGroup
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex.getAdapter
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex.getAdapter
|
||||
import com.itsaky.androidide.inflater.internal.utils.ViewFactory.generateLayoutParams
|
||||
import com.itsaky.androidide.uidesigner.fragments.DesignerWorkspaceFragment.Companion.DRAGGING_WIDGET_MIME
|
||||
import com.itsaky.androidide.uidesigner.models.UiView
|
||||
import com.itsaky.androidide.uidesigner.models.UiViewGroup
|
||||
import com.itsaky.androidide.uidesigner.models.UiWidget
|
||||
import java.io.File
|
||||
|
||||
@@ -35,10 +36,14 @@ import java.io.File
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class WidgetDragListener(val view: IViewGroup, private val placeholderView: View) :
|
||||
internal class WidgetDragListener(val view: UiViewGroup, private val placeholderView: View) :
|
||||
View.OnDragListener {
|
||||
|
||||
private val placeholder by lazy { ViewImpl(LayoutFile(File(""), ""), "", placeholderView).also { it.includeInIndexComputation = false } }
|
||||
private val placeholder by lazy {
|
||||
UiView(LayoutFile(File(""), ""), "", placeholderView).also {
|
||||
it.includeInIndexComputation = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDrag(v: View, event: DragEvent): Boolean {
|
||||
return when (event.action) {
|
||||
@@ -52,7 +57,7 @@ class WidgetDragListener(val view: IViewGroup, private val placeholderView: View
|
||||
}
|
||||
placeholder.removeFromParent()
|
||||
val state = event.localState
|
||||
if (state is ViewImpl) {
|
||||
if (state is UiView) {
|
||||
state.includeInIndexComputation = false
|
||||
}
|
||||
val index = view.computeViewIndex(event.x, event.y)
|
||||
@@ -71,7 +76,7 @@ class WidgetDragListener(val view: IViewGroup, private val placeholderView: View
|
||||
data
|
||||
}
|
||||
is UiWidget ->
|
||||
data.createView(view.viewGroup.context, (view as ViewImpl).file).apply {
|
||||
data.createView(view.viewGroup.context, view.file).apply {
|
||||
this.view.layoutParams =
|
||||
generateLayoutParams(this@WidgetDragListener.view.viewGroup)
|
||||
val adapter = getAdapter(this.name)
|
||||
@@ -87,7 +92,7 @@ class WidgetDragListener(val view: IViewGroup, private val placeholderView: View
|
||||
this.view.onHighlightStateUpdated(false)
|
||||
|
||||
child.onHighlightStateUpdated(false)
|
||||
if (child is ViewImpl) {
|
||||
if (child is UiView) {
|
||||
child.includeInIndexComputation = true
|
||||
}
|
||||
|
||||
|
||||
+32
-14
@@ -26,18 +26,22 @@ import androidx.fragment.app.viewModels
|
||||
import com.blankj.utilcode.util.SizeUtils
|
||||
import com.itsaky.androidide.fragments.BaseFragment
|
||||
import com.itsaky.androidide.inflater.IInflateEventsListener
|
||||
import com.itsaky.androidide.inflater.IInflationEvent
|
||||
import com.itsaky.androidide.inflater.ILayoutInflater
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.IViewGroup
|
||||
import com.itsaky.androidide.inflater.IViewGroup.SingleOnHierarchyChangeListener
|
||||
import com.itsaky.androidide.inflater.OnInflateViewEvent
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.ViewGroupImpl
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
import com.itsaky.androidide.inflater.viewGroup
|
||||
import com.itsaky.androidide.uidesigner.R
|
||||
import com.itsaky.androidide.uidesigner.UIDesignerActivity
|
||||
import com.itsaky.androidide.uidesigner.databinding.FragmentDesignerWorkspaceBinding
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutDesignerErrorBinding
|
||||
import com.itsaky.androidide.uidesigner.drag.WidgetDragListener
|
||||
import com.itsaky.androidide.uidesigner.models.UiView
|
||||
import com.itsaky.androidide.uidesigner.models.UiViewGroup
|
||||
import com.itsaky.androidide.uidesigner.utils.WidgetTouchListener
|
||||
import com.itsaky.androidide.uidesigner.utils.bgDesignerView
|
||||
import com.itsaky.androidide.uidesigner.utils.layeredForeground
|
||||
@@ -68,7 +72,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
}
|
||||
|
||||
private val workspaceView by lazy {
|
||||
object : ViewGroupImpl(LayoutFile(File(""), ""), "", binding!!.workspace) {}
|
||||
UiViewGroup(LayoutFile(File(""), ""), "", binding!!.workspace)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -79,9 +83,19 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
}
|
||||
|
||||
private val inflateListener by lazy {
|
||||
IInflateEventsListener { event ->
|
||||
if (event is OnInflateViewEvent) {
|
||||
setupView(event.data)
|
||||
object : IInflateEventsListener {
|
||||
override fun onEvent(event: IInflationEvent<*>) {
|
||||
if (event is OnInflateViewEvent) {
|
||||
setupView(event.data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInterceptCreateView(view: IView): IView {
|
||||
view as ViewImpl
|
||||
if (view is IViewGroup) {
|
||||
return UiViewGroup(view.file, view.name, view.viewGroup)
|
||||
}
|
||||
return UiView(view.file, view.name, view.view)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,19 +148,23 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
val fg = view.view.foreground
|
||||
view.view.foreground =
|
||||
if (fg != null) layeredForeground(requireContext(), fg) else bgDesignerView(view.view.context)
|
||||
|
||||
|
||||
if (view is IViewGroup) {
|
||||
view.view.setOnDragListener(WidgetDragListener(view, placeholder))
|
||||
view.addOnHierarchyChangeListener(
|
||||
object : SingleOnHierarchyChangeListener() {
|
||||
override fun onViewAdded(group: IViewGroup, view: IView) {
|
||||
setupView(view)
|
||||
}
|
||||
}
|
||||
)
|
||||
setupViewGroup(view as UiViewGroup)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupViewGroup(viewGroup: UiViewGroup) {
|
||||
viewGroup.view.setOnDragListener(WidgetDragListener(viewGroup, placeholder))
|
||||
viewGroup.addOnHierarchyChangeListener(
|
||||
object : SingleOnHierarchyChangeListener() {
|
||||
override fun onViewAdded(group: IViewGroup, view: IView) {
|
||||
setupView(view as UiView)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun setupFromBundle(bundle: Bundle?) {
|
||||
bundle?.let {
|
||||
val path = it.getString(UIDesignerActivity.EXTRA_FILE) ?: return
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.uidesigner.models
|
||||
|
||||
/**
|
||||
* Extension properties for [UiView] and [UiViewGroup]
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
interface CommonUiView {
|
||||
|
||||
var includeInIndexComputation: Boolean
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.uidesigner.models
|
||||
|
||||
/**
|
||||
* Implementation of [CommonUiView].
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class CommonUiViewImpl : CommonUiView {
|
||||
override var includeInIndexComputation: Boolean = true
|
||||
}
|
||||
+6
-5
@@ -17,14 +17,15 @@
|
||||
|
||||
package com.itsaky.androidide.uidesigner.models
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.view.View
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.SingleChildViewGroup
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
|
||||
/**
|
||||
* Root view includes the inflated XML layout.
|
||||
* Extension of [IView] for the UI Designer.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class RootViewImpl(file: LayoutFile, name: String, view: ViewGroup) :
|
||||
SingleChildViewGroup(file, name, view)
|
||||
internal open class UiView(file: LayoutFile, name: String, view: View) :
|
||||
ViewImpl(file, name, view), CommonUiView by CommonUiViewImpl()
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.uidesigner.models
|
||||
|
||||
import android.graphics.RectF
|
||||
import android.view.ViewGroup
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.IViewGroupAdapter
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.HORIZONTAL
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.TOP_LEFT
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.VERTICAL
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex
|
||||
import com.itsaky.androidide.inflater.internal.ViewGroupImpl
|
||||
|
||||
/**
|
||||
* Extension of [IView] for the UI Designer.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
internal class UiViewGroup(file: LayoutFile, name: String, view: ViewGroup) :
|
||||
ViewGroupImpl(file, name, view), CommonUiView by CommonUiViewImpl() {
|
||||
|
||||
/**
|
||||
* Finds the index of the view based on the touch location.
|
||||
*
|
||||
* @param x The x coordinate.
|
||||
* @param y The y coordinate.
|
||||
* @return The index where the new child should be added. This index must be valid.
|
||||
*/
|
||||
fun computeViewIndex(x: Float, y: Float): Int {
|
||||
if (childCount == 0) {
|
||||
return 0
|
||||
}
|
||||
val adapter =
|
||||
ViewAdapterIndex.getAdapter(name) as? IViewGroupAdapter
|
||||
?: throw IllegalStateException("No view adapter for '$name'")
|
||||
return when (adapter.getLayoutBehavior(this)) {
|
||||
TOP_LEFT -> childCount
|
||||
VERTICAL -> computeViewIndexVertically(x, y)
|
||||
HORIZONTAL -> computeViewIndexHorizontally(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeViewIndexHorizontally(x: Float, y: Float): Int {
|
||||
get(0).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (x < rect.left) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
get(childCount - 1).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (x > rect.right) {
|
||||
return childCount
|
||||
}
|
||||
}
|
||||
val (child, index) = findNearestChild(x, y, false) ?: return childCount
|
||||
val rect = getViewRect(child)
|
||||
val mid = rect.left + (rect.width() / 2)
|
||||
val left = RectF(rect).apply { this.right = mid - 10 }
|
||||
val right = RectF(rect).apply { this.left = mid + 10 }
|
||||
if (x > left.left && x < left.right) {
|
||||
return index - 1
|
||||
}
|
||||
if (x > right.left && x < right.right) {
|
||||
return index + 1
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
private fun computeViewIndexVertically(x: Float, y: Float): Int {
|
||||
get(0).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (y < rect.top) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
get(childCount - 1).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (y > rect.bottom) {
|
||||
return childCount
|
||||
}
|
||||
}
|
||||
val (child, index) = findNearestChild(x, y, true) ?: return childCount
|
||||
val rect = getViewRect(child)
|
||||
val mid = rect.top + (rect.height() / 2)
|
||||
val top = RectF(rect).apply { this.bottom = mid - 10 }
|
||||
val bottom = RectF(rect).apply { this.top = mid + 10 }
|
||||
if (y > top.top && y < top.bottom) {
|
||||
return index - 1
|
||||
}
|
||||
if (y > bottom.top && y < bottom.bottom) {
|
||||
return index + 1
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
private fun findNearestChild(x: Float, y: Float, vertical: Boolean = true): Pair<IView, Int>? {
|
||||
for (i in 0 until childCount) {
|
||||
val child = get(i) as UiView
|
||||
if (!child.includeInIndexComputation) {
|
||||
continue
|
||||
}
|
||||
val rect = getViewRect(child)
|
||||
if (vertical && (y > rect.top && y < rect.bottom)) {
|
||||
return child to i
|
||||
}
|
||||
|
||||
if (!vertical && (x > rect.left && x < rect.right)) {
|
||||
return child to i
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getViewRect(view: IView): RectF {
|
||||
val v = view.view
|
||||
val rect = RectF()
|
||||
rect.left = v.left.toFloat()
|
||||
rect.top = v.top.toFloat()
|
||||
rect.right = rect.left + v.width
|
||||
rect.bottom = rect.top + v.height
|
||||
return rect
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.itsaky.androidide.uidesigner.fragments.DesignerWorkspaceFragment
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class WidgetTouchListener(private val view: IView, context: Context) : OnTouchListener {
|
||||
internal class WidgetTouchListener(private val view: IView, context: Context) : OnTouchListener {
|
||||
|
||||
private var touchedView: View? = null
|
||||
|
||||
|
||||
@@ -24,4 +24,4 @@ import com.itsaky.androidide.inflater.IViewGroup
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class ForwardingViewGroup(val src: IViewGroup) : IViewGroup by src
|
||||
open class ForwardingViewGroup(val src: IViewGroup) : IViewGroup by src
|
||||
|
||||
@@ -87,15 +87,6 @@ interface IViewGroup : IView {
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index of the view based on the touch location.
|
||||
*
|
||||
* @param x The x coordinate.
|
||||
* @param y The y coordinate.
|
||||
* @return The index where the new child should be added. This index must be valid.
|
||||
*/
|
||||
fun computeViewIndex(x: Float, y: Float): Int
|
||||
|
||||
/**
|
||||
* Adds the given hierarchy change listener.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.itsaky.androidide.inflater
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
fun interface IInflateEventsListener {
|
||||
interface IInflateEventsListener {
|
||||
|
||||
/**
|
||||
* Called when an event occurs. The [event] parameter contains more information about the event.
|
||||
@@ -30,6 +30,15 @@ fun interface IInflateEventsListener {
|
||||
* @param event The event.
|
||||
*/
|
||||
fun onEvent(event: IInflationEvent<*>)
|
||||
|
||||
/**
|
||||
* Allows the listener to intercept the view creation event and return view instance of their own.
|
||||
*
|
||||
* @param view The view that was created. The properties of this view is not expected to be
|
||||
* modified (see [OnInflateViewEvent] instead).
|
||||
* @return The view that should replace the [view] instance.
|
||||
*/
|
||||
fun onInterceptCreateView(view: IView): IView = view
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -24,4 +24,4 @@ import com.itsaky.androidide.inflater.IView
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class ForwardingView(val src: IView) : IView by src
|
||||
open class ForwardingView(protected open val src: IView) : IView by src
|
||||
|
||||
+4
-4
@@ -282,10 +282,10 @@ open class LayoutInflaterImpl : ILayoutInflater() {
|
||||
): IView {
|
||||
return try {
|
||||
val v = createViewInstance(widget.qualifiedName, parent.context)
|
||||
if (v is ViewGroup) {
|
||||
return ViewGroupImpl(currentLayoutFile, widget.qualifiedName, v)
|
||||
}
|
||||
return ViewImpl(currentLayoutFile, widget.qualifiedName, v)
|
||||
val view = if (v is ViewGroup) {
|
||||
ViewGroupImpl(currentLayoutFile, widget.qualifiedName, v)
|
||||
} else ViewImpl(currentLayoutFile, widget.qualifiedName, v)
|
||||
return inflationEventListener?.onInterceptCreateView(view) ?: view
|
||||
} catch (err: Throwable) {
|
||||
onCreateUnsupportedView("Unable to create view for widget ${widget.qualifiedName}", parent)
|
||||
}
|
||||
|
||||
@@ -83,93 +83,6 @@ open class ViewGroupImpl(file: LayoutFile, name: String, view: ViewGroup) :
|
||||
}
|
||||
}
|
||||
|
||||
override fun computeViewIndex(x: Float, y: Float): Int {
|
||||
if (childCount == 0) {
|
||||
return 0
|
||||
}
|
||||
val adapter =
|
||||
ViewAdapterIndex.getAdapter(name) as? IViewGroupAdapter
|
||||
?: throw IllegalStateException("No view adapter for '$name'")
|
||||
return when (adapter.getLayoutBehavior(this)) {
|
||||
TOP_LEFT -> childCount
|
||||
VERTICAL -> computeViewIndexVertically(x, y)
|
||||
HORIZONTAL -> computeViewIndexHorizontally(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeViewIndexHorizontally(x: Float, y: Float): Int {
|
||||
get(0).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (x < rect.left) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
get(childCount - 1).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (x > rect.right) {
|
||||
return childCount
|
||||
}
|
||||
}
|
||||
val (child, index) = findNearestChild(x, y, false) ?: return childCount
|
||||
val rect = getViewRect(child)
|
||||
val mid = rect.left + (rect.width() / 2)
|
||||
val left = RectF(rect).apply { this.right = mid - 10 }
|
||||
val right = RectF(rect).apply { this.left = mid + 10 }
|
||||
if (x > left.left && x < left.right) {
|
||||
return index - 1
|
||||
}
|
||||
if (x > right.left && x < right.right) {
|
||||
return index + 1
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
private fun computeViewIndexVertically(x: Float, y: Float): Int {
|
||||
get(0).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (y < rect.top) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
get(childCount - 1).apply {
|
||||
val rect = getViewRect(this)
|
||||
if (y > rect.bottom) {
|
||||
return childCount
|
||||
}
|
||||
}
|
||||
val (child, index) = findNearestChild(x, y, true) ?: return childCount
|
||||
val rect = getViewRect(child)
|
||||
val mid = rect.top + (rect.height() / 2)
|
||||
val top = RectF(rect).apply { this.bottom = mid - 10 }
|
||||
val bottom = RectF(rect).apply { this.top = mid + 10 }
|
||||
if (y > top.top && y < top.bottom) {
|
||||
return index - 1
|
||||
}
|
||||
if (y > bottom.top && y < bottom.bottom) {
|
||||
return index + 1
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
private fun findNearestChild(x: Float, y: Float, vertical: Boolean = true): Pair<IView, Int>? {
|
||||
for (i in 0 until childCount) {
|
||||
val child = get(i) as ViewImpl
|
||||
if (!child.includeInIndexComputation) {
|
||||
continue
|
||||
}
|
||||
val rect = getViewRect(child)
|
||||
if (vertical && (y > rect.top && y < rect.bottom)) {
|
||||
return child to i
|
||||
}
|
||||
|
||||
if (!vertical && (x > rect.left && x < rect.right)) {
|
||||
return child to i
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun addOnHierarchyChangeListener(listener: OnHierarchyChangeListener) {
|
||||
this.hierarchyChangeListeners.add(listener)
|
||||
}
|
||||
@@ -185,26 +98,4 @@ open class ViewGroupImpl(file: LayoutFile, name: String, view: ViewGroup) :
|
||||
protected open fun notifyOnViewRemoved(child: IView) {
|
||||
this.hierarchyChangeListeners.forEach { it.onViewRemoved(this, child) }
|
||||
}
|
||||
|
||||
protected open fun getViewRect(view: IView): RectF {
|
||||
val v = view.view
|
||||
val rect = RectF()
|
||||
rect.left = v.left.toFloat()
|
||||
rect.top = v.top.toFloat()
|
||||
rect.right = rect.left + v.width
|
||||
rect.bottom = rect.top + v.height
|
||||
return rect
|
||||
}
|
||||
|
||||
private fun topHalf(src: RectF): RectF {
|
||||
val result = RectF(src)
|
||||
result.bottom -= result.height() / 2
|
||||
return src
|
||||
}
|
||||
|
||||
private fun bottomHalf(src: RectF): RectF {
|
||||
val result = RectF(src)
|
||||
result.top += result.height() / 2
|
||||
return src
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,6 @@ constructor(
|
||||
|
||||
private var fg: Drawable? = null
|
||||
private var touched: Drawable? = null
|
||||
|
||||
var includeInIndexComputation = true
|
||||
|
||||
internal val attributes = mutableListOf<IAttribute>()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user