与 TextWatcher 相关的代码仅适用于一个 EditView
TextWatcher -related code works well only with one EditView
我有以下 issue.I 有一个 activity,动物收容所应用程序的一部分,用户必须在其中输入或编辑与宠物相关的数据,如重量、名称和 breed.What 我想要实现的是显示一个对话框,询问用户是否要继续编辑或离开 activity,这取决于他是否实际更改了 EditText 视图中的任何文本。
为此,我创建了一个布尔变量,如果文本被编辑/触发对话框/或者保持 false/do nothing/ 如果用户没有编辑任何内容,它应该变为真。
我已将 TextWatcher 附加到我的 EditText 字段,并尝试通过在 onTextChanged
或 beforeTextChanged
中将变量更改为 true。我尝试将 EditText 字段的哈希值或字符串值与 CharSequence charSequence
在 onTextChanged
方法中,但它只适用于其中一个 EditText fields/meaning 当用户更改文本/时它会触发对话框。每当我尝试将类似的逻辑应用于其余的 EditText 字段时以及功能中断和布尔变量保持 "true" 无论 what/meaning 用户看到对话框无论他们是否更改文本/。
我在内部 class 中尝试了各种比较、if 逻辑、switch 语句,但似乎没有任何内容 work.Kindly 看到代码 below.Thank 你。
/**
* Allows user to create a new pet or edit an existing one.
*/
public class EditorActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, TextWatcher {
/**
* EditText field to enter the pet's name
*/
private EditText mNameEditText;
/**
* EditText field to enter the pet's breed
*/
private EditText mBreedEditText;
/**
* EditText field to enter the pet's weight
*/
private EditText mWeightEditText;
/**
* EditText field to enter the pet's gender
*/
private Spinner mGenderSpinner;
/**
* Gender of the pet. The possible values are:
* 0 for unknown gender, 1 for male, 2 for female.
*/
public static int mGender;
public static String mPetName;
public static String mPetBreed;
public static String mPetWeight;
private static ArrayAdapter mGenderSpinnerAdapter;
private static Uri mSinglePetUri;
private static ContentValues mContentValues;
// we will show warning dialog to the user,if the below variable is true
private boolean mPetHasChanged;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// checks if we are about to edit the information about an existing pet or add
// a new pet record , adjusts the activity title accordingly and initializes/
// activates Loader only if we are updating an existing pet
mSinglePetUri = getIntent().getData();
if (mSinglePetUri != null) {
setTitle(R.string.edit_pet_activity_title);
getSupportLoaderManager().initLoader(0, null, this);
} else {
setTitle(getString(R.string.add_a_pet_activity_title));
}
// Find all relevant views that we will need to read user input from
mNameEditText = findViewById(R.id.edit_pet_name);
mBreedEditText = findViewById(R.id.edit_pet_breed);
mWeightEditText = findViewById(R.id.edit_pet_weight);
mGenderSpinner = findViewById(R.id.spinner_gender);
setupSpinner();
// watch for text changes
mNameEditText.addTextChangedListener(this);
mBreedEditText.addTextChangedListener(this);
mWeightEditText.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
int nameTextHashCode = mNameEditText.getText().hashCode();
int breedTextHashCode = mBreedEditText.getText().hashCode();
int weightTextHashCode = mWeightEditText.getText().hashCode();
boolean nameChanged = nameTextHashCode == charSequence.hashCode();
boolean breedChanged = breedTextHashCode == charSequence.hashCode();
boolean weightChanged = weightTextHashCode == charSequence.hashCode();
//this works-mPetHasChanged properly changes value
mPetHasChanged = nameChanged ;
//this doesn't work - the value is always true even when user didn't change a thing
mPetHasChanged = nameChanged||breedChanged||weightChanged;
}
@Override
public void afterTextChanged(Editable editable) {
}
}
然后在另一种方法中测试布尔值以显示或不显示对话框
if (!mPetHasChanged) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
return true;
}
// Otherwise if there are unsaved changes, setup a dialog to warn the user.
// Create a click listener to handle the user confirming that
// changes should be discarded.
DialogInterface.OnClickListener discardButtonClickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// User clicked "Discard" button, navigate to parent activity.
NavUtils.navigateUpFromSameTask(EditorActivity.this);
}
};
// Show a dialog that notifies the user they have unsaved changes
showUnsavedChangesDialog(discardButtonClickListener);
return true;
XML 布局:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Layout for the editor -->
<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:padding="@dimen/activity_margin"
tools:context=".EditorActivity">
<!-- Overview category -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_overview"
style="@style/CategoryStyle" />
<!-- Input fields -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:paddingLeft="4dp"
android:orientation="vertical">
<!-- Name field -->
<EditText
android:id="@+id/edit_pet_name"
android:hint="@string/hint_pet_name"
android:inputType="textCapWords"
style="@style/EditorFieldStyle" />
<!-- Breed field -->
<EditText
android:id="@+id/edit_pet_breed"
android:hint="@string/hint_pet_breed"
android:inputType="textCapWords"
style="@style/EditorFieldStyle" />
</LinearLayout>
</LinearLayout>
<!-- Gender category -->
<LinearLayout
android:id="@+id/container_gender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_gender"
style="@style/CategoryStyle" />
<!-- Input field -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:orientation="vertical">
<!-- Gender drop-down spinner -->
<Spinner
android:id="@+id/spinner_gender"
android:layout_height="48dp"
android:layout_width="wrap_content"
android:paddingRight="16dp"
android:spinnerMode="dropdown"/>
</LinearLayout>
</LinearLayout>
<!-- Measurement category -->
<LinearLayout
android:id="@+id/container_measurement"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_measurement"
style="@style/CategoryStyle" />
<!-- Input fields -->
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:paddingLeft="4dp">
<!-- Weight field -->
<EditText
android:id="@+id/edit_pet_weight"
android:hint="@string/hint_pet_weight"
android:inputType="number"
style="@style/EditorFieldStyle" />
<!-- Units for weight (kg) -->
<TextView
android:id="@+id/label_weight_units"
android:text="@string/unit_pet_weight"
style="@style/EditorUnitsStyle"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
当你只需要 mPetChanged 时,你为什么还要匹配 HashCodes
?
看这个:
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mPetHasChanged = !mNameEditText.getText().toString().trim().equals("") || !mBreedEditText.getText().toString().trim().equals("") || !mWeightEditText.getText().toString().trim().equals("");
}
您可以对每个 EditText
使用 If 来检查它们是否为空,但这看起来很简单。您也可以使用 isBlank()
,但 StringUtils()
带有 Apache
库,您可以使用 String.isEmpty()
,它在 Java 中可用,但 returns true
如果 EditText
只包含空格。
更新:你可以在onTextChanged(CharSequence charSequence, int start, int before, int count)
中比较start
和before
,如果start和before的值不一样,说明文本已经改变了。如下所示:
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int i2) {
mPetHasChanged = start!= before;
}
我花了很多时间反复试验,但我设法使代码以正确的方式工作。
@LalitFauzdar - 非常感谢你帮助我找到了 EditText
- 相关解决方案的一部分。:
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int i2) {
mPetHasChanged = start!= before;
}
另一部分原来是监听用户修改数据时删除按键。
然后我还必须通知用户未决更改,如果他在微调器中修改了他的选择,在我的 activity 中显示宠物的性别。
这个答案让我知道如何监听 "real" 用户对微调器所做的更改。
以下是与初始问题相关的部分代码:
/**
* Allows user to create a new pet or edit an existing one.
*/
public class EditorActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, TextWatcher, View.OnKeyListener, View.OnTouchListener {
/**
* EditText field to enter the pet's name
*/
private EditText mNameEditText;
/**
* EditText field to enter the pet's breed
*/
private EditText mBreedEditText;
/**
* EditText field to enter the pet's weight
*/
private EditText mWeightEditText;
/**
* EditText field to enter the pet's gender
*/
private Spinner mGenderSpinner;
/**
* Gender of the pet. The possible values are:
* 0 for unknown gender, 1 for male, 2 for female.
*/
public static int mGender;
public static String mPetName;
public static String mPetBreed;
public static String mPetWeight;
private static ArrayAdapter mGenderSpinnerAdapter;
private static Uri mSinglePetUri;
/**we will show warning dialog to the user,if the below variable is true*/
private boolean mPetHasChanged;
/**This flag turns to true if the spinner was actually touched by the user */
private boolean spinnerActivated;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// checks if we are about to edit the information about an existing pet or add
// a new pet record , adjusts the activity title accordingly and initializes/
// activates Loader only if we are updating an existing pet
mSinglePetUri = getIntent().getData();
if (mSinglePetUri != null) {
setTitle(R.string.edit_pet_activity_title);
getSupportLoaderManager().initLoader(0, null, this);
} else {
setTitle(getString(R.string.add_a_pet_activity_title));
}
// Find all relevant views that we will need to read user input from
mNameEditText = findViewById(R.id.edit_pet_name);
mBreedEditText = findViewById(R.id.edit_pet_breed);
mWeightEditText = findViewById(R.id.edit_pet_weight);
mGenderSpinner = findViewById(R.id.spinner_gender);
setupSpinner();
mNameEditText.addTextChangedListener(this);
mBreedEditText.addTextChangedListener(this);
mWeightEditText.addTextChangedListener(this);
mNameEditText.setOnKeyListener(this);
mBreedEditText.setOnKeyListener(this);
mWeightEditText.setOnKeyListener(this);
mGenderSpinner.setOnTouchListener(this);
}
/**
* Setup the dropdown spinner that allows the user to select the gender of the pet.
*/
private void setupSpinner() {
// Create adapter for spinner. The list options are from the String array it will use
// the spinner will use the default layout
mGenderSpinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.array_gender_options, android.R.layout.simple_spinner_item);
// Specify dropdown layout style - simple list view with 1 item per line
mGenderSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
// Apply the adapter to the spinner
mGenderSpinner.setAdapter(mGenderSpinnerAdapter);
// attach listener to the spinner to handle user selection from the pet's gender list.
mGenderSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selection = (String) parent.getItemAtPosition(position);
if (selection.equals(getString(R.string.gender_male))) {
mGender = PetsEntry.PET_GENDER_MALE;
} else if (selection.equals(getString(R.string.gender_female))) {
mGender = PetsEntry.PET_GENDER_FEMALE;
} else {
mGender = PetsEntry.PET_GENDER_UNKNOWN;
}
// if the Spinner was not actually touched by the user, the
//spinnerActivated flag is
//false and the method is exited earlier as there was not actual selection
//change,
//made by the user.This manages the behaviour of onItemSelected ,where the
// method is
//called twice - once when the spinner is initialized and once again if
// the user changes
//selection.
if (!spinnerActivated){
return;
}
mPetHasChanged=true;
}
// Because onItemSelectedListener is an interface, onNothingSelected must be
// defined
@Override
public void onNothingSelected(AdapterView<?> parent) {
mGender = PetsEntry.PET_GENDER_UNKNOWN;
}
});
}
//more code between,unrelated to topic
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
/**The logic in this method gets triggered if the user changes existing pet's data by
using
* any key except the delete one*/
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (start != before){
mPetHasChanged=true;
}
}
@Override
public void afterTextChanged(Editable editable) {
}
/** The logic in this method gets triggered if the user presses the delete button,
* while editing pet's data, so we won't miss any type of editing action*/
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
if (keyCode== KeyEvent.KEYCODE_DEL){
mPetHasChanged=true;
}
return false;
}
/**This method checks if the spinner was actually touched by the user and turns the
* flag variable to true and based on the flag's value we trigger the further logic in
* {#onItemSelected}*/
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
spinnerActivated=true;
return false;
}
}
我有以下 issue.I 有一个 activity,动物收容所应用程序的一部分,用户必须在其中输入或编辑与宠物相关的数据,如重量、名称和 breed.What 我想要实现的是显示一个对话框,询问用户是否要继续编辑或离开 activity,这取决于他是否实际更改了 EditText 视图中的任何文本。
为此,我创建了一个布尔变量,如果文本被编辑/触发对话框/或者保持 false/do nothing/ 如果用户没有编辑任何内容,它应该变为真。
我已将 TextWatcher 附加到我的 EditText 字段,并尝试通过在 onTextChanged
或 beforeTextChanged
中将变量更改为 true。我尝试将 EditText 字段的哈希值或字符串值与 CharSequence charSequence
在 onTextChanged
方法中,但它只适用于其中一个 EditText fields/meaning 当用户更改文本/时它会触发对话框。每当我尝试将类似的逻辑应用于其余的 EditText 字段时以及功能中断和布尔变量保持 "true" 无论 what/meaning 用户看到对话框无论他们是否更改文本/。
我在内部 class 中尝试了各种比较、if 逻辑、switch 语句,但似乎没有任何内容 work.Kindly 看到代码 below.Thank 你。
/**
* Allows user to create a new pet or edit an existing one.
*/
public class EditorActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, TextWatcher {
/**
* EditText field to enter the pet's name
*/
private EditText mNameEditText;
/**
* EditText field to enter the pet's breed
*/
private EditText mBreedEditText;
/**
* EditText field to enter the pet's weight
*/
private EditText mWeightEditText;
/**
* EditText field to enter the pet's gender
*/
private Spinner mGenderSpinner;
/**
* Gender of the pet. The possible values are:
* 0 for unknown gender, 1 for male, 2 for female.
*/
public static int mGender;
public static String mPetName;
public static String mPetBreed;
public static String mPetWeight;
private static ArrayAdapter mGenderSpinnerAdapter;
private static Uri mSinglePetUri;
private static ContentValues mContentValues;
// we will show warning dialog to the user,if the below variable is true
private boolean mPetHasChanged;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// checks if we are about to edit the information about an existing pet or add
// a new pet record , adjusts the activity title accordingly and initializes/
// activates Loader only if we are updating an existing pet
mSinglePetUri = getIntent().getData();
if (mSinglePetUri != null) {
setTitle(R.string.edit_pet_activity_title);
getSupportLoaderManager().initLoader(0, null, this);
} else {
setTitle(getString(R.string.add_a_pet_activity_title));
}
// Find all relevant views that we will need to read user input from
mNameEditText = findViewById(R.id.edit_pet_name);
mBreedEditText = findViewById(R.id.edit_pet_breed);
mWeightEditText = findViewById(R.id.edit_pet_weight);
mGenderSpinner = findViewById(R.id.spinner_gender);
setupSpinner();
// watch for text changes
mNameEditText.addTextChangedListener(this);
mBreedEditText.addTextChangedListener(this);
mWeightEditText.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
int nameTextHashCode = mNameEditText.getText().hashCode();
int breedTextHashCode = mBreedEditText.getText().hashCode();
int weightTextHashCode = mWeightEditText.getText().hashCode();
boolean nameChanged = nameTextHashCode == charSequence.hashCode();
boolean breedChanged = breedTextHashCode == charSequence.hashCode();
boolean weightChanged = weightTextHashCode == charSequence.hashCode();
//this works-mPetHasChanged properly changes value
mPetHasChanged = nameChanged ;
//this doesn't work - the value is always true even when user didn't change a thing
mPetHasChanged = nameChanged||breedChanged||weightChanged;
}
@Override
public void afterTextChanged(Editable editable) {
}
}
然后在另一种方法中测试布尔值以显示或不显示对话框
if (!mPetHasChanged) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
return true;
}
// Otherwise if there are unsaved changes, setup a dialog to warn the user.
// Create a click listener to handle the user confirming that
// changes should be discarded.
DialogInterface.OnClickListener discardButtonClickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// User clicked "Discard" button, navigate to parent activity.
NavUtils.navigateUpFromSameTask(EditorActivity.this);
}
};
// Show a dialog that notifies the user they have unsaved changes
showUnsavedChangesDialog(discardButtonClickListener);
return true;
XML 布局:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Layout for the editor -->
<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:padding="@dimen/activity_margin"
tools:context=".EditorActivity">
<!-- Overview category -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_overview"
style="@style/CategoryStyle" />
<!-- Input fields -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:paddingLeft="4dp"
android:orientation="vertical">
<!-- Name field -->
<EditText
android:id="@+id/edit_pet_name"
android:hint="@string/hint_pet_name"
android:inputType="textCapWords"
style="@style/EditorFieldStyle" />
<!-- Breed field -->
<EditText
android:id="@+id/edit_pet_breed"
android:hint="@string/hint_pet_breed"
android:inputType="textCapWords"
style="@style/EditorFieldStyle" />
</LinearLayout>
</LinearLayout>
<!-- Gender category -->
<LinearLayout
android:id="@+id/container_gender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_gender"
style="@style/CategoryStyle" />
<!-- Input field -->
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:orientation="vertical">
<!-- Gender drop-down spinner -->
<Spinner
android:id="@+id/spinner_gender"
android:layout_height="48dp"
android:layout_width="wrap_content"
android:paddingRight="16dp"
android:spinnerMode="dropdown"/>
</LinearLayout>
</LinearLayout>
<!-- Measurement category -->
<LinearLayout
android:id="@+id/container_measurement"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Label -->
<TextView
android:text="@string/category_measurement"
style="@style/CategoryStyle" />
<!-- Input fields -->
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="2"
android:paddingLeft="4dp">
<!-- Weight field -->
<EditText
android:id="@+id/edit_pet_weight"
android:hint="@string/hint_pet_weight"
android:inputType="number"
style="@style/EditorFieldStyle" />
<!-- Units for weight (kg) -->
<TextView
android:id="@+id/label_weight_units"
android:text="@string/unit_pet_weight"
style="@style/EditorUnitsStyle"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
当你只需要 mPetChanged 时,你为什么还要匹配 HashCodes
?
看这个:
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mPetHasChanged = !mNameEditText.getText().toString().trim().equals("") || !mBreedEditText.getText().toString().trim().equals("") || !mWeightEditText.getText().toString().trim().equals("");
}
您可以对每个 EditText
使用 If 来检查它们是否为空,但这看起来很简单。您也可以使用 isBlank()
,但 StringUtils()
带有 Apache
库,您可以使用 String.isEmpty()
,它在 Java 中可用,但 returns true
如果 EditText
只包含空格。
更新:你可以在onTextChanged(CharSequence charSequence, int start, int before, int count)
中比较start
和before
,如果start和before的值不一样,说明文本已经改变了。如下所示:
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int i2) {
mPetHasChanged = start!= before;
}
我花了很多时间反复试验,但我设法使代码以正确的方式工作。
@LalitFauzdar - 非常感谢你帮助我找到了 EditText
- 相关解决方案的一部分。:
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int i2) {
mPetHasChanged = start!= before;
}
另一部分原来是监听用户修改数据时删除按键。 然后我还必须通知用户未决更改,如果他在微调器中修改了他的选择,在我的 activity 中显示宠物的性别。 这个答案让我知道如何监听 "real" 用户对微调器所做的更改。 以下是与初始问题相关的部分代码:
/**
* Allows user to create a new pet or edit an existing one.
*/
public class EditorActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, TextWatcher, View.OnKeyListener, View.OnTouchListener {
/**
* EditText field to enter the pet's name
*/
private EditText mNameEditText;
/**
* EditText field to enter the pet's breed
*/
private EditText mBreedEditText;
/**
* EditText field to enter the pet's weight
*/
private EditText mWeightEditText;
/**
* EditText field to enter the pet's gender
*/
private Spinner mGenderSpinner;
/**
* Gender of the pet. The possible values are:
* 0 for unknown gender, 1 for male, 2 for female.
*/
public static int mGender;
public static String mPetName;
public static String mPetBreed;
public static String mPetWeight;
private static ArrayAdapter mGenderSpinnerAdapter;
private static Uri mSinglePetUri;
/**we will show warning dialog to the user,if the below variable is true*/
private boolean mPetHasChanged;
/**This flag turns to true if the spinner was actually touched by the user */
private boolean spinnerActivated;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// checks if we are about to edit the information about an existing pet or add
// a new pet record , adjusts the activity title accordingly and initializes/
// activates Loader only if we are updating an existing pet
mSinglePetUri = getIntent().getData();
if (mSinglePetUri != null) {
setTitle(R.string.edit_pet_activity_title);
getSupportLoaderManager().initLoader(0, null, this);
} else {
setTitle(getString(R.string.add_a_pet_activity_title));
}
// Find all relevant views that we will need to read user input from
mNameEditText = findViewById(R.id.edit_pet_name);
mBreedEditText = findViewById(R.id.edit_pet_breed);
mWeightEditText = findViewById(R.id.edit_pet_weight);
mGenderSpinner = findViewById(R.id.spinner_gender);
setupSpinner();
mNameEditText.addTextChangedListener(this);
mBreedEditText.addTextChangedListener(this);
mWeightEditText.addTextChangedListener(this);
mNameEditText.setOnKeyListener(this);
mBreedEditText.setOnKeyListener(this);
mWeightEditText.setOnKeyListener(this);
mGenderSpinner.setOnTouchListener(this);
}
/**
* Setup the dropdown spinner that allows the user to select the gender of the pet.
*/
private void setupSpinner() {
// Create adapter for spinner. The list options are from the String array it will use
// the spinner will use the default layout
mGenderSpinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.array_gender_options, android.R.layout.simple_spinner_item);
// Specify dropdown layout style - simple list view with 1 item per line
mGenderSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
// Apply the adapter to the spinner
mGenderSpinner.setAdapter(mGenderSpinnerAdapter);
// attach listener to the spinner to handle user selection from the pet's gender list.
mGenderSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selection = (String) parent.getItemAtPosition(position);
if (selection.equals(getString(R.string.gender_male))) {
mGender = PetsEntry.PET_GENDER_MALE;
} else if (selection.equals(getString(R.string.gender_female))) {
mGender = PetsEntry.PET_GENDER_FEMALE;
} else {
mGender = PetsEntry.PET_GENDER_UNKNOWN;
}
// if the Spinner was not actually touched by the user, the
//spinnerActivated flag is
//false and the method is exited earlier as there was not actual selection
//change,
//made by the user.This manages the behaviour of onItemSelected ,where the
// method is
//called twice - once when the spinner is initialized and once again if
// the user changes
//selection.
if (!spinnerActivated){
return;
}
mPetHasChanged=true;
}
// Because onItemSelectedListener is an interface, onNothingSelected must be
// defined
@Override
public void onNothingSelected(AdapterView<?> parent) {
mGender = PetsEntry.PET_GENDER_UNKNOWN;
}
});
}
//more code between,unrelated to topic
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
/**The logic in this method gets triggered if the user changes existing pet's data by
using
* any key except the delete one*/
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (start != before){
mPetHasChanged=true;
}
}
@Override
public void afterTextChanged(Editable editable) {
}
/** The logic in this method gets triggered if the user presses the delete button,
* while editing pet's data, so we won't miss any type of editing action*/
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
if (keyCode== KeyEvent.KEYCODE_DEL){
mPetHasChanged=true;
}
return false;
}
/**This method checks if the spinner was actually touched by the user and turns the
* flag variable to true and based on the flag's value we trigger the further logic in
* {#onItemSelected}*/
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
spinnerActivated=true;
return false;
}
}