activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment example"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="fragment one"
android:id="@+id/fragone"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="fragment two"
android:id="@+id/fragtwo"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frame"
android:background="#00BCD4"/>
</LinearLayout>
</layout>
MainActivity.kt
package com.androindian.fragment
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.FragmentManager
import com.androindian.fragment.databinding.ActivityMainBinding
import com.androindian.fragment.ui.login.SecondFrag
class MainActivity : AppCompatActivity() {
var binding: ActivityMainBinding?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= DataBindingUtil.setContentView(this,R.layout.activity_main)
binding?.fragone?.setOnClickListener {
var fragmentmanager: FragmentManager=supportFragmentManager
var fragmentTransaction=fragmentmanager.beginTransaction()
var firstFrag=FirstFrag()
fragmentTransaction.replace(R.id.frame,firstFrag)
fragmentTransaction.commit()
}
binding?.fragtwo?.setOnClickListener {
var fragmentmanager: FragmentManager=supportFragmentManager
var fragmentTransaction=fragmentmanager.beginTransaction()
var secondFrag= SecondFrag()
fragmentTransaction.replace(R.id.frame,secondFrag)
fragmentTransaction.commit()
}
}
}
FirstFrag.kt
package com.androindian.fragment
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.databinding.DataBindingUtil
import com.androindian.fragment.databinding.FragmentFirstBinding
class FirstFrag : Fragment() {
var binding: FragmentFirstBinding?=null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
var view: View
//view=inflater.inflate(R.layout.fragment_first, container, false)
binding=DataBindingUtil.inflate(inflater,
R.layout.fragment_first, container, false)
// var button: Button?=null
//button=view?.findViewById(R.id.bt)
binding?.bt?.setOnClickListener {
var intent=Intent(context,Registr::class.java)
startActivity(intent)
}
return binding?.root
}
}
fragment_first.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFrag"
android:orientation="vertical">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_blank_fragment" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bt"
android:text="Hellow frag"/>
</LinearLayout>
</layout>
second_frag.kt
package com.androindian.fragment.ui.login
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import com.androindian.fragment.databinding.FragmentSecondBinding
import com.androindian.fragment.R
class SecondFrag : Fragment() {
private lateinit var loginViewModel: LoginViewModel
private var _binding: FragmentSecondBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loginViewModel = ViewModelProvider(this, LoginViewModelFactory())
.get(LoginViewModel::class.java)
val usernameEditText = binding.username
val passwordEditText = binding.password
val loginButton = binding.login
val loadingProgressBar = binding.loading
loginViewModel.loginFormState.observe(viewLifecycleOwner,
Observer { loginFormState ->
if (loginFormState == null) {
return@Observer
}
loginButton.isEnabled = loginFormState.isDataValid
loginFormState.usernameError?.let {
usernameEditText.error = getString(it)
}
loginFormState.passwordError?.let {
passwordEditText.error = getString(it)
}
})
loginViewModel.loginResult.observe(viewLifecycleOwner,
Observer { loginResult ->
loginResult ?: return@Observer
loadingProgressBar.visibility = View.GONE
loginResult.error?.let {
showLoginFailed(it)
}
loginResult.success?.let {
updateUiWithUser(it)
}
})
val afterTextChangedListener = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// ignore
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
// ignore
}
override fun afterTextChanged(s: Editable) {
loginViewModel.loginDataChanged(
usernameEditText.text.toString(),
passwordEditText.text.toString()
)
}
}
usernameEditText.addTextChangedListener(afterTextChangedListener)
passwordEditText.addTextChangedListener(afterTextChangedListener)
passwordEditText.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
loginViewModel.login(
usernameEditText.text.toString(),
passwordEditText.text.toString()
)
}
false
}
loginButton.setOnClickListener {
loadingProgressBar.visibility = View.VISIBLE
loginViewModel.login(
usernameEditText.text.toString(),
passwordEditText.text.toString()
)
}
}
private fun updateUiWithUser(model: LoggedInUserView) {
val welcome = getString(R.string.welcome) + model.displayName
// TODO : initiate successful logged in experience
val appContext = context?.applicationContext ?: return
Toast.makeText(appContext, welcome, Toast.LENGTH_LONG).show()
}
private fun showLoginFailed(@StringRes errorString: Int) {
val appContext = context?.applicationContext ?: return
Toast.makeText(appContext, errorString, Toast.LENGTH_LONG).show()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/fragment_horizontal_margin"
android:paddingTop="@dimen/fragment_vertical_margin"
android:paddingRight="@dimen/fragment_horizontal_margin"
android:paddingBottom="@dimen/fragment_vertical_margin"
tools:context=".ui.login.SecondFrag">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:hint="@string/prompt_password"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="48dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="48dp"
android:layout_marginBottom="64dp"
android:enabled="false"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.2" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="32dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="64dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/password"
app:layout_constraintStart_toStartOf="@+id/password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
Registr.kt
package com.androindian.fragment
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class Registr : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_registr)
}
}
activity_regstr.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Registr">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reg"
tools:layout_editor_absoluteX="144dp"
tools:layout_editor_absoluteY="170dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
androidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Fragment"
tools:targetApi="31">
<activity
android:name=".Registr"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>