userRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/userRecyclerView"/>
I saw a code tutorial video. When he used "userRecyclerview", it says "userRecyclerview" comes from the second code I post above. But it did not come out when I write "userRecyclerview", also there is a Unresolved reference problem.
Seems like they're using Kotlin synthetics to bind the view.
Kotlin synthetics will generate some extra code that will allow you to access views in the layout XML, just as if they were properties with the name of the id you used in the layout definition.
But it has been deprecated already. So to access your views either use findViewById() or replace Kotlin synthetics
with Jetpack view binding following this: https://developer.android.com/topic/libraries/view-binding/migration
Related
I am following a tutorial exactly. I gave the view a name in the layout XML file under android:id. When I type that name in Kotlin, it is highlighted in red and there is an "unresolved reference" error.
For example, in XML activity_main.xml:
<TextView
android:id="#+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
In Kotlin MainActivity.kt:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
nameTextView // <-- This is highlighted red with error so I can't use it!
}
I created this question because I've seen variations of it several times since the deprecation of Kotlin Android Extensions, but they are all phrased in various ways and are not very searchable. I think the common factor is a new Android programmer following a tutorial that was written before the deprecation. These tutorials generally don't specify that the feature being used is called synthetic properties or Kotlin Android Extensions, synthetic view properties, or kotlin-android-extensions, and that the feature is deprecated.
The ability to refer to a view directly by it's ID/name in Kotlin is called "synthetic properties" and it is a feature of a project plugin called Kotlin Android Extensions.
Google and JetBrains decided to deprecate Kotlin Android Extensions, meaning they no longer support it, and discourage you from using it. Ever since it was deprecated, when you create a new project in Android Studio, the plugin is no longer included in the new project. Therefore, synthetic properties are not supported in new projects and you will get an "unresolved reference" error if you try to use it.
Tutorials written between 2017 and 2020 often make use of this feature, and if they haven't been updated, they probably don't even mention it by name, because it was taken for granted to be an included plugin in new projects.
Google explained the reasons for deprecating it in this blog post, with these key reasons:
They pollute the global namespace
They don’t expose nullability information
They only work in Kotlin code
The quick and easy way to get your view reference is to use findViewById. The type of View should go inside the brackets <>. In an Activity, it looks like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val nameTextView = findViewById<TextView>(R.id.nameTextView)
// Now you can refer to the view using the variable
nameTextView.setText(R.string.hello_world)
}
In a Fragment, you would probably be working with the view in the onViewCreated function, so you must call findViewById on the parent view. (If you need to access it elsewhere in the Fragment, use requireView() instead of view.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val nameTextView = view.findViewById<TextView>(R.id.nameTextView)
//...
}
findViewById is probably the best option for now if you just want to complete your tutorial that was written before Kotlin Android Extensions was deprecated.
However, using findViewById can be tedious, and it is also error prone, because it won't warn you if you are searching for a view that isn't in the current layout. If you do, it will crash at runtime. For this reason, Google recommends using View Binding. There are a few steps to get started with view binding, but once you set it up, it is a cleaner option than findViewById. The official instructions are here.
Finally, if you really don't care that Kotlin Android Extensions is deprecated and want to use it anyway, it currently still works OK, but you have to add the plugin to your new project to enable it. (Beware this will no longer work in Kotlin 1.8 and up.) To do that, open the build.gradle file for your app module. At the top in the plugins block, you can add a line for kotlin-android-extensions, like this:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
Then press the "Sync project with Gradle files" button in the toolbar to enable it.
You can't directly access the view ids.
But you can use:
Jetpack as Kotlin Android Extensions are deprecated. Source Kotlin Android Extensions Deprection
You can use view binding. View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module.
Source: View Binding
I want to implement this type of sliding selection list in my kotlin based android studio app. but, I don't know what actually it is. so, plz help me
Its Called Spinner
In Xml File implement like this
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Follow this link for more details
https://www.geeksforgeeks.org/spinner-in-kotlin/
An app uses ExpandableListActivity, and the usage of ExpandableListView is standard based on the document:
<ExpandableListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:divider="#android:color/transparent"
android:dividerHeight="5dip"
android:layout_marginTop="10dip">
</ExpandableListView>
Android Studio 3.2 has the following warning:
How can I get rid of the warning?
This is probably a typo. Change it to:
"#android:id/empty"
and
"#android:id/list"
See also https://developer.android.com/reference/android/app/ListActivity
ListActivity has a default layout that consists of a single,
full-screen list in the center of the screen. However, if you desire,
you can customize the screen layout by setting your own view layout
with setContentView() in onCreate(). To do this, your own view MUST
contain a ListView object with the id "#android:id/list" (or R.id.list
if it's in code)
I don't know what is ( id="#id/android:list")
give it an normal id ( #+id/androidlist )
and handle it in your code
but if you learn how to work with ExpandableListView
I prefer this link tutorial for you ExpandableListView Link
GL sir
I am new to MVVMCross (and mobile in general) and I am looking to implement binding to error messages (like FluentValidation ValidationResults or IDataErrorInfo).
Preferably, I would like an Errors like dictionary that I can bind directly to:
bind(label).To(vm => vm.Errors["Name"])
I have tried an ObservableDictionary (http://blogs.microsoft.co.il/blogs/shimmy/archive/2010/12/26/observabledictionary-lt-tkey-tvalue-gt-c.aspx), but I am not getting notified when the ViewModel adds errors.
As expected, wrapping access as a property in the view model works, but could get cumbersome:
public string NameError { get { return Errors.ContainsKey("Name") ? Errors["Name"] : null; } }
I have also considered creating a custom binding, but am not sure how to get access to the ViewModel and pass the field name I want. Seems like I could pass Errors or the property name.
Finally, since invalid conversions (i,e. 22ab for an int) are not pushed down into the view model, is there a way to get those errors? Should I be validating before data gets pushed back to the view model instead? Like textFieldShouldEndEditing or ShouldChangeCharacters on iOS? I could wrap a custom control if necessary.
What techniques are others using with Xamarin/MVVMCross using to provide validation feedback?
Thanks in advance.
MvvmCross doesn't currently implement the IDataErrorInfo level of data-binding
This is mainly because no-one has yet asked for it - but I guess that might just change with this question. If you do have specific requirements, then the project would be interested to hear them - suspect the best place for that is github issues for the project.
For your specific questions...
The approach of binding to an ObservableDictionary which implements the INotifyCollectionChanged and INotifyPropertyChanged should work.
However, looking at the code in your link, I don't think that dictionary is correctly implementing INotifyPropertyChanged - in addition to the INotifyCollectionChanged events, it should also be raising the property change notifications on Count and Item[] - without these the binding to the whole set will work, but not to individual items and to count. For an example source of ObservableCollection, see https://github.com/mosa/Mono-Class-Libraries/blob/master/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs
Looking a second time at the code in your link, it appears that the dictionary is correctly implementing INotifyPropertyChanged - it is raising the property change notifications Item[] - and this is the string required for the individual items to bind. Do you have debug trace enabled? Does the trace give you any clue about why it is failing?
I've submitted some fixes today - https://github.com/slodge/MvvmCross/issues/345 - and have tested them in this sample - Test_WithErrors.axml - I would expect this same sample should work on iOS (the iOS test app is a work in progress) and that it should also be extensible for Jeremy's excellent FluentValidation (although I've not used that in PCL form yet)
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter email:"
/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
local:MvxBind="Text Email"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff0000"
local:MvxBind="Text Errors['Email']"
/>
Thanks for pointing out this error - fixed binaries will be nuget in the next day or two!
On the int-string question, the binding layer currently "does it's best" (TM) to convert UI types to VM types. However, there is no event currently triggered when it fails - so there is no way to fire any validation rules in the ViewModel from the binding.
Instead, where free text input is allowed, I think you'll need to implement the ViewModel types as string and will then need to trigger the validation rules when the ViewModel property changes. Because MvvmCross doesn't expose any binding level hooks for when validation occurs, you'll maybe need to tweak when binding occurs (e.g. on first responder resign) rather than having continual validation - but this should be fairly straight-forward using a custom-binding.
Per the question here,
What's "tools:context" in Android layout files?
The 'tools' namespace reference (xmlns:tools="http://schemas.android.com/tools") has begun to appear in my layouts recently, and I want to know more. The original post only described the 'tools:context' attribute, but I have also noticed usage of the "tools:listitem" attribute appearing when I have designated a preview layout item for a listview, i.e.
<ListView
android:id="#+id/lvCustomer"
tools:listitem="#layout/customer_list_item" >
</ListView>
Are there more elements?
What brought me to this 'tools' namespace is that I want to be able to have 'preview-only' text (i.e. in a TextView or EditText) when using the layout designer in eclipse.
Currently, I assign the 'text' or 'hint' property for previewing text when arranging my layouts... but then I always have to remember to clear the preview value from within the code.
Ideally, instead of
<string name="preview_customer_name">Billy Bob's Roadhouse Pub</string>
...
<TextView
android:id="#+id/tvCustomerName"
android:text="#string/preview_customer_name"
</TextView>
have a something like:
<TextView
android:id="#+id/tvCustomerName"
tools:previewText="#string/preview_customer_name"
</TextView>
Thanks-
We've just added support for designtime attributes like this in Android Studio 0.2.11. See http://tools.android.com/tips/layout-designtime-attributes for more.
Think of them as design time helpers only.They do not get processed in actual view rendering at run time.
For example you want to set background of some view in your layout design when working on android studio so that you can make clear distinction where that particular view is.So you would normally do that with
android:background="#color/<some-color>"
Now risk is that sometimes we forget to remove that color and it gets shipped in apk.
instead you can do as follows:
tools:background="#color/<some-color>"
These changes will be local to android studio and will never get transferred to apk.
And also check out http://tools.android.com/tech-docs/tools-attributes for more options.
You will find tool attribute when you set object in graphical layout.
Listview (in graphical mode) -> right Click -> Preview List Content -> Choose Layout...
produces:
tools:listitem="#layout/customer_list_item"
See in layout XML below. There are 2 namespace in use "xmlns:android" and "xmlns:tools".
Tools namespace is used when the developer wants to define placeholder content that is only used in preview or in design time. Tools namespace is removed when we compiled the app.
So in the code below, I want to show the placeholder image (image_empty) that will only be visible at design time, and image1 will the actual image that will be shown when the application launch