addTextChangedListener()多次触发,并列出listview中的所有edittext字段

时间:2016-05-11 15:34:26

标签: android listview

我有一个列表视图,其中包含4个列表项,每个列表项包含2个文本视图和1个edittext视图。我在自定义适配器中定义了一个addTextChangedListener,以查找edittext中的更改,然后保存文本。

当列表项2,3和4中的edittext视图中的文本被更改时,addTextChangedListener将触发一次,但是当单击列表项1中的编辑文本时,它会多次触发。此外,当我打印从基本适配器单击的列表项的位置时,它显示所有4个列表项都已循环。

有人可以解释为什么会这样,请提出解决方案。

下面是代码和logcat输出。

列表视图XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.dumbrella.uidesign.ListView">


<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/listView"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="20dp"
    android:descendantFocusability="beforeDescendants" />

<Button
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Submit"
    android:id="@+id/btnSubmit"
    android:layout_below="@+id/listView"
    android:layout_centerHorizontal="true" />

</RelativeLayout>

列出项目XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textSize="32dp"
    android:text="IC"
    android:gravity="center"
    android:id="@+id/questionIcon"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="Small Text"
    android:id="@+id/questionText"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_toRightOf="@+id/questionIcon"
    android:layout_toEndOf="@+id/questionIcon"
    android:layout_alignParentTop="true" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/userAnswer"
    android:layout_alignParentBottom="true"
    android:layout_toRightOf="@+id/questionIcon"
    android:layout_alignRight="@+id/questionText"
    android:layout_alignEnd="@+id/questionText"
    android:inputType="text"
    android:textSize="12dp"/>

</RelativeLayout>

列表视图活动:

import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class QuestionsListView extends AppCompatActivity {

String TAG = "Question List View Activity";

ArrayList<ListData> adapterList = new ArrayList<ListData>();
ListView listViewDetail;
QuestionsAdapter mQuestionAdapter;
SharedPreferences userAnswersSharedPreferences;
SharedPreferences.Editor userAnswersSharedPreferencesEditor;

private String[] questionIcon = new String[]{
        "T", "W", "M", "C"
};

private String[] questionDescription = new String[]{
        "Question1?", "Question2?", "Question3?", "Question4?"
};

private String[] userAnswerHint = new String[]{
        "Answer1", "Answer2", "Answer3", "Answer4"
};

private String[] userAnswers = new String[] {
        "Null", "Null", "Null", "Null"
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view);

    listViewDetail = (ListView) findViewById(R.id.listView);

    getDataInList();
    mQuestionAdapter = new QuestionsAdapter();
    listViewDetail.setAdapter(mQuestionAdapter);

    userAnswersSharedPreferences = getSharedPreferences("UserAnswersPreferences", Context.MODE_PRIVATE);
    userAnswersSharedPreferencesEditor = userAnswersSharedPreferences.edit();

    Button btnSubmit = (Button) findViewById(R.id.btnSubmit);
    btnSubmit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            for (int i=0; i<questionIcon.length; i++) {

                ListData currentListData1 = mQuestionAdapter.getItem(i);
                Log.v("TAG" , currentListData1.getQuestionIcon());
                Log.v("TAG" , currentListData1.getQuestionDescription());
                Log.v("TAG" , currentListData1.getUserAnswerHint());
                Log.v("TAG" , currentListData1.getUserAnswer());
            }
        }
    });
}

private void getDataInList() {
    for (int i = 0; i < questionIcon.length; i++) {
        // Create a new object for each list item
        ListData listData = new ListData();
        listData.setQuestionIcon(questionIcon[i]);
        listData.setQuestionDescription(questionDescription[i]);
        listData.setUserAnswerHint(userAnswerHint[i]);
        listData.setUserAnswer("Null");
        // Add this object into the ArrayList myList
        adapterList.add(listData);
    }
}

public class QuestionsAdapter extends BaseAdapter {

    @Override
    public int getCount() {
        return adapterList.size();
    }

    @Override
    public ListData getItem(int position) {
        return adapterList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_item, parent, false);
        }

        final TextView questionText = (TextView) convertView.findViewById(R.id.questionText);
        final TextView questionIcon = (TextView) convertView.findViewById(R.id.questionIcon);
        final EditText userAnswer = (EditText) convertView.findViewById(R.id.userAnswer);

        final ListData currentListData = getItem(position);

        questionIcon.setText(currentListData.getQuestionIcon());
        questionText.setText(currentListData.getQuestionDescription());
        //userAnswer.setHint(currentListData.getUserAnswerHint());

        questionIcon.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.v("TAG", "In Listener");
                questionIcon.setText("Z");
            }
        });

        userAnswer.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                Log.v("ListView Adapter After", "Text Changed to :" + s.toString());
                Log.v("ListView Adapter After", "List Item Clicked :" + String.valueOf(position));
                currentListData.setUserAnswer(userAnswer.getText().toString());
                switch (position) {
                    case 0:
                        userAnswersSharedPreferencesEditor.putString("T",s.toString());
                        break;
                    case 1:
                        userAnswersSharedPreferencesEditor.putString("W",s.toString());
                        break;
                    case 2:
                        userAnswersSharedPreferencesEditor.putString("M",s.toString());
                        break;
                    case 3:
                        userAnswersSharedPreferencesEditor.putString("C",s.toString());
                        break;
                }
                userAnswersSharedPreferencesEditor.commit();
                userAnswers[position] = currentListData.getUserAnswer();
            }
        });

        return convertView;
    }
}

private class ListData {

    private String questionIcon;
    private String questionDescription;
    private String userAnswerHint;
    private String userAnswer;

    public String getQuestionIcon() {
        return questionIcon;
    }

    public void setQuestionIcon(String questionIcon) {
        this.questionIcon = questionIcon;
    }

    public String getQuestionDescription() {
        return questionDescription;
    }

    public void setQuestionDescription(String questionDescription) {
        this.questionDescription = questionDescription;
    }

    public String getUserAnswerHint() {
        return userAnswerHint;
    }

    public void setUserAnswerHint(String userAnswerHint) {
        this.userAnswerHint = userAnswerHint;
    }

    public String getUserAnswer() {
        return userAnswer;
    }

    public void setUserAnswer(String userAnswer) {
        this.userAnswer = userAnswer;
    }
}
}

Logcat输出:(当列表项2,3和4中的文本被更改时)

05-11 20:58:03.453 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:58:03.453 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :2 


05-11 20:58:03.453 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:58:03.453 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :3

05-11 20:58:03.453 3914-3914 / com.dumbrella.uidesign V / ListView Adapter After:Text Changed to:f    05-11 20:58:03.453 3914-3914 / com.dumbrella.uidesign V / ListView Adapter After:List Item Clicked:4

Logcat输出:(当列表项1中的文本被更改时)

05-11 20:59:22.928 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.928 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :0
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :1
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :2
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :3
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :0
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :1
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :2
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :3
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :0
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :1
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.929 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :2
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :3
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign 
V/ListView Adapter After: Text Changed to :f
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :0
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :1
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :2
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
 05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :3
  05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: Text Changed to :f
  05-11 20:59:22.930 3914-3914/com.dumbrella.uidesign V/ListView Adapter After: List Item Clicked :0

3 个答案:

答案 0 :(得分:1)

zgc7009是正确的,因为您没有正确接近getView方法。虽然你对如何膨胀视图没有错。我怀疑的问题是,无法保证调用getView多少次TextWatcherEditText个侦听器添加到TextWatcher。起初我以为你只能向EditText添加一个addTextChangedListener监听器,但事实证明你可以添加很多。这是public void addTextChangedListener(TextWatcher watcher) { if (mListeners == null) { mListeners = new ArrayList<TextWatcher>(); } mListeners.add(watcher); } 方法的来源:

getView

反正。 if(currentListData.hasListener) { // Just an example. You define the logic or how you want to store the TextWatcher listener userAnswer.addTextChangedListener(new TextWatcher() { //le code } } 被称为多个时间并添加越来越多的侦听器。但是你无法知道这将会是多少次。您需要将侦听器与数据或其他方式相关联。这样您就可以检查是否应该添加侦听器。如下所示:

  if (convertView == null) {

        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.list_item, parent, false);
        EditText userAnswer = (EditText) convertView.findViewById(R.id.userAnswer);
        userAnswer.addTextChangedListener(new TextWatcher() {
            //le code
            @Override
            public void afterTextChanged(Editable s) {
                //Figure out the best way to get the current position.
            }
        }
    }

我当然不会为你编写代码。但那就是如何解决它。

修改

实际上,在考虑更多之后,你甚至不应该创造比必要更多的听众。在给视图充气时添加监听器。

{{1}}

答案 1 :(得分:0)

在通过TextWatcher

设置新实例之前,您需要删除所有Adapter个实例

Here您可以找到解决方案

答案 2 :(得分:0)

最好动态添加布局而不是ListView项。处理EditText中的ListView非常重要。

这是我的建议。

第1步:添加LinearLayout而不是ListView。它的方向必须垂直

第2步:在此LinearLayout上动态添加列表项布局,初始化其组件并将Value设置为该组件。

以下示例可以动态地将布局添加到LinearLayout中:

List<EditText> lists=new ArrayList<EditText>();
LinearLayout options_layout = (LinearLayout) findViewById(R.id.root_layout);
for (int i = 0; i < 4; i++) {
  View to_add = inflater.inflate(R.layout.list_element,
                        options_layout,false);

  EditText text = (EditText) to_add.findViewById(R.id.your_edit_text);
  text.setText("YOUR VALUE");
  lists.add(text);

  options_layout.addView(to_add);
}

第3步:将所有EditText添加到每个List<EditText>的{​​{1}}和addTextChangedListener

EditText来电回复后,您可以通过afterTextChanged上的简单循环从EditText获取所有List<EditText>值。

希望这会对你有所帮助:)。