EditText is returning null when accessed from an a

2019-09-16 03:43发布

问题:

I have an adapter class which uses the getFilter function within a ListView. I wanted to modify it so that when the search is empty, the EditText text color becomes red. I have the following code which doesn't FC my app but the return string is blank instead of what is in the EditText

My partial adapter class:

@SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            data = (ArrayList<SetRows>)results.values;
            if (data.isEmpty()) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View myView = inflater.inflate(R.layout.main, null);
                EditText myTextView = (EditText) myView.findViewById(R.id.etSearch);
                myTextView.setTextColor(Color.RED);
                Toast.makeText(getContext(), myTextView.getText().toString(), 2000).show();
            }
            notifyDataSetChanged();
            clear();
            for(int i = 0, l = data.size(); i < l; i++)
                add(data.get(i));
            notifyDataSetInvalidated();
        }

How do I modify the code so that I can achieve the result?

回答1:

public class YourActivity extends Activity
{
    private EditText editText = null;
    // etc.

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

        editText = (EditText) findViewById(R.id.my_edit_text);
        // etc.
    }

    private Filter listFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint)
        {
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results)
        {
            ArrayList<SetRows> data = (ArrayList<SetRows>) results.values;
            if (data.isEmpty()) YourActivity.this.editText.setTextColor(Color.RED);
            Toast.makeText(getContext(), myTextView.getText().toString(), 2000).show();
        }
    };
}


回答2:

Try ... myTextView.getEditable().toString(), sometimes it works



回答3:

I don't think that the code involving LayoutInflater is doing what you think it is doing.

inflater.inflate(R.layout.main, null) will not get you an existing instance of R.layout.main; rather it uses the XML layout defined in main.xml to generate an entirely new View tree.

Assuming your main Activity is calling setContentView(R.layout.main), calling inflater.inflate(R.layout.main, null) will result in you have two completely separate instances of that layout in memory. A reference to an EditText in one of these trees will be in no way related to the reference in the other tree.

Once you have inflated the second View tree, you don't seem to do anything with it, so it is never displayed to the user. The user is still interacting with the layout you created in your Activity, while you are trying to get data from this second invisible tree.

How do I modify the code so that I can achieve the result?

There are a number of ways to do this, but without knowing how publishResults() is related to your Activity, it is difficult to recommend one. Here are some ideas:

  • Create a callback in your Activity that performs the desired operation
  • Pass a reference to your EditText to whatever class has the publishResults() method


回答4:

NOTE: The purpose of baseAdapters is to set data on your listview. So the checking must be done on the class where the EditText has been declared.

By utilizing the TextWatcher interface which checks the updated value of your EditText,

public class SearchActivity extends Activity implements TextWatcher{
    private EditText searchField;
    private SearchActivity activity;
    private ListView listView;
    private String [] matches; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.yourLayout);

        activity = this;
        searchField = (EditText)findViewById(R.id.searchField);
        searchField.addTextChangedListener(this);           


        listView = (ListView)findViewById(R.id.list);
        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                long arg3) {

               //your action
            }
        });
    }

    @Override
    public void afterTextChanged(final Editable searchField) {
        listView.setAdapter(null);

        //check for matches here and store it to newly created array of Strings

        if(searchField.length()>0 && matches.length > 0){   //added another condition here
            listView.setAdapter(new YourAdapter());         
        }else{
            this.searchField.setTextColor(Color.RED); // <--changes HERE
        }
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}

    @Override
    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
}