簡體   English   中英

單擊項目時ListView掛起

[英]ListView hangs when i click on an Item

我有一個selectWord()函數,該函數填充兩個字符串和一個ArrayList ,然后將它們(字符串)放入ListViewTextView

我要做的是,當有人單擊listItem ,字符串和ArrayList應該更改其值,並將新值放在TextViewListView

我創建了一個函數,該函數從文本文件中選擇單詞,然后在ClickListener數據顯示到視圖中; 我所做的是再次調用同一函數,以便它從文本文件中選擇數據並將其放入視圖中。 測驗類型的應用程序,選擇一個選項,然后選擇下一個問題

我幾天前寫了類似的代碼來工作。

public class MainActivity extends AppCompatActivity {

    private ArrayList<String> words = new ArrayList<>();    //words list
    private ArrayList<String> defns = new ArrayList<>();    //deffinitions
    private String word;
    private String correct;
    public ArrayList<String> randOptions = new ArrayList<>();
    private Random randy = new Random();
    private TextView wordView;
    private ListView optionView;

    public void readFile() { //works fine
        //populate the ArrayLists
        String word, defn;
        Scanner file = new Scanner(getResources().openRawResource(raw.dictionary1));

        while(file.hasNextLine()) {
              String line = file.nextLine();
              String[] lineArray = line.split(" ");
              if (lineArray.length >= 2) {
                  word = lineArray[0];
                  defn = lineArray[1];
                  words.add(word);
                  defns.add(defn);
              }
          }
    }

    public void selectWord() {

        readFile(); //read file
        //get some data
        int rand = randy.nextInt(words.size());
        this.word = words.get(rand);
        this.correct = defns.get(rand);

        //make 4 diff options
        randOptions.add(correct);

        for(int i=0; i<3; i++) {
            rand = randy.nextInt(defns.size());
            if(randOptions.contains(defns.get(rand)))
                    i--;
            else
                randOptions.add(defns.get(rand));
        }
        Collections.shuffle(randOptions);

        //add the data to views
        wordView.setText(this.word);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, randOptions);
        optionView.setAdapter(adapter);
    }

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(layout.activity_main);

        wordView = findViewById(id.currentWord);
        optionView = findViewById(id.options);

        selectWord();

        optionView.setOnItemClickListener(
              new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                       String selected = ((TextView) view).getText().toString();
                       if (correct.equals(selected)) {
                           Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show();
                       } else {
                              Toast.makeText(MainActivity.this, "Wrong", Toast.LENGTH_SHORT).show();
                       }
                       selectWord(); //so that it changes the vlaues in views but when I add that 
                       //line my hangs there soon as I click on the list item
               }
           }
       );    
}

optionView.setOnItemClickListener(...)使用AdapterView 因此,當您調用selectWord(); 從此ClickListener 內部掛起... 為什么? :僅僅因為您正在重新創建ArrayAdapter<String>並在ListView再次進行設置。

您可以要求ArrayAdapter更改其數據,以便ListView仍使用相同的ArrayAdapter而不是要求它殺死自己(即從地面重新創建自己)。 在這種情況下,您應該通知更改,如下所示:

  1. 首先從selectWord()方法中刪除ArrayAdapter<String> adapter = ..optionView.setAdapter
  2. 創建全局 ArrayAdapter並將其設置在selectWord()方法外部的ListView
  3. 然后,每次您要更改選項selectWord()請調用selectWord()
  4. 然后清除ArrayAdapter並再次填充它。
  5. 最后通知更改。

// create this method to update the options (re-populate the ArrayAdapter)
// of course ArrayAdapter and randOptions should be GLOBAL
public void updateOptions() {
    adapter.clear(); 
    if (randOptions != null){
       for (String option : randOptions) {
           adapter.insert(option,adapter.getCount());
        }
    }     
    adapter.notifyDataSetChanged();
} 

// first declare the ArrayAdapter globally as a field
ArrayAdapter<String> adapter;

// inside onCreate() method, initialize the ArrayAdapter (i.e. outside the `selectWord()` method) 
// using this constructor: ArrayAdapter(Context context, int resource)
adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1);

// after that, set the adapter (it's empty by now)
optionView.setAdapter(adapter);

// fill the Random Options Array
selectWord();
// call update options
updateOptions();

// and use it inside the CLickListener like this
optionView.setOnItemClickListener(
          new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                // whatever ...
                selectWord(); //so that it changes the options in the array
                updateOptions(); // update options in the same ArrayAdapter
})});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM