Question about #BindingMethod in this code - android-databinding

Slide title resolving setter I read this slide , but i don't understand BindingMethod, we must write this method any where? or it just explain how stuff work.
I know for exemple we must write write BindingAdapter for some attribue like bellow
<TextView android : text = "#{myVariable}"/>
textView.setText(myVariable);
<ImageView android:src="#{user.image}"/>
imageView.setImageDrawable(user.image);
#BindingMethod(
type = android.widget.ImageView.class,
attribute = "android:src",
method = "setImageDrawable")

I think method 1 is equivalente method 2, so we have choise to write in our java method 1 or method2 <ImageView android:src="#{user.image}"/> // method 1 imageView.setImageDrawable(user.image); // method 2 #BindingMethod( type = android.widget.ImageView.class, attribute = "android:src", method = "setImageDrawable")
But now i want to know when we use #BindingMethod and when we use #BindingAdapter.

Related

Textview won't scroll when using append

I'm trying to get a TextView/ScrollView in Kotlin to scroll to bottom after appending text.
Weird thing is, I have it working perfectly for 1 TextView, however, another (near identical) TextView doesn't work?
So after a while of struggling to find a difference, I finally found ... something ...
I was populating one of them:
textView = text
and the other
textView2.append ( text )
The one using append, would not scroll to bottom, nor would it show the shaded curve for "overScrollmode" (which is set to true).
Obviously, I was using append, because I'm adding a small amount of text, repeatedly.
The other textView, is an "all or nothing" replacement. (in reality, I don't want the latter to scroll down, I actually set it to scroll to 0,0 (top), however, I used it as a test to find this issue :) )
So why does a text view, when using append, not honor/scroll as a result ?
<androidx.cardview.widget.CardView
android:id="#+id/cvMoveHistory"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="5dp"
app:cardBackgroundColor="#025D68"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="#id/cvMoveHint"
app:layout_constraintEnd_toStartOf="#+id/linearLayoutBoardButtons"
app:layout_constraintStart_toEndOf="#+id/frLayGameBoard"
app:layout_constraintTop_toTopOf="parent">
<ScrollView
android:id="#+id/svMoveHistory"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="5dp"
android:fillViewport="true">
<TextView
android:id="#+id/moveHistory"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#939393"
android:fontFamily="monospace"
android:padding="4dp"
android:scrollbars="vertical"
android:text="123) 5e2-5e3 1a1-1a3"
android:textColor="#000000"
android:textSize="11sp" />
</ScrollView>
</androidx.cardview.widget.CardView>
and in code:
-- in onCreate
tvMoveHistory = findViewById ( R.id.moveHistory )
svMoveHistory = findViewById ( R.id.svMoveHistory )
tvMoveHistory.movementMethod = ScrollingMovementMethod()
-- to actually add text
moveHistory.append ( newText )
-- during a central Refresh routine (yes, confirmed it runs via debugger)
svMoveHistory.post {
svMoveHistory.fullScroll(View.FOCUS_DOWN)
}
What's even more strange, I created a new project, minimal with just a few objects in order to re-create the issue.
It behaves perfectly whether I use append, or just straight assign it.
So I'm again baffled as to what's causing the issue ? (ie using append in my current project means no scroll to bottom, using .text = full text means scroll to bottom works).
However, re-testing in another fresh project results in expected behaviour?
Text I'm adding is very simple, no spannable string, no bold/html markup etc.
Just simple line in format of a simple chess-like notation:
12) a5-g6 e3-h7
... etc. (+ CR ie \n at end of line for new line)
I've scoured my logic, I literally don't touch that textView for any reason other than to append a small piece of text. Occassionally (ie new game), I reset it: = ""
but aside from above code, there is nothing else updating/modifying this textview/scrollview ?
Any ideas what I'm missing?

How to pass XML widget id to ViewModel?

The target is when a button clicked, a chart refresh data.
I used MPAndroidChart, data binding layout.
The question is how can I get 'lineChart' from XML widget id?
And I think maybe it is not the right way to achieve this, what is the better way to refresh a chart when a button clicked?
Code in xxxViewModel.class:
fun onButtonClicked() {
// how can I get 'lineChart' from XML widget id?
plotChart(lineChart)
}
fun plotChart(lineChart: LineChart){
//detail code
}
We should not pass the view reference to the view model, this will break the MVVM architecture pattern.
so view will call the viewmodel and perform some action VM and return the data via Live data.
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:onClick="onButtonClicked"
android:paddingEnd="5dp"
android:paddingRight="5dp"
/>
in the above code there is a xml attribute android:onClick. Map the name of the function, which is defined (action for click of button) in the activity/fragment.
fun onButtonClicked() {
viewModel.plotChart(lineChart)
}
in the above method, view will call viewModel to plotChart method to perform action.

Android Spinner text difference

I'm adding two different spinners to my XML layout, one thats filled through an XML file and one thats filled programmatically.
<Spinner
android:id="#+id/spHome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAlignment="textEnd" />
<Spinner
android:id="#+id/spDevice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:entries="#array/spinner_data"
android:textAlignment="textEnd" />
So the one Spinner is filled through this XML file, which goes great and gives a good clear text quality.
<resources>
<string-array name="spinner_data">
<item>Alle apparaten</item>
<item>Light</item>
<item>Door Sensor</item>
<item>Socket</item>
<item>Smart meter</item>
<item>Multi sensor</item>
</string-array>
<string-array name="solo_data">
<item>Hele huis</item>
</string-array>
The other spinner gets filled programmatically, with the following code:
private var roomDtoList: ArrayList<RoomItemDto> = ArrayList()
private var spRoomData : ArrayList<String> = ArrayList<String>()
private fun fillSpRooms(){
spRoomData.clear()
for(item in roomDtoList){
spRoomData.add(item.name)
}
var spAdapter : ArrayAdapter<String> = ArrayAdapter<String>(this.context, R.layout.spinner_drop_layout, R.id.spinnerTextview, spRoomData)
spHome!!.adapter = spAdapter
}
So whenever I fill this spinner with the following code, the filled text looks ugly and has no margin/spacing between every line. Even when I add margin and textStyling into the R.id.spinnerTextview, it won't make the text look clear.
Anyone knows a fix?
Try doing this. Hope this will help.
for(item in roomDtoList){
spRoomData.add(item.name)
}
spHome!!.setOnItemSelectedListener(this)
// Create an ArrayAdapter using a simple spinner layout and languages array
val aa = ArrayAdapter(this, android.R.layout.simple_spinner_item, spRoomData)
// Set layout to use when the list of choices appear
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Set Adapter to Spinner
spHome!!.setAdapter(aa)

Difference between id and data-dojo-id

What is the difference between an id and a data-dojo-id in a dojo tag such as this:
<button id="save" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-event="onClick:save">Save</button>
I try to reference this button to change it's label with:
var myButton = dijit.byId("save");
so that I can change the button label
myButton.set("label", "Add New");
If I use id="save" it works. If I only use data-dojo-id="save" it doesn't work.
I'm fairly new to Dojo so an explanation or tutorial you can point me to would be much appreciated!
data-dojo-id assigns widget into global namespace, i.e. into window object:
<button data-dojo-id="save" data-dojo-type="dijit/form/Button">Save</button>​
so you can access the button directly:
save.set("label", "Add New");
See the difference in action at jsFiddle: http://jsfiddle.net/phusick/7yV56/
EDIT: To answer your questions. I do not use data-dojo-id at all. It pollutes global namespace which is the direct opposite of what the AMD does. Anyway, you can still use something like widgets.save and widgets.rename to minimize the pollution:
<button data-dojo-id="widgets.save" data-dojo-type="dijit/form/Button">Save</button>​
<button data-dojo-id="widgets.rename" data-dojo-type="dijit/form/Button">Rename</button>​
IMO, data-dojo-id is there for progressive enhancement, not for fully-fledged applications.
data-dojo-id just assigns an instance to a variable, so with multiple dijits with the same data-dojo-id the variable will point to the last one assigned (i.e. it'll not be an array).
You can avoid extensive use of registry.byId writing your method to obtain widgets according to your needs. The best way to start is dijit/registy.findWidgets(rootNode, skipNode). Please also note, that dojo/parser.parse(rootNode, options) returns an array of instantiated objects, or more precisely:
Returns a blended object that is an array of the instantiated objects,
but also can include a promise that is resolved with the instantiated
objects. This is done for backwards compatibility. If the parser
auto-requires modules, it will always behave in a promise fashion and
parser.parse().then(function(instances){...}) should be used.
An example of a method I use to assign ContentPane's dijits into its widgets property, which is an object:
_attachTemplateWidgets: function(widgets) {
widgets = widgets || this.getChildren();
for(var each = 0; each < widgets.length; each++) {
var widget = widgets[each];
var attachPoint = widget.params.dojoAttachPoint;
if(attachPoint) {
this.widget[attachPoint] = widget;
}
var children = widget.getChildren();
if(children.length > 0) {
this._attachTemplateWidgets(children);
}
}
}
I put the entire class here: https://gist.github.com/3754324. I use this app.ui._Pane instead of dijit/layout/ContentPane.

Dynamically Created LABEL Element not showing up in XUL application

I'm trying to dynamically create a set of labels in my XUL Runner application. I have an HBox like so:
<hbox class="upload-attachments"></hbox>
If I manually assign a label element to it like so:
<hbox class="upload-attachments"><label value="test" /></hbox>
It works fine. Also, when I query the object in Javascript I can access the test label.
When I try and create new label elements programmatically it fails. This is roughly what I am doing:
var attachments = view.query_first('.upload-attachments');
var label = view.ownerDocument.createElement('label');
label.value = "Some value."
attachments.appendChild(label);
var childCount = attachments.childNodes.length;
The query_first method is just a call to the Sly Query Selector engine and in other cases works fine. The childCount value is updating appropriately, and as I said, I can access and manipulate any labels I manually add to the hbox.
Thanks in advance,
Either append it with the attribute set, or set the property after inserting:
var label = view.ownerDocument.createElement('label');
attachments.appendChild(label);
label.value = "Some value."
-- or --
var label = view.ownerDocument.createElement('label');
label.setAttribute("value", "Some value.");
attachments.appendChild(label);
The reasoning being that, before the element was inserted, the property setters don't work.