Android Studio with Kotlin How Does Control Pass From MainActivity to Another Class - android-studio

I'm using android studio 4.1.1 and kotlin.
I'm trying to learn programming Android apps using Android Studio and Kotlin. I have a question that a couple of tutorials and searching threads have not answered for me. How does control pass from the MainActivity.kt class to another class, i.e: FirstFragment.kt?
I'm doing fine with other things I'm learning in tutorials, but I cannot figure this out.
Example:
I create a new Basic Activity app in Android Studio with Kotlin. In the java directory, I see these classes: FirstFragment.kt, MainActivity.kt and SecondFragment.kt.
In the res/layout/ directory, I see: activity_main.xml, content_main.xml, fragment_first.xml and fragment_second.xml.
Question 1) When the app loads in an emulator, I see the button and textView from the fragment_first.xml. How does this happen? I cannot see in the code where it says, "load fragment_first.xml".
MainActivity.kt has setContentView(R.layout.activity_main) which loads that layout. activity_main.xml has <include layout="#layout/content_main" />. But from there, I do not know where to find the code that loads the fragment_first.xml layout.
I believe that when fragment_first.xml loads, control passes from MainActivity.kt to FirstFragment.kt, yes? Question 2). Is this because of the onCreate function?
Thanks for helping me to understand this better.

There are multiple ways to load a fragment. Traditionally, you use the FragmentManager to create a Fragment transaction that tells the Activity to place a Fragment into the view hierarchy and start managing its lifecycle.
More recently, they have added the Navigation component, which can be used in place of directly using the FragmentManager.
In the current new project Basic Activity, the layout activity_main.xml includes the layout content_main. In content_main.xml, you'll see that it includes a fragment element that is set to the Fragment (using the name parameter) NavHostFragment, which is a special Fragment that the Navigation component uses to host children fragments that are specified in a navigation XML file. This fragment element also specifies the navigation xml file using the navGraph property. It specifies nav_graph.xml, which you'll find in the res/navigation directory.
If you open nav_graph.xml, you'll see that it has FirstFragment set as the home fragment, so that is what pulls it up as the first fragment that you see.
Basically, the control flow is:
Activity's onCreate() sets content view to activity_main, which includes content_main.
content_main includes a NavHostFragment that is automatically inserted in the view hierarchy so the Activity starts running it.
The NavHostFragment is set in the XML to use nav_graph, which tells it to load FirstFragment first.

Related

EditText in kotlin [duplicate]

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

Why Android Studio creates two xml layout files

The eClipse only creates one acitivity_main.xml file, but Android studio creates two xml layout files. The default layout for acitivity_main.xml is the CoordinatorLayout but for content_main.xml is RelativeLayout.
Why need two xmls ? The default is to refer activity_main as: setContentView(R.layout.activity_main), but I find setContentView(R.layout.content_main) also works.
What is the relationship between these two layouts ?
Is there any difference If I drop a button view to the content_main.xml or I drop a button view to activity_main.xml ?
Thanks
Why create 2 files :
These 2 files are created to make your work EASIER. As main file contain your stuff like FAB, toolbar in Coordinate layout. Now your content file is file in which you can make UI of view without interrupting the basic flow. I personally recommend this.
Why need two xmls ? The default is to refer activity_main as:
setContentView(R.layout.activity_main), but I find
setContentView(R.layout.content_main) also works.
These will work as after all these are layout files so can set as content view.
Is there any difference If I drop a button view to the content_main.xml or I drop a button view to activity_main.xml ?
No difference at all.

Adding UIWebView to second (not first) Storyboard view controller

Getting started with xCode 4.6.3 and I'm running into a hiccup.
I've built a simple app using the UIWebView to display a local HTML file and it's contents. I used that to debug any issues with the HTML and/or image displays and I'm all set.
Now I need to recreate that within a larger project I've built with storyboards for all my navigations between multiple view controllers. My issue comes when I'm trying to control-click drag from the WebView into the ViewController.h code below the #interface like many tutorials show, and that worked fine within my smaller single view controller app. It won't do it. I know I'm missing something obvious here. Am I going to have the set up these screens (I have multiple ones to do this same way) as separate xib files and add them into my main project?
Thanks for any help and clarification.
-Chris
You can create a class called for example myWebViewController and in Interface builder add a UIWebView to it. The control+drag to the header file will work.
Every time you want a UIViewController that has a browser in it, define its class as myWebViewController in Interface Builder.
Try not to repeat code. If you see UIViewControllers or any other UIView...that do the same thing, you can group them into a class that you use over and over.

Android dev: what is the difference between INSTANTIATING a View and DEFINING it in the XML Layout

I'm a newbie in Android development.
I have Eclipse with ADT (sdk version: 17 , Android 4.2).
I don't understand what is the difference between:
DEFINING a View (via visual editor provided by ADT or directly in the XML layout file corresponding to the current activity)
and
INSTANTIATING a View (PASSING THE CONTEXT AS PARAMETER) such as: TextView tv = new TextView(getContext()); (taken from : What is 'Context' on Android? , first asnwer)
and
INSTANTIATING a View (WITHOUT PASSING THE CONTEXT AS PARAMETER) such as: TextView tv = new TextView();
Thank in advance for any advice.
Kind regards
To use your terminology:
When DEFINING a View in XML (or the ADT editor - which just creates the XML for you), it still needs to be inflated by a layout inflater. A layout inflater will INSTANTIATE the View(s) for you. This can be done behind the scenes - such as when you call Activity.setContentView(), or directly using View.inflate(). The inflater effectively just runs through the XML and instantiates all of the Views it contains.
When INSTANTIATING a View, you're giving it the Context so it has a reference to resources - so it can load images, strings, dimensions etc - plus other Android related functionality (which you can probably ignore for now).
You can't INSTANTIATE a View without the context.

Android "tools" namespace in layout xml documentation

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

Resources