TextWatcher相关的代码仅适用于一个EditView

问题描述 投票:0回答:1

我有以下问题。我正在做一个动物庇护所应用程序的一部分,用户必须输入或编辑与宠物有关的数据,如体重,名称和品种。我想要实现的是显示一个对话框,询问用户是否要继续编辑或退出活动,这取决于他是否实际更改了EditText视图中的任何文本。为此,我创建了一个布尔变量,如果对文本进行了编辑/触发对话框,则应将其设置为true /,或者如果用户未进行任何编辑,则应设置为false /不执行任何操作。我已将TextWatcher附加到我的EditText字段,并尝试通过在onTextChangedbeforeTextChanged中执行此操作将变量更改为true。我尝试将EditText字段的哈希或字符串值与CharSequence charSequence中的onTextChanged进行比较]方法,但仅适用于EditText字段之一,这意味着当用户更改text /时,它将触发对话框。每当我尝试对其余EditText字段应用类似的逻辑时,功能就会中断并且布尔变量保持不变无论用户是什么意思,无论用户是否更改文本,都将看到“ true”。我在内部类中尝试了各种比较,if-logic,switch语句,但似乎无济于事。请参见下面的代码。谢谢。

/**
 * 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>
java android android-edittext android-textwatcher
1个回答
0
投票

当您只需要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中提供,您可以使用Java中可用的String.isEmpty(),但如果true仅包含空格,它将返回EditText

更新:您可以比较start中的beforeonTextChanged(CharSequence charSequence, int start, int before, int count),如果start和before的值不同,则表示文本已更改。如下提供:

@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int i2) {
    mPetHasChanged = start!= before;
}
© www.soinside.com 2019 - 2024. All rights reserved.