Как правильно установить setOnItemClickListener в класс non-activity, который заполняет ListView из класса Activity

Мой ListView создается динамически из HashMap в зависимости от того, что пользователь вводит в EditText в классе без активности. Причина, по которой я полагаю, что это связано с setOnItemClickListener, заключается в том, что она работает, когда я устанавливаю значения ListView вручную в классе Activity в методе OnCreate. Класс non-activity содержит несколько методов, таких как AsyncTask и метод рекурсии.

Класс активности

public class WordEntry extends AppCompatActivity implements OnClickListener, OnItemClickListener {

//Variable Declared

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

    /*Code for reading values into HashMap here*/

    btn_Resolve = (Button) findViewById(R.id.submit_word);
    btn_Resolve.setOnClickListener(this);

    //TODO Make list item clickable.

    spin_options = (Spinner) findViewById(R.id.spin_choose_resolver_type);
    ArrayAdapter<CharSequence> spin_adapter = ArrayAdapter.createFromResource(this,
            R.array.resolver_options, R.layout.simpler_spinner_item);

    spin_adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
    spin_options.setAdapter(spin_adapter);
    lv_words = (ListView) findViewById(R.id.lv_word_display);

    /*This following two lines were a test to see if manually setting the adapter worked, it did. */
    //lv_words.setAdapter(spin_adapter);
    //lv_words.setOnItemClickListener(this);


}

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    Log.i("HelloListView", "You clicked item: " + parent + " at position: " + position);

}


@Override
public void onClick(View v) {

    switch (v.getId()) {
        case R.id.submit_word:

            edt_WordEntry = (EditText) findViewById(R.id.word_entry_textbox);
            word = edt_WordEntry.getText().toString().toLowerCase();
            Pattern pattern = Pattern.compile("\\s");
            Matcher matcher = pattern.matcher(word);
            boolean space_found = matcher.find();
            View hideKey = this.getCurrentFocus();

            if (space_found) {
               edt_WordEntry.setText(R.string.no_spaces_allowed);

            } else {
                ResolveWord fixAnagram = new ResolveWord(word, this,wordHashSet);
                ResolveAllWords fixAnagramAll = new ResolveAllWords(word,this,wordHashSet);

                /*The following two lines are two other methods that I tried during debugging to try get it working. Separately of                  course and this debugging was for when the spinner was set to something other than "Anagram's"*/
                //fixAnagramAll.lv_words.setOnItemClickListener(new ResolveWord(word,this,wordHashSet));  
                //lv_words.setOnItemClickListener(new ResolveWord(word,this,wordHashSet));                           
                if(spin_options.getSelectedItem().toString().equals("Anagram;s")) {
                    hideKeyboard(this);
                    fixAnagram.execute();
                } else {
                    hideKeyboard(this);
                    fixAnagramAll.execute();
                }
            }
            break;

        default:
            break;
    }

}

Класс без занятий

public class ResolveWord extends  AsyncTask<Void, Integer, ArrayList<String>> implements OnItemClickListener {

 /*Variable Declared*/


public ResolveWord(String letters, Activity wordEntryContext, HashSet<String> passedHashSet) {
    /*Variables initiated */

}


   /*Some code.....*/

@Override
protected void onPostExecute(ArrayList<String> wordSuccess) {

    /*Code which puts data into an arraylist so I can put into the array adadater that follows...*/

    ArrayAdapter<String> adapter = new ArrayAdapter<>(thisContext,R.layout.lv_displaywrods_wordentry,
            wordSuccess);

    //Ways I tried to get the ListView clickable in the non-activity class...
    lv_words.setAdapter(adapter);

    //lv_words.setOnItemClickListener(new WordEntry());
    //lv_words.setOnItemClickListener(this);

   /*lv_words.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //I have a break point here to see if the string gets assigned during debugging after clicking a rowitem.
        String x = "Test";

    }
});*/

    //This always returns false
    boolean o = lv_words.hasOnClickListeners();
    //This always returns true
    boolean p = lv_words.isClickable();


}

В дополнение к вышеуказанному коду я также сделал некоторые изменения недавно, когда решил, что решил, и создал onItemClickListener в классе активности в методе onCreate и назначил это значение с помощью getOnItemClickListener. Затем я передал его классу non-activity через конструктор, но это также не сработало.

0
задан 20 июля '16 в 16:31
источник поделиться
4 ответов

За кулисами ArrayAdapter использует метод toString() для каждой записи в массиве ArrayList (или массиве), предоставленной ему, и заполняет макет, указанный во втором аргументе используемого вами конструктора.

Если список массивов wordSuccess не пуст, тогда ваше сопоставление записи с этим макетом не выполняется. ArrayAdapter ожидает TextView или что-то, что является производным от него как второй аргумент в этом конструкторе. Ваш файл макета lv_displaywords_wordentry, скорее всего, не является прямым текстовым или не содержит TextView, который был связан с каким-то контейнером ViewGroup. Поскольку вы показываете простые элементы списка, я бы рекомендовал вам использовать android.R.layout.simple_list_item_1, и если ваш список массивов не пуст, вы должны увидеть слова, которые появляются.

РЕДАКТИРОВАТЬ:

Как я уже догадался, из комментариев я понимаю, что вы пытаетесь передать макет, который разрешает ListView вместо TextView в вашем ArrayAdapter. Вы можете использовать ListView нормально, но у вашего адаптера нет способа сопоставления записи String в списке массивов с объектом ListView (поскольку ListView представляет всю коллекцию, а отображение выполняется на основе один на один). Вот почему вам нужно передать TextView (или пользовательский подкласс или его вариант). Используйте макет списка элементов для Android, и вы должны получить стандартный TextView.

1
ответ дан 23 июля '16 в 13:12
источник

В AsyncTask вы можете установить OnClickListeners в методе onPostExecute и один метод onPreExecute.
Вы не можете добавить OnClickListener или выполнять какие-либо операции пользовательского интерфейса в методе doInBackground, поскольку вы выполняете сетевые операции.

Таким образом, вы можете установить OnClickListener OnClickListener:

lv_words.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick() {
        // Do some coding...
    }
});
1
ответ дан 20 июля '16 в 16:37
источник

Вы можете попытаться сделать сеттер для ResolveWord для передачи объекта WordEntry - wordEntry в ResolveWord и в onPostExecute (...) write: lv_words.setOnItemClickListener(wordEntry);

0
ответ дан 20 июля '16 в 17:04
источник

Трудно понять вас, но я думаю, вы собираетесь архивировать следующее:

public class ResolveWord extends  AsyncTask<Void, Integer, ArrayList<String>> {
    private Activity wordEntryContext;

   public ResolveWord(String letters, Activity wordEntryContext, HashSet<String> passedHashSet) {
       this.wordEntryContext = wordEntryContext;
       /*Other variables initiated */ 
   } 

   @Override 
   protected void onPostExecute(ArrayList<String> wordSuccess) {
       // your code
       lv_words.setOnItemClickListener((OnItemClickListener)wordEntryContext); 
   }

}
0
ответ дан 23 июля '16 в 13:59
источник

Другие вопросы по меткам или Задайте вопрос