Как прослушать onClickEvent пользовательского элемента управления и добавить дополнительную обработку

#android #kotlin

Вопрос:

Я только что создал простое приложение для Android Kotlin для демонстрации составного шаблона в шаблоне дизайна Gang of Four.

Но я не знаю, как прослушивать событие щелчка по объекту, чтобы добавить этот объект в мое выбранное соединение и перемещать в нем объекты. Поэтому я хочу перемещать только выбранные мной графические объекты (красные объекты на изображении ниже).

Функция перемещения правильно работает со всеми компонентами.

Более того, я остановился на том, чтобы сделать градиент рисоваемым.Форма кольца видна программно. Использовал все свойства, такие как thicknessRatio, innerRatio, V. v. Поэтому я делаю это странным образом, устанавливаю контур вокруг овальной формы :))))

Все комментарии о моем коде, чтобы сделать его лучше для демонстрации, приветствуются. Спасибо всем тебе, братан.

Моя активность:

 class MainActivity : AppCompatActivity() {
    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val parent: RelativeLayout = findViewById(R.id.layout)
        val xField: TextInputEditText = findViewById(R.id.x_text)
        val yField: TextInputEditText = findViewById(R.id.y_text)
        val moveButton: Button = findViewById(R.id.move_button)

        var allCompound = CompoundGraphic()
        var selectedCompound = CompoundGraphic()


        var dot = Dot(this, parent, 100, 100)
        dot.draw()
        allCompound.add(dot)

        var circle = Circle(this, parent, 200, 200, 200)
        circle.draw()
        allCompound.add(circle)

        var compound1 = CompoundGraphic()
        compound1.add(Dot(this, parent, 300, 1000))
        compound1.add(Circle(this, parent, 400, 850, 150))
        compound1.draw()
        allCompound.add(compound1)

        moveButton.setOnClickListener {
            val x = xField.text.toString().toIntOrNull() ?: 0
            val y = yField.text.toString().toIntOrNull() ?: 0
            allCompound.move(x, y)
        }
    }
}
 

Мои определения для классов:

 interface Graphic {
    fun move(x: Int, y: Int)
    fun draw()
}

open class Dot(context: Context, val parent: RelativeLayout, var x: Int, var y: Int) :
    View(context), Graphic, View.OnClickListener {

    var isClicked = false

    private val dotDrawable = GradientDrawable()
    private val dotParam = RelativeLayout.LayoutParams(40, 40)

    init {
        setOnClickListener(this)
    }

    override fun draw() {
        dotDrawable.shape = GradientDrawable.OVAL
        dotDrawable.setColor(Color.BLACK)

        this.background = dotDrawable

        dotParam.leftMargin = x
        dotParam.topMargin = y

        parent.addView(this, dotParam)
    }

    override fun move(x: Int, y: Int) {
        this.x  = x
        this.y  = y
        dotParam.leftMargin = this.x
        dotParam.topMargin = this.y
        parent.removeView(this)
        parent.addView(this, dotParam)
    }

    override fun onClick(v: View?) {
        when (isClicked) {
            false -> {
                dotDrawable.setColor(Color.RED)
            }
            else -> {
                dotDrawable.setColor(Color.BLACK)
            }
        }
        isClicked = !isClicked
    }
}

class Circle(context: Context, parent: RelativeLayout, x: Int, y: Int, var radius: Int) :
    Dot(context, parent, x, y) {

    private val circleDrawable = GradientDrawable()
    private val circleParam = RelativeLayout.LayoutParams(radius * 2, radius * 2)

    override fun draw() {
        circleDrawable.shape = GradientDrawable.OVAL
        circleDrawable.setColor(Color.WHITE)
        circleDrawable.setStroke(20, Color.BLACK)

        this.background = circleDrawable

        circleParam.leftMargin = x
        circleParam.topMargin = y

        parent.addView(this, circleParam)
    }

    override fun move(x: Int, y: Int) {
        this.x  = x
        this.y  = y
        circleParam.leftMargin = this.x
        circleParam.topMargin = this.y
        parent.removeView(this)
        parent.addView(this, circleParam)
    }

    override fun onClick(v: View?) {
        when (isClicked) {
            false -> {
                circleDrawable.setStroke(20, Color.RED)
            }
            else -> {
                circleDrawable.setStroke(20, Color.BLACK)
            }
        }
        isClicked = !isClicked
    }
}

class CompoundGraphic : Graphic {
    var children: MutableList<Graphic> = mutableListOf()

    fun add(child: Graphic) {
        children.add(child)
    }

    fun remove(child: Graphic) {
        children.remove(child)
    }

    override fun draw() {
        children.forEach {
            it.draw()
        }
    }

    override fun move(x: Int, y: Int) {
        children.forEach {
            it.move(x, y)
        }
    }
}
 

Мое изображение приложения

Комментарии:

1. Ооо! Я просто следую Псевдокоду в рефакторинге.гуру. Клиентский код, к которому они обращаются, — это ImageEditor. У меня есть знания только о приложении для Android, поэтому я включил его в свой CompoundGraphic. Кажется неловким ^^. У вас есть какие-нибудь подсказки для меня о композиции ? Спасибо.

2. Я только что отредактировал чей-то комментарий по ошибке. Извини за этого братана …