单击项目时 ListView 挂起
ListView hangs when i click on an Item
我有一个 selectWord()
函数来填充两个字符串和一个 ArrayList
,然后它将它们(字符串)放入 ListView
和 TextView
.
我想要做的是,当有人点击 listItem
时,字符串和 ArrayList
应该更改它们的值并将新值放入 TextView
和 ListView
.
我创建了一个函数,可以从文本文件中提取 selects 个单词,然后在 ClickListener
中将数据显示到视图中;我所做的是再次调用相同的函数,以便它 selects 来自文本文件的数据并将其放入视图中。 (一个测验类型的应用程序,select一个选项,然后是下一个问题)
几天前我写了类似的代码。
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
。所以当你从 inside 调用 selectWord();
这个 ClickListener
它挂起...... 为什么?: 仅仅因为你是-创建 ArrayAdapter<String>
并在 ListView
.
中再次设置它
与其要求它自杀(即从地面重新创建自己),您可以要求 ArrayAdapter
更改其数据,这样 ListView
仍将使用相同的 ArrayAdapter
.在这种情况下,您应该通知更改,如下所示:
- 首先从
selectWord()
方法中删除 ArrayAdapter<String> adapter = ..
和 optionView.setAdapter
。
- 创建global
ArrayAdapter
并在selectWord()
方法外的ListView
中设置。
- 然后每次你想改变选项..etc调用
selectWord()
.
- 然后清除
ArrayAdapter
并重新填充它。
- 最后通知更改。
// 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
})});
我有一个 selectWord()
函数来填充两个字符串和一个 ArrayList
,然后它将它们(字符串)放入 ListView
和 TextView
.
我想要做的是,当有人点击 listItem
时,字符串和 ArrayList
应该更改它们的值并将新值放入 TextView
和 ListView
.
我创建了一个函数,可以从文本文件中提取 selects 个单词,然后在 ClickListener
中将数据显示到视图中;我所做的是再次调用相同的函数,以便它 selects 来自文本文件的数据并将其放入视图中。 (一个测验类型的应用程序,select一个选项,然后是下一个问题)
几天前我写了类似的代码。
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
。所以当你从 inside 调用 selectWord();
这个 ClickListener
它挂起...... 为什么?: 仅仅因为你是-创建 ArrayAdapter<String>
并在 ListView
.
与其要求它自杀(即从地面重新创建自己),您可以要求 ArrayAdapter
更改其数据,这样 ListView
仍将使用相同的 ArrayAdapter
.在这种情况下,您应该通知更改,如下所示:
- 首先从
selectWord()
方法中删除ArrayAdapter<String> adapter = ..
和optionView.setAdapter
。 - 创建global
ArrayAdapter
并在selectWord()
方法外的ListView
中设置。 - 然后每次你想改变选项..etc调用
selectWord()
. - 然后清除
ArrayAdapter
并重新填充它。 - 最后通知更改。
// 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
})});