Android data binding - unable to invoke the click handler - android

I have created a simple login screen using the databinding as described at http://developer.android.com/tools/data-binding/guide.html however I am unable to get the notification of text changed from
the text box or
the button click.
I think for the text box notification, the android team might not have implemented it completely. However, I fail to understand my mistake for the button click handler.
The fragment code looks like
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FragmentAccountSetupInitialBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_account_setup_initial, container, false);
View view = binding.getRoot();
binding.setAccount(new UserAccount());
return view;
}
The ViewModel for user account is as defined below
public class UserAccount extends BaseObservable {
private String _email;
private String _password;
#Bindable
public String getEmail() {
return _email;
}
public void setEmail(String email) {
if(!TextUtils.equals(_email, email)) {
_email= email;
notifyPropertyChanged(BR.email);
}
}
#Bindable
public String getPassword() {
return _password;
}
public void setPassword(String password) {
if(!TextUtils.equals(_password, password)) {
_password = password;
notifyPropertyChanged(BR.password);
}
}
public void onSignInButtonClick(View view) {
// Sign in now
}
}
And the fragment layout is
<layout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="account" type="project.namespace.UserAccount"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="56dp"
android:paddingLeft="24dp"
android:paddingRight="24dp">
<!-- Email Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/email"
android:text="#{account.email}"/>
</android.support.design.widget.TextInputLayout>
<!-- Password Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="#string/password"
android:text="#{account.password}"/>
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="#string/signin"
android:onClick="#{account.onSignInButtonClick}"/>
</LinearLayout>
</FrameLayout>
</layout>
Update
Moving to android studio 2.1 beta 2 solves the first problem. Updated the layout as follows
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/email"
android:text="#={account.email}"/>

Can you try the following for your button?
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="#string/signin"
android:onClick="#{account::onSignInButtonClick}"/>
I get an error on the IDE ('!=', '%'... expected, got ':') but it works when the app is running... The important part is the "::".
Hope this helps you!

As I known,the onClick event seems not work in fragment and I don't why.Try use BindingAdapter annotation to define custom setter.

Related

Using webview with entered string values

I just want to ask you how can i use webview with an entered strings from edittext?
For example, i created 2 fragment one of these shows webview and another one gets 2 edittext from users. I just want to get entered edittext values from 2. fragment to 1. fragment. Because i want create a URL like this : webView.loadUrl("http://www.truebilisim.com/myiphone/index.php?id=" + ID + "&sifre=" + Password);
This is my first fragment.
<FrameLayout 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=".Tab1">
<WebView
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And this is the second one.
<FrameLayout 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=".Tab2">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingTop="80dp"
android:paddingRight="30dp"
android:paddingLeft="30dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Tab2">
<ImageView
android:src="#drawable/logo_small"
android:id="#+id/logo"
android:layout_marginBottom="30dp"
android:layout_width="match_parent"
android:layout_height="100dp" />
<android.support.design.widget.TextInputLayout
android:id="#+id/layout_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/logo">
<EditText
android:hint="ID"
android:textColor="#color/colorPrimary"
android:id="#+id/idx"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/layout_pass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/layout_id"
>
<EditText
android:inputType="textPassword"
android:hint="Şifre"
android:textColor="#color/colorPrimary"
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/btn_login"
android:layout_below="#id/layout_pass"
android:backgroundTint="#color/colorPrimaryDark"
android:text="KAYDET"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Your question is too big to answer here. And its not specific. I'm just going to mention the steps. You'll find code for specific parts if you search properly.
Initialize your EditTexts. You you'll send the values from the EditText's when the user clicks the login button.
Set onClickListener on the login button. Inside the listener, check if your EditTexts have value or not. If they have value, goto the other fragment.
Send the values of EditText to the other fragment, you can do this in multiple ways. One is, just get an instance to the destination fragment object, and send the value.
I get these strings like this but cant find a way to use at first fragment. Can u show me ?
public class Tab2 extends Fragment {
public Tab2() {
// Required empty public constructor
}
EditText ed1,ed2;
private Button b1;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab2, container, false);
b1 = view.findViewById(R.id.btn_login);
ed1 = view.findViewById(R.id.idx);
ed2 = view.findViewById(R.id.password);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String n = ed1.getText().toString();
String p = ed2.getText().toString();
}
});
return view;
}
}

Android ProgressBar NPE Within Fragment

I want to display a Progressbar in my LoginFragment for testing purposes however after I connect my view variables in the OnCreateView Callback in my LoginFragment, my app shuts down and its due to:
Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
But what's driving me nuts is that this is the only View that throws a NPE, all my other views I am able to manipulate and reference without a problem. I also tried to use a Progressbar in the LoginActivity that hosts the LoginFragment and the Progressbar worked as expected, but why not in the fragment ??
I attached the code xml and fragment code corresponding to the LoginFragment
public class LoginFragment extends Fragment {
private AutoCompleteTextView name;
private EditText password;
private ProgressBar progressBar;
//......... Skipped For Brevity .........
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.login_fragment, container, false);
v.setBackgroundResource(R.drawable.album_jazz_blues);
name = v.findViewById(R.id.username);
password = v.findViewById(R.id.password);
progressBar = v.findViewById(R.id.progress_bar);
//progressBar.setVisibility(View.VISIBLE); <-------- THROWS NPE
return v;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:id="#+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/login_parent_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="16dp"
android:orientation="vertical"
tools:layout_alignParentTop="true"
tools:layout_alignParentStart="true" >
<AutoCompleteTextView
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/email"
android:maxLines="1"
android:singleLine="true" />
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/password"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
tools:ignore="Autofill" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
<ProgressBar
style="#style/Widget.AppCompat.ProgressBar"
android:layout_gravity="center"
android:indeterminate="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progress_bar">
</ProgressBar>
What Am I missing here ?
As Aaron in the comments pointed out, I had two different layout folders a normal folder and v-26 folder which did not necessarily mirror each other so what I did was assign the folders the exact same elements and attributes with their corresponding values with the exception of
EditTextandroid:importantForAutofill
autofill attribute, in v-26 android:importantForAutofill="no and in my regular layout folder tools:ignore="Autofill"

How to request or remove the focus on edittext using data binding

I am learning mvvm structure and making an app using mvvm structure and data binding also.
Now, what I want to do is, I wanted to fetch a user from sharedpreference, If I am getting a user successfully then, I would set the name of usr to edittext1. In that case, I want to request focus on edittext2.
How to achieve that using databinding? (in such a way that i don't
have to use activity. The job should be done using view model and xml
only.)
I have tried that using following way.
StartGameViewModel
public class StartGameViewModel extends ViewModel {
public static String TAG="StartGameViewModel";
private Preference<User> preference;
public ObservableField<String> player1Name=new ObservableField<>("");
public ObservableField<String> player2Name=new ObservableField<>("");
public ObservableBoolean shouldRequestFocus=new ObservableBoolean(false);
StartGameViewModel(Preference preference){
this.preference=preference;
}
public void getPreference() {
preference.get(Constants.CURRENT_USER,User.class)
.subscribe(new Observer<User>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(User user) {
player1Name.set(user.name);
shouldRequestFocus.set(true);
}
#Override
public void onError(Throwable e) {
Log.i(TAG,"user is logged out");
}
#Override
public void onComplete() {
Log.i(TAG,"Completed Preference");
}
});
}
}
activity_start_game.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"
tools:context=".view.StartGameActivity">
<data>
<variable
name="startGameViewModel"
type="com.sevenbits.android.mvvmsample.viewmodel.StartGameViewModel" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/splash_bg">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter Players Name"
android:textSize="24sp"
android:textColor="#color/white"
app:layout_constraintVertical_bias="0.75"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="#+id/input_layout"
app:layout_constraintTop_toTopOf="parent"
/>
<LinearLayout
android:id="#+id/input_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:background="#color/white"
android:elevation="20dp"
android:orientation="vertical"
android:paddingBottom="40dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.45"
tools:layout_editor_absoluteX="8dp">
<android.support.design.widget.TextInputLayout
android:id="#+id/til_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<android.support.design.widget.TextInputEditText
android:id="#+id/et_player1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Player1"
android:text="#{startGameViewModel.player1Name}"
app:addTextChangedListener="#{startGameViewModel.Player1Watcher}" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/til_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<android.support.design.widget.TextInputEditText
android:id="#+id/et_player2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Player2"
android:text="#{startGameViewModel.player2Name}"
app:addTextChangedListener="#{startGameViewModel.Player2Watcher}" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<Button
android:id="#+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bg_button"
android:elevation="20dp"
android:gravity="center"
android:paddingBottom="20dp"
android:paddingEnd="40dp"
android:paddingStart="40dp"
android:paddingTop="20dp"
android:text="Start"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/input_layout" />
</android.support.constraint.ConstraintLayout>
</layout>
StartGameActivity:
public class StartGameActivity extends AppCompatActivity {
ActivityStartGameBinding activityStartGameBinding;
StartGameViewModel startGameViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDataBinding();
setStartGameListener();
}
private void initDataBinding() {
activityStartGameBinding = DataBindingUtil.setContentView(this, R.layout.activity_start_game);
StartGameViewModelFactory startGameViewModelFactory= Injection.provideStartGameViewModelFactory(this);
startGameViewModel = ViewModelProviders.of(this,startGameViewModelFactory).get(StartGameViewModel.class);
activityStartGameBinding.setStartGameViewModel(startGameViewModel);
startGameViewModel.getPreference();
if(startGameViewModel.shouldRequestFocus.get())
findViewById(R.id.et_player2).requestFocus();
}
private void setStartGameListener() {
findViewById(R.id.start_button).setOnClickListener(v -> {
Intent intent=new Intent(StartGameActivity.this,GameActivity.class);
intent.putExtra(Constants.PLAYER1_NAME,startGameViewModel.player1Name.get());
intent.putExtra(Constants.PLAYER2_NAME,startGameViewModel.player2Name.get());
startActivity(intent);
});
}
}
Very simple via binding adapter
#JvmStatic
#BindingAdapter("requestFocus")
fun requestFocus(view: TextView, requestFocus: Boolean) {
if (requestFocus) {
view.isFocusableInTouchMode = true
view.requestFocus()
}
}
<EditText
android:id="#+id/et_company"
android:layout_width="0dp"
android:layout_height="match_parent"
android:imeOptions="actionDone"
android:inputType="textCapSentences"
android:maxLength="32"
android:scrollbars="vertical"
app:requestFocus="#{company.requestFocus}" />
I know this is an old question, but I was not able to solve the issue with the current answer. Posting my answer here:
in XML:
<EditText
android:id="#+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="#dimen/elevation15"
app:requestFocus="#{viewmodel.focus}"/>
And in the viewModel, I had a Boolean variable declared as
val focus = true
And the binding adapter is as follows:
companion object{
#BindingAdapter("requestFocus")
#JvmStatic fun requestFocus(editText: EditText, requestFocus: Boolean){
if(requestFocus){
editText.isFocusableInTouchMode = true
editText.requestFocus()
}
}
}
Basically what is happening here is, Since app:requestFocus is written inside the xml, it will invoke the binding adapter with the focus Boolean, which is given as the value for the attribute for app:requestFocus.
In my case, I didn't want to remove focus, that's why I used Boolean. If it needs to be changed, using a livedata and set the value, and update the binding adapter accordingly
Disclaimer: I am new to MVVM and Databinding, someone please correct me if I am wrong.

EditText setError is out of place in BottomSheetDialog

I am facing a problem with the position of the error indicator of my EditText when calling editText.setError("...").
As you can see in the screenshot I am using a BottomSheetDialog with an EditText inside of it. When I display the error indicator, the text is completely out of place. It seems as if the dialog "thinks" that it is full-screen, while it is actually not.
This is my dialog layout file (phone_dialog.xml):
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:padding="#dimen/padding_layout_normal"
android:text="#string/dialog_title_edit_phone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<EditText
android:id="#+id/etPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:inputType="phone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvTitle"/>
<Button
android:id="#+id/btnSavePhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/etPhone"/>
</android.support.constraint.ConstraintLayout>
My Activity layout file (activity_contacts.xml):
<?xml version="1.0" encoding="utf-8"?>
<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"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvContacts"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
This is how I show the dialog from my Activity:
PhoneBottomDialog dialog = new PhoneBottomDialog(Context);
dialog.show();
This is my PhoneBottomDialog class:
public class PhoneBottomDialog extends BottomSheetDialog {
public PhoneBottomDialog(Context context) {
super(context);
View view = getLayoutInflater().inflate(R.layout.phone_dialog, null);
setContentView(view);
// additional setup below this...
}
// ...
}
I am not performing any other layouting inside my custom PhoneButtomDialog. Changing the root layout of my dialog to RelativeLayout or LinearLayout as well as adding a ScrollView did not change anything. It's also not a device or specific Android version related issue as the problem occurs on all of my testing devices ranging from Android 5.0 to 7.1, it also occurs on the emulator.
Does anyone have an idea why this is happening?
You can use TextInputLayout and inside that you can define Edit Text.
I have done some modification inside your phone_dialog.xml.
phone_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="bottom"
android:background="#android:color/holo_blue_light"
android:padding="10dp"
app:behavior_hideable="true"
app:behavior_peekHeight="60dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:gravity="center"
android:padding="10dp"
android:text="dialog_title_edit_phone" />
<android.support.design.widget.TextInputLayout
android:id="#+id/inputPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/TextInputLayoutLabel">
<EditText
android:id="#+id/etPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter phone"
android:imeOptions="actionDone"
android:inputType="phone"
android:maxLines="1"
android:textSize="20sp" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/btnSavePhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/etPhone"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="8dp"
android:text="Save" />
</LinearLayout>
</FrameLayout>
Inside style.xml add this.
<style name="TextInputLayoutLabel" parent="Widget.Design.TextInputLayout">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">#android:color/black</item>
<item name="android:textSize">15sp</item>
<!-- Label color in TRUE state and bar color FALSE and TRUE State -->
<item name="colorAccent">#color/colorPrimary</item>
<item name="colorControlNormal">#color/colorAccent</item>
<item name="colorControlActivated">#color/colorAccent</item>
</style>
PhoneBottomDialog.java
public class PhoneBottomDialog extends BottomSheetDialog {
TextInputLayout inputPhone;
EditText edtPhone;
Button btnSave;
public PhoneBottomDialog(Context context) {
super(context);
View view = getLayoutInflater().inflate(R.layout.phone_dialog, null);
setContentView(view);
// additional setup below this...
inputPhone = (TextInputLayout) view.findViewById(R.id.inputPhone);
edtPhone = (EditText) view.findViewById(R.id.etPhone);
btnSave = (Button) view.findViewById(R.id.btnSavePhone);
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!validatePhone())
return;
}
});
}
private boolean validatePhone() {
if (edtPhone.getText().toString().isEmpty()) {
inputPhone.setError("Please enter valid phone number with country code.");
requestFocus(edtPhone);
return false;
} else {
inputPhone.setErrorEnabled(false);
}
return true;
}
private void requestFocus(View view) {
if (view.requestFocus()) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
// ...
}
And inside Activity.
#SuppressLint("SetTextI18n")
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test24);
mContext = this;
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
PhoneBottomDialog dialog = new PhoneBottomDialog(mContext);
dialog.show();
}
Below you can see the output for this.
add compile 'com.android.support:design:24.2.0' in gradle dependencies
use TextInputLayout in xml.
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputServer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="36dp"
app:errorTextAppearance="#style/TextErrorAppearance">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
........./>
</android.support.design.widget.TextInputLayout>
From Lollipop(5.0) version android provide TextInputLayout to do this.
Use below xml and java code to show same type view.
abc.xml:
<android.support.design.widget.TextInputLayout
android:id="#+id/text_input_layout_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
app:theme="#style/AppTheme">
<android.support.v7.widget.AppCompatEditText
android:id="#+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:imeOptions="actionNext"
android:inputType="text"
android:singleLine="true"
android:textColor="#color/icons"
android:textSize="16sp" />
</android.support.design.widget.TextInputLayout>
Abc.java:
private TextInputLayout
textInputLayout_User = (TextInputLayout) findViewById(R.id.text_input_layout_user);
textInputLayout_User.setError(getString(R.string.valid_username));

Android Data Binding Recycler View twitches after adding element

I have fragment with RecycleView and Floating Action Button to add new object.
POJO:
public class MockCar extends BaseObservable {
private String name;
private String plateNumber;
public MockCar(String name, String plateNumber) {
this.name = name;
this.plateNumber = plateNumber;
}
#Bindable
public String getName() {
return name;
}
#Bindable
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.car);
}
#Bindable
public String getPlateNumber() {
return plateNumber;
}
#Bindable
public void setPlateNumber(String plateNumber) {
this.plateNumber = plateNumber;
notifyPropertyChanged(BR.car);
}
}
item.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">
<data>
<variable
name="car"
type="com.igor.touchless.model.MockCar"/>
<variable
name="click"
type="com.igor.touchless.adapter.interfaces.CarClickHandler"/>
</data>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_gravity="center"
android:padding="4dp"
android:background="#FFF"
card_view:cardCornerRadius="6dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="#{car.name}"
android:textColor="#color/primary_text"
android:textSize="18sp" />
<TextView
android:id="#+id/plate_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/name"
android:text="#{car.plateNumber}"
android:textColor="#color/secondary_text"
android:textSize="13sp" />
<ImageView
android:id="#+id/button_edit"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:background="#color/primary"
android:src="#drawable/ic_create_black_24dp"
app:civ_border_color="#00EEEEEE"
app:civ_border_width="0dp"
app:civ_shadow="false"
app:civ_shadow_color="#008BC34A"
app:civ_shadow_radius="0" />
<ImageView
android:id="#+id/button_remove"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#F44336"
android:src="#drawable/ic_clear_black_24dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</layout>
After pressing floating action button I add new item to collection
public void add(MockCar car) {
carList.add(car);
notifyDataSetChanged();
}
The problem is next - when I try to add elements more then can fit in the screen (8th and all next) I can see that recycler view twitches, doesn't matter I am at the beginning of the list or at the end. As far as I understand it updated all views if I update ArrayList or try to change any property of the object. I assume I made something wrong with it notifyPropertyChanged(BR.car), but have no idea how to deal with it.
If I use standard approach everything works as expected.
I just started learning android data binding. Sure somebody has already faced with this problem. Thanks in advance.

Categories

Resources