I'm trying to create a Two-Way Data binding connection with a LiveData object of a modal class. But when I tries to read the values of user it turns out to be null. Here is my code -
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModal: MainActivityViewModal = ViewModelProvider(
this,
MainActivityViewModalFactory()
).get(MainActivityViewModal::class.java)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
this,
R.layout.activity_main
).apply {
this.lifecycleOwner = this#MainActivity
this.viewModal = viewModal
}
}}
Here is the Layout file -
<data>
<variable
name="viewModal"
type="com.weaponx.databindingexample.MainActivityViewModal" />
</data>
<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=".MainActivity">
<ImageView
android:id="#+id/ivLogo"
android:layout_width="100dp"
android:layout_height="100dp"
android:contentDescription="#string/logo"
android:tint="#000000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/ic_menu_myplaces" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clBody"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ivLogo">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.10" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/tilUserName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/edit_text_bg"
android:hint="#string/user_name"
android:padding="5dp"
app:layout_constraintEnd_toStartOf="#id/guideline2"
app:layout_constraintStart_toEndOf="#id/guideline1"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/tietUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#null"
android:inputType="text"
android:text="#={viewModal.user.userName}" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/tilPassword"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#drawable/edit_text_bg"
android:hint="#string/password"
android:padding="5dp"
app:layout_constraintEnd_toStartOf="#id/guideline2"
app:layout_constraintStart_toEndOf="#id/guideline1"
app:layout_constraintTop_toBottomOf="#id/tilUserName">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/tietPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#null"
android:inputType="textPassword"
android:text="#={viewModal.user.password}" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:background="#drawable/button_bg"
android:text="#string/login"
android:onClick="#{() -> viewModal.login()}"
android:textAllCaps="false"
android:textColor="#android:color/white"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="#id/guideline2"
app:layout_constraintStart_toEndOf="#id/guideline1"
app:layout_constraintTop_toBottomOf="#id/tilPassword" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.90" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the ViewModal
class MainActivityViewModal : ViewModel() {
var user = MutableLiveData<User>()
fun login() {
println("Login Success ${user.value}")
}}
And here is the Modal Class
class User() {
var userName: String = ""
var password: String = ""
override fun toString(): String {
return "User(userName='$userName', password='$password')"
}}
Please tell me any solution or a good way around to this problem
In the MainActivityViewModal define user as just User type rather as MutableLiveData.
Related
I am trying to use ViewModel for making API calls, But when I cick the button to send the phone number for OTP the app breaks and their is not information in the logcat too.
Code of LoginActivity.kt
`
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
private lateinit var viewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel = LoginViewModelFactory(LoginService.create()).create(LoginViewModel::class.java)
binding.loginViewModel = viewModel
binding.lifecycleOwner = this
binding.continueButton.setOnClickListener {
viewModel.onLogin()
}
viewModel.login.observe(this){
gotoOTP()
}
}
fun gotoOTP(){
var intent = Intent(this#LoginActivity, OTPLoginVerification::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
this.startActivity(intent)
this.finish()
}
}
`
code for LoginViewModel.kt
`
class LoginViewModel(var loginService: LoginService) : ViewModel(), Observable {
val phoneNumber: MutableLiveData<String> = MutableLiveData()
val login = MutableLiveData<Unit>()
fun onLogin(){
loginService.getOTP(LoginRequestModel(phone_no = phoneNumber.value.toString()))
.enqueue(object: Callback<LoginResponseModel>{
override fun onResponse(call: Call<LoginResponseModel>, response: Response<LoginResponseModel>) {
if(response.isSuccessful) {
if (response.body()!!.result) login.postValue(Unit)
else print("Error")
}
else{
print("Error")
}
}
override fun onFailure(call: Call<LoginResponseModel>, t: Throwable) {
print("Error")
}
})
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
}
`
code for LoginViewModelFactory.kt
`
class LoginViewModelFactory(private val loginService: LoginService): ViewModelProvider.Factory{
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(LoginViewModel::class.java)){
return LoginViewModel(loginService) as T
}
else throw IllegalArgumentException("Error Unknown ViewModel Type")
}
}
And this is the service Interface
interface LoginService {
#POST("getOTP")
fun getOTP(#Body model: LoginRequestModel) : Call<LoginResponseModel>
companion object{
val BASE_URL = "*********"
fun create(): LoginService{
val client = OkHttpClient.Builder()
client.connectTimeout(2, TimeUnit.MINUTES)
client.readTimeout(2, TimeUnit.MINUTES)
client.writeTimeout(2, TimeUnit.MINUTES)
val gson = GsonBuilder()
.serializeNulls()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.setLenient()
.create()
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client.build())
.build()
return retrofit.create(LoginService::class.java)
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="LoginViewModel"
type="com.example.sample.viewmodels.LoginViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Auth.LoginActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/g_h_1"
app:cardBackgroundColor="#color/peach_dark"
style="#style/CustomCardViewStyle">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="1.2:1"
android:src="#drawable/loginimage" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitCenter"
android:src="#drawable/logo"
app:layout_constraintDimensionRatio="3:1"
app:layout_constraintTop_toTopOf="#id/g_h_2"
app:layout_constraintStart_toStartOf="#id/g_v_2"
app:layout_constraintEnd_toEndOf="#id/g_v_3"
app:layout_constraintBottom_toBottomOf="#id/g_h_3" />
<TextView
android:id="#+id/company_highlight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/company_highlight"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_4"
app:layout_constraintTop_toTopOf="#id/g_h_3"
android:textAlignment="center"
android:textSize="20dp"
android:fontFamily="#font/metropolisbold"
android:textColor="#color/t_dark" />
<TextView
android:id="#+id/login_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/login_text"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_4"
app:layout_constraintTop_toBottomOf="#id/company_highlight"
android:textAlignment="center"
android:textSize="17dp"
android:fontFamily="#font/metropolissemibold" />
<androidx.gridlayout.widget.GridLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/gridview_mobilenumber"
app:layout_constraintStart_toStartOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_4"
app:layout_constraintTop_toBottomOf="#+id/login_textview"
android:layout_marginTop="25dp"
app:columnCount="2">
<com.google.android.material.card.MaterialCardView
android:id="#+id/country_flag_cardview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_column="0"
android:padding="10dp"
app:layout_columnWeight="0.4"
app:cardCornerRadius="10dp"
app:layout_rowWeight="1"
android:layout_marginLeft="3dp"
app:strokeWidth="1dp"
app:strokeColor="#color/t_light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/country_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:padding="5dp"
android:src="#drawable/indianflag" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/country_flag"
android:layout_centerVertical="true"
android:src="#drawable/dropdown" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/mobile_number_cardview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_column="1"
android:padding="10dp"
android:layout_marginLeft="10dp"
app:layout_columnWeight="20"
app:layout_rowWeight="1"
app:cardCornerRadius="10dp"
app:strokeWidth="1dp"
app:strokeColor="#color/t_light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/country_code_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:fontFamily="#font/metropolissemibold"
android:text="#string/country_code"
android:layout_alignParentLeft="true"
android:layout_marginLeft="5dp"
android:textColor="#color/t_dark"
android:textSize="22dp" />
<EditText
android:id="#+id/mobile_number_edittext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#+id/country_code_textview"
android:background="#null"
android:fontFamily="#font/metropolislight"
android:hint="#string/enter_mobile"
android:text="#{LoginViewModel.phoneNumber}"
android:inputType="phone"
android:maxLength="10"
android:textColor="#color/t_dark"
android:textColorHint="#color/t_light"
android:textSize="15dp" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.gridlayout.widget.GridLayout>
<TextView
android:id="#+id/new_user_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New User"
android:textSize="15dp"
android:fontFamily="#font/metropolisbold"
app:layout_constraintEnd_toEndOf="#id/g_v_4"
app:layout_constraintTop_toBottomOf="#id/gridview_mobilenumber"
android:textColor="#color/peach_700"
android:layout_marginTop="5dp" />
<com.google.android.material.button.MaterialButton
android:id="#+id/continue_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_4"
app:layout_constraintTop_toBottomOf="#id/new_user_textview"
android:text="Continue"
android:fontFamily="#font/metropolissemibold"
android:textAllCaps="false"
android:textSize="17dp"
app:cornerRadius="10dp"
android:layout_marginTop="20dp" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_h_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.45" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_h_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.47" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_h_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.54" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.10" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.30" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.70" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.90" />
</android.constraintlayout.widget.ConstraintLayout>
</ScrollView>
To the best of my knowledge I tried to make changes but nothing worked.
Any help would be great, As I am unable to find the place where I am making mistake.
Thanks in Advance.
I am following this tutorial to create an android app with space animation stuff. In the step titled "Transition Manager" you're instructed to add the following code to your MainActivity.kt file:
`
constraintSet1.clone(constraintLayout) //1
constraintSet2.clone(this, R.layout.activity_main) //2
departButton.setOnClickListener { //3
//apply the transition
TransitionManager.beginDelayedTransition(constraintLayout) //4
val constraint = if (!isOffscreen) constraintSet1 else constraintSet2
isOffscreen = !isOffscreen
constraint.applyTo(constraintLayout) //5
}
`
When this code is added the variable "constraintLayout" throws up an unresolved reference error
I think constraintLayout is supposed to be pointing to something in the xml and something is failing to make that happen, I just don't know what.
The kotlin code after adding the above block is:
`
package com.raywenderlich.android.razegalactic
import android.os.Bundle
import android.support.constraint.*
import android.support.v7.app.AppCompatActivity
import android.transition.TransitionManager
import kotlinx.android.synthetic.main.keyframe1.*
/**
* Main Screen
*/
class MainActivity : AppCompatActivity() {
private val constraintSet1 = ConstraintSet()
private val constraintSet2 = ConstraintSet()
private var isOffscreen = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.keyframe1)
switch1.setOnCheckedChangeListener { _, isChecked ->
switch1.setText(if (isChecked) R.string.round_trip else R.string.one_way)
constraintSet1.clone(constraintLayout) //1
constraintSet2.clone(this, R.layout.activity_main) //2
departButton.setOnClickListener { //3
//apply the transition
TransitionManager.beginDelayedTransition(constraintLayout) //4
val constraint = if (!isOffscreen) constraintSet1 else constraintSet2
isOffscreen = !isOffscreen
constraint.applyTo(constraintLayout) //5
}
}
}
}
`
The main xml is as follows:
`
<android.support.constraint.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/ConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="#+id/flightsIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/rocket_icon"
app:layout_constraintBottom_toBottomOf="#+id/spaceStationIcon"
app:layout_constraintEnd_toStartOf="#+id/roverIcon"
app:layout_constraintStart_toEndOf="#+id/spaceStationIcon"
app:layout_constraintTop_toTopOf="#+id/spaceStationIcon" />
<ImageView
android:id="#+id/spaceStationIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginTop="15dp"
android:src="#drawable/space_station_icon"
app:layout_constraintEnd_toStartOf="#+id/flightsIcon"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/roverIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/rover_icon"
app:layout_constraintBottom_toBottomOf="#+id/flightsIcon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/flightsIcon"
app:layout_constraintTop_toTopOf="#+id/flightsIcon" />
<TextView
android:id="#+id/spaceStationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="#string/space_stations"
app:layout_constraintEnd_toEndOf="#+id/spaceStationIcon"
app:layout_constraintStart_toStartOf="#+id/spaceStationIcon"
app:layout_constraintTop_toBottomOf="#+id/spaceStationIcon" />
<TextView
android:id="#+id/textView1"
android:layout_width="124dp"
android:layout_height="98dp"
android:layout_marginEnd="40dp"
android:background="#color/colorPrimary"
android:gravity="center"
android:paddingEnd="20dp"
android:text="#string/dca"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="#+id/doubleArrowsIcon"
app:layout_constraintEnd_toEndOf="#+id/doubleArrowsIcon"
app:layout_constraintTop_toTopOf="#+id/doubleArrowsIcon" />
<TextView
android:id="#+id/roverLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="#string/rovers"
app:layout_constraintEnd_toEndOf="#+id/roverIcon"
app:layout_constraintStart_toStartOf="#+id/roverIcon"
app:layout_constraintTop_toBottomOf="#+id/roverIcon" />
<TextView
android:id="#+id/textView2"
android:layout_width="124dp"
android:layout_height="98dp"
android:layout_marginStart="40dp"
android:background="#color/colorPrimary"
android:gravity="center"
android:paddingStart="20dp"
android:text="#string/mars"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="#+id/doubleArrowsIcon"
app:layout_constraintStart_toStartOf="#+id/doubleArrowsIcon"
app:layout_constraintTop_toTopOf="#+id/doubleArrowsIcon" />
<TextView
android:id="#+id/flightsLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="#string/flights"
app:layout_constraintEnd_toEndOf="#+id/flightsIcon"
app:layout_constraintStart_toStartOf="#+id/flightsIcon"
app:layout_constraintTop_toBottomOf="#+id/flightsIcon" />
<ImageView
android:id="#+id/doubleArrowsIcon"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginBottom="40dp"
android:src="#drawable/double_arrows"
app:layout_constraintBottom_toTopOf="#+id/guideline1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Switch
android:id="#+id/switch1"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="200dp"
android:background="#color/colorAccent"
android:checked="false"
android:padding="8dp"
android:switchPadding="24dp"
android:text="#string/one_way"
android:textColor="#android:color/white"
app:layout_constraintStart_toStartOf="#+id/guideline2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#color/colorAccent"
android:padding="8dp"
android:text="#string/traveller"
android:textColor="#android:color/white"
app:layout_constraintStart_toStartOf="#+id/guideline2"
app:layout_constraintTop_toBottomOf="#+id/switch1" />
<ImageView
android:id="#+id/rocketIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="8dp"
android:src="#drawable/rocket_icon"
app:layout_constraintCircle="#id/galaxyIcon"
app:layout_constraintCircleAngle="270"
app:layout_constraintCircleRadius="100dp" />
<ImageView
android:id="#+id/galaxyIcon"
android:layout_width="90dp"
android:layout_height="90dp"
android:src="#drawable/galaxy"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline1"
app:layout_constraintVertical_bias="0.495" />
<Button
android:id="#+id/departButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/depart"
android:textColor="#android:color/white"
app:backgroundTint="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="158dp" />
<android.support.constraint.Guideline
android:id="#+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="0dp" />
<android.support.constraint.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintGuide_percent="1" />
</android.support.constraint.ConstraintLayout>
`
can anyone tell me what I might be missing or how this can be fixed?
Thanks in advance.
You're suppose to reference a view from the xml before you can use it.
Do this, also if the name of the layout the MainActivity is suppose to use is main.xml, it should be the one your setContentView use not some other layout.
lateinit var cosntraintLayout: ConstraintLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main) // <- main.xml
cosntraintLayout = findViewById<ConstraintLayout>(R.id.ConstraintLayout) // <- add this line
...
...
}
switch1 and departButton will also throw the same error, but I'll leave it for you to figure it out based on the code I provided.
Using com.google.android.material:material:1.6.1, when setting hint enabled to true and then to false, the outline gets broken. Here is the example code.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val someHintButton = findViewById<MaterialButton>(R.id.someHintButton)
val noHintButton = findViewById<MaterialButton>(R.id.noHintButton)
val textInput = findViewById<TextInputEditText>(R.id.textInput)
val textLayout = findViewById<TextInputLayout>(R.id.textLayout)
someHintButton.setOnClickListener {
textInput.setText("Some text")
textLayout.setHintEnabled(true)
textLayout.setHint("Entered text:")
}
noHintButton.setOnClickListener {
textLayout.setHint(null)
textLayout.setHintEnabled(false)
textInput.setText("Some text will be entered here")
}
}
}
activity_main.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=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
android:layout_marginTop="5dp"
android:layout_marginHorizontal="5dp"
android:id="#+id/textLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
>
<com.google.android.material.textfield.TextInputEditText
android:focusable="false"
android:editable="false"
android:id="#+id/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here some text"
android:textAlignment="center"
android:inputType="none"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="#+id/someHintButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:text="some hint"
android:textColor="#color/black"
android:textColorLink="#FFFFFF"
app:backgroundTint="#FFFFFF"
app:cornerRadius="8dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<com.google.android.material.button.MaterialButton
android:id="#+id/noHintButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No hint"
android:textColor="#color/black"
android:textColorLink="#FFFFFF"
app:backgroundTint="#FFFFFF"
app:cornerRadius="8dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Screen after launch:
Screen after 'Some hint' pressed:
Screen after 'No hint' pressed:
setHint(null) or setHint("") don't do any difference. Why doesn't outline get reconnected? Please advise.
It is my first time using data binding, so I'm confused. Trying to implement two-way databinding in EditText with MVVM architecture and getting this error in my Build:
The expression 'viewmodelClientUrl.getValue()' cannot be inverted, so it cannot be used in a two-way binding
Details: There is no inverse for method getValue, you must add an #InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions
I can't understand what it means
There is my LoginViewModel:
class LoginViewModel(
private val repository: MainRepository): ViewModel() {
private var _clientUrl = MutableLiveData<String?>()
private var _username = MutableLiveData<String?>()
private var _password = MutableLiveData<String?>()
private val validationError = ValidationError()
val clientUrl: LiveData<String?>
get() = _clientUrl
val username: LiveData<String?>
get() = _username
val password: LiveData<String?>
get() = _password
fun onClick(){
val clientUrl = clientUrl.toString().trim()
val username = username.toString().trim()
val password = password.toString().trim()
validateCredentials(clientUrl, username, password)
}
private fun validateCredentials(clientUrl: String, username: String, password: String): Boolean {
if(!Patterns.WEB_URL.matcher(clientUrl).matches() || clientUrl.isEmpty()) {
validationError.isUrlValid = false
return false
}
if(username.isEmpty()) {
validationError.isUsernameValid = false
return false
}
if(password.isEmpty()) {
validationError.isUsernameValid = false
return false
}
return true
}
There is my layout:
<layout
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">
<data>
<import type="android.view.View"/>
<variable
name="viewmodel"
type="com.example.redmining.ui.login.LoginViewModel"/>
<variable
name="validationError"
type="com.example.redmining.model.ValidationError"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".ui.login.LoginFragment"
android:background="#color/white">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/urlTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="170dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/clientUrl"
android:text="#={viewmodel.clientUrl}"
android:fontFamily="#font/poppins_light"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/url_hint"
android:inputType="textUri"
android:selectAllOnFocus="true"
/>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/urlTextInputLayout"
app:layout_constraintStart_toStartOf="#id/urlTextInputLayout"
android:text="Invalid URL"
android:textColor="#android:color/holo_red_light"
android:textSize="12sp"
android:layout_marginTop="-8dp"
android:layout_marginStart="5dp"
android:visibility="#{validationError.urlValid ? View.GONE : View.VISIBLE}"/>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/usernameTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/urlTextInputLayout">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/poppins_light"
android:hint="#string/login"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
android:text="#={viewmodel.username}" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/usernameTextInputLayout"
app:layout_constraintStart_toStartOf="#id/usernameTextInputLayout"
android:text="Enter your username"
android:textColor="#android:color/holo_red_light"
android:textSize="12sp"
android:layout_marginTop="-8dp"
android:layout_marginStart="5dp"
android:visibility="#{validationError.usernameValid ? View.GONE : View.VISIBLE}"/>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/usernameTextInputLayout"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:text="#={viewmodel.password}"
android:id="#+id/password"
android:fontFamily="#font/poppins_light"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/password"
android:imeActionLabel="#string/log_in"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/passwordTextInputLayout"
app:layout_constraintStart_toStartOf="#id/passwordTextInputLayout"
android:text="Enter your password"
android:textColor="#android:color/holo_red_light"
android:textSize="12sp"
android:layout_marginTop="-8dp"
android:layout_marginStart="5dp"
android:visibility="#{validationError.passwordValid ? View.GONE : View.VISIBLE}"/>
<Button
android:onClick="#{() -> viewmodel.onClick()}"
android:id="#+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:layout_marginEnd="48dp"
android:layout_marginTop="16dp"
android:backgroundTint="#color/black"
android:enabled="true"
android:fontFamily="#font/poppins_light"
android:paddingLeft="30dp"
android:paddingTop="20dp"
android:paddingRight="30dp"
android:paddingBottom="20dp"
android:text="#string/log_in"
android:textAllCaps="true"
android:textColor="#color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/passwordTextInputLayout"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I think you don't need 2 way binding, because it will work fine without it.
android:text="#{viewmodel.clientUrl}"
Even if you need to use it then, there are 2 approaches :
1st approach :
Use MutableLiveData instead of LiveData, because LiveData doesn't provide setter.
make _clientUrl non-private and :
android:text="#{viewmodel._clientUrl}"
2nd approach :
If you want to use LiveData then use afterTextChanged to set the value :
in ViewModel :
fun updateClientUrl(s: Editable) {
_clientUrl.value = s.toString();
}
In XML :
android:text="#{viewmodel.clientUrl}"
android:afterTextChanged="#{viewmodel.updateClientUrl}"
All of the solutions will work :
I'm getting this error on Android 5x but i don't know what it could be the problem. I'm getting the error on the file FragmentDataNewjourneyBindingImpl. So i tracked and the file that is using the FragmentDataNewJourneyBinding is AuthenticationFragment. So it could be either my xml has something wrong or my fragment has.
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="br.com.gabriel.novajornada.security.auth.AuthenticationViewModel" />
<variable
name="constantes"
type="br.com.gabriel.novajornada.constants.ConstantsKt" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/include"
android:fitsSystemWindows="true">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout11"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
style="#style/bo_texto_regular"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin"
android:layout_marginEnd="#dimen/margin"
android:gravity="center_horizontal"
android:lineSpacingExtra="4sp"
android:text="#string/fill_data_title_new_journey"
android:textColor="#1a1b1a"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="#id/constraintLayout11" />
<TextView
android:id="#+id/textView98"
style="#style/bo_texto_regular"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin"
android:layout_marginTop="#dimen/margin_small"
android:layout_marginEnd="#dimen/margin"
android:gravity="center_horizontal"
android:lineSpacingExtra="6sp"
android:text="#string/fill_data_subtitle"
android:textColor="#4a4b4a"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="#id/textView"
tools:layout_editor_absoluteX="0dp" />
<br.com.original.common.components.BOTextInputLayout
android:id="#+id/text_input_cpf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin"
android:layout_marginTop="19dp"
android:layout_marginRight="#dimen/margin"
android:hint="#string/identifier_field_title"
android:theme="#style/TextInputLayoutTheme.ClearButton"
app:errorEnabled="true"
app:errorTextAppearance="#style/MyProfile.Error"
app:hintTextAppearance="#style/TextLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView98">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/identifier"
style="#style/TextInputEditTextTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:text="#={viewModel.credentials.cpf}"
app:mask="#{ `###.###.###-##` }" />
</br.com.original.common.components.BOTextInputLayout>
<br.com.original.common.components.BOTextInputLayout
android:id="#+id/text_input_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin"
android:layout_marginRight="#dimen/margin"
android:hint="#string/name_field"
android:inputType="textNoSuggestions|textVisiblePassword"
android:theme="#style/TextInputLayoutTheme.ClearButton"
app:errorEnabled="true"
app:errorTextAppearance="#style/MyProfile.Error"
app:hintTextAppearance="#style/TextLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_input_cpf">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/name"
style="#style/TextInputEditTextTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ âãàáäêèéëîìíïôòóõöùúüñçÂÃÀÁÄÊÈÉËÎÌÍÏÔÒÓÕÖÙÚÜÑÇ"
android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="#{constantes.NAMES_MAX_LENGTH}"
android:text="#={viewModel.credentials.name}" />
</br.com.original.common.components.BOTextInputLayout>
<br.com.original.common.components.BOTextInputLayout
android:id="#+id/text_input_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin"
android:layout_marginRight="#dimen/margin"
android:clipChildren="false"
android:hint="#string/cellphone_ddd_field_title"
android:theme="#style/TextInputLayoutTheme.ClearButton"
app:errorTextAppearance="#style/MyProfile.Error"
app:hintTextAppearance="#style/TextLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_input_name">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/phone"
style="#style/TextInputEditTextTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:text="#={viewModel.credentials.phoneNumber}"
app:mask="#{ `(##) #####-####` }" />
</br.com.original.common.components.BOTextInputLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="#dimen/margin"
app:layout_constraintBottom_toTopOf="#+id/btnConfirm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_input_phone"
app:layout_constraintVertical_bias="1.0">
<TextView
android:id="#+id/politicas"
style="#style/seja_subtitle_h3_regular"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="#dimen/margin"
android:paddingEnd="#dimen/margin"
android:text="#string/politicas_header_new_journey"
android:textSize="#dimen/text_small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteY="4dp" />
<TextView
android:id="#+id/openPoliticas"
style="#style/seja_subtitle_h3_regular"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="#dimen/margin"
android:paddingTop="2pt"
android:paddingEnd="#dimen/margin"
android:text="#string/privacy_policy_new_journey"
android:textSize="#dimen/text_small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/politicas" />
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="#+id/btnConfirm"
style="#style/seja_button_bordeless"
android:layout_width="match_parent"
android:layout_height="#dimen/button_height_seja"
android:layout_marginStart="#dimen/margin"
android:layout_marginTop="#dimen/margin"
android:layout_marginEnd="#dimen/margin"
android:enabled="#{identifier.text.length() == 14 && phone.text.length() == 15 && name.text.length() > 2}"
android:text="#string/continue_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<include
android:id="#+id/include"
layout="#layout/seja_bar_layout_newjourney_center" />
<br.com.original.bank.novajornada.common.component.BOStateView
android:id="#+id/stateView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:msv_errorView="#layout/seja_error_view_newjourney"
app:msv_loadingView="#layout/seja_loading_view_newjourney" />
</RelativeLayout>
</layout>
This is AuthenticationFragment.kt. I put only the part of the bindingView declaration because i think it's more important:
#ExperimentalCoroutinesApi
class AuthenticationFragment : NavigationFragment() {
val viewModel: AuthenticationViewModel by viewModel()
lateinit var bindingView: FragmentDataNewjourneyBinding
lateinit var formValidate: FormValidate
private val novaJornadaActivity: NovaJornadaActivity by lazy { activity as NovaJornadaActivity }
private val management: TagManagement by inject()
#ExperimentalCoroutinesApi
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
bindingView = DataBindingUtil.inflate<FragmentDataNewjourneyBinding>(inflater, R.layout.fragment_data_newjourney, container, false)
.apply {
lifecycleOwner = this#AuthenticationFragment
viewModel = this#AuthenticationFragment.viewModel
}
viewModel.checkUserPromoted((activity as NovaJornadaActivity).userPromoted)
return bindingView.root
}
Is there something wrong with my implementation? I will be glad for anyone for trying to help me