Currently in Beagle, the component TextInput has the behavior of executing an action list. To do this, it exposes the onChange
property, which receives the list of actions that will be triggered.
In this tutorial you will see how to create a custom widget with the behavior of triggering a list of actions, then we will create DatePicker
, a date selection component.
You will inherit from TextView
and DatePickerDialog.OnDateSetListener
.
class DatePickerComponent(
context: Context
) : TextView(context), DatePickerDialog.OnDateSetListener {
private val myCalendar: Calendar = Calendar.getInstance()
var dateSetListener: DateSetListener? = null
init {
this.setOnClickListener {
DatePickerDialog(context, this, myCalendar
.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
myCalendar.get(Calendar.DAY_OF_MONTH)).show()
}
}
fun setText(text: String) {
this.text = text
}
private fun Date.formatDate(): String{
val myFormat = "yyyy-MM-dd"
val simpleDateFormat = SimpleDateFormat(myFormat, Locale.US)
return simpleDateFormat.format(this).toString()
}
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
myCalendar[Calendar.YEAR] = year
myCalendar[Calendar.MONTH] = month
myCalendar[Calendar.DAY_OF_MONTH] = dayOfMonth
dateSetListener?.onDateSet(myCalendar.time.formatDate())
}
}
interface DateSetListener{
fun onDateSet(value: String)
}
As you can see, there are some methods in class, see below the explanation:
In the init method is the click configuration. When the user clicks on the text, it will display a calendar to select the date.
init {
this.setOnClickListener {
DatePickerDialog(context, this, myCalendar
.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
myCalendar.get(Calendar.DAY_OF_MONTH)).show()
}
}
The setText
method is responsible for displaying the text for the user to click. For example: click here to select a date
.
fun setText(text: String) {
this.text = text
}
The next method is an extension function responsible for formatting the date.
private fun Date.formatDate(): String{
val myFormat = "yyyy-MM-dd"
val simpleDateFormat = SimpleDateFormat(myFormat, Locale.US)
return simpleDateFormat.format(this).toString()
}
This method came from the DatePickerDialog.OnDateSetListener interface and it is responsible for taking the date selected by the user.
dateSetListener?.onDateSet(myCalendar.time.formatDate())
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
myCalendar[Calendar.YEAR] = year
myCalendar[Calendar.MONTH] = month
myCalendar[Calendar.DAY_OF_MONTH] = dayOfMonth
dateSetListener?.onDateSet(myCalendar.time.formatDate())
}
Create a subclass of WidgetView and put the@RegisterWidget
.
buildView
method that came from the WidgetView ()
classdate
this attribute responsible for presenting the value of the selected date.onChange
this attribute responsible for taking the selected date value.@RegisterWidget
class DatePicker(
val date: Bind<String>,
val onChange: List<Action>
) : WidgetView() {
override fun buildView(rootView: RootView) = DatePickerComponent(rootView.getContext()).apply {
observeBindChanges(rootView, this, date) { text ->
text?.let { setText(it) }
}
dateSetListener = object : DateSetListener {
override fun onDateSet(value: String) {
this@DatePicker.handleEvent(
rootView,
this@apply,
onChange,
ContextData(
id = "onChange",
value = value
)
)
}
}
}
}
This block of code looks at the date attribute, and when you change the value, it adds the new value.
observeBindChanges(rootView, this, date) { text ->
text?.let { setText(it) }
}
This code block has the interface of our component, where it overrides the onDateSet
method that contains the value of the date selected by the user. Through this value you will create a ContextData with id onChange and the value will be the value returned by the interface method.
@{onChange}
. In the Step below we will see how to get this value from onChange.dateSetListener = object : DateSetListener {
override fun onDateSet(value: String) {
this@DatePicker.handleEvent(
rootView,
this@apply,
onChange,
ContextData(
id = "onChange",
value = value
)
)
}
}
Using the declarative kotlin of Beagle you will create a screen, where the DatePicker component will be added and below you will see a text.
Below is an example using the component:
Container(
context = ContextData(
id = "ctx",
value = "Escolha uma data"
),
children = listOf(
DatePicker(
date = expressionOf("@{ctx}"),
onChange = listOf(
SetContext(
contextId = "ctx",
value = "@{onChange}"
)
)
),
Text(text = expressionOf("@{ctx}"))
)
)
Check out an example on the emulator:
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.