编辑:我的问题似乎是BaseAdapter
只是不会发布超过1个Spinner。如果我将数组的大小更改为0,它就不会放任何东西,但是超过1的任何东西都会截断它。它永远不会从getView()
传递位置0,它永远不会超过1.我已经在它上面了好几个小时。有这个原因吗?
我遇到使用Spinners
在ListView
中动态添加BaseAdapter
的问题。我之前尝试过它作为测试,以确保它可以在测试类中正确完成,并且它正确地迭代位置。但是现在我再次这样做并且失败了。我的意思是失败而不是getView()
创建新的Spinner
,它永远不会离开位置0.它仍然运行。永远不要添加更多Spinner
s。
这是我的代码:
主适配器代码
public class RemindersAdapter extends BaseAdapter{
Spinner[] shownReminders = new Spinner[1];
TextView[] removeReminders = new TextView[1];
String[] reminders = new String[1]; //this hlds the values of the coresponding spinner
RemindersAdapter mAdapter;
@Override
public int getCount() {
return shownReminders.length;
}
@Override
public Object getItem(int position) {
return shownReminders[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
Log.d("TAG", "A NEW SPINNER AND TEXTVIEW IS CREATED HERE WITH POSITION"+position);
if(view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.reminder_spinner, parent, false);
}
Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminder_spinner);
reminderSpinner.setTag(String.valueOf(position));
ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource(
parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item);
reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
reminderSpinner.setAdapter(reminderAdapter);
reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener());
shownReminders[position] = reminderSpinner;
TextView remove = (TextView)view.findViewById(R.id.remove_reminder);
remove.setTag(String.valueOf(position));
removeReminders[position] = remove;
remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("The Array positioning of this remove view is: ", ""+v.getTag());
}
});
return view;
}
public void addReminder() {
Log.d("addReminder METHOD", "The Add Reminder method is running");
Spinner[] temp = new Spinner[shownReminders.length+1];
TextView[] temp2 = new TextView[removeReminders.length+1];
String [] temp3 = new String[reminders.length+1];
for(int i = 0; i < shownReminders.length; i++) {
temp[i] = shownReminders[i];
temp2[i] = removeReminders[i];
temp3[i] = reminders[i];
}
shownReminders = temp;
removeReminders = temp2;
reminders = temp3;
mAdapter.notifyDataSetChanged();//this just makes the adapter refresh itself
}
public void giveYourself(RemindersAdapter adapter) {
mAdapter = adapter;
}
public class MyOnReminderSelectedListener implements OnItemSelectedListener{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
int position = Integer.parseInt(parent.getTag().toString()); //gets the position of the Spinner and puts it in the same index in the reminders array
reminders[position] = parent.getItemAtPosition(pos).toString();
for(int i =0; i < reminders.length; i++) Toast.makeText(parent.getContext(), i+": "+reminders[i], Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing for now
}
}//end of MyOnReminderSelectedListener innerclass
}//end of Class
活动中运行的内容
reminderList = (ListView)findViewById(R.id.reminders_list);
reminderAdapter = new RemindersAdapter();
reminderAdapter.giveYourself(reminderAdapter);
reminderList.setAdapter(reminderAdapter);
TextView addReminder = (TextView)findViewById(R.id.add_reminder);
addReminder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", "The onClick is running !");
reminderAdapter.addReminder();
}
});
我很茫然,因为我的代码看起来与我的测试代码完全一样,并进行了一些修改,以便它可以与我的应用程序一起使用。但Adapter
使用的信息几乎相同。我也将发布测试代码,以便你们可以看到有效的代码。
测试代码
public class RemindersAdapter extends BaseAdapter{
Spinner[] shownReminders = new Spinner[1];
ArrayList<TextView> removeSpinner = new ArrayList<TextView>();
Context mContext;
public RemindersAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return shownReminders.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return shownReminders[position];
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
Log.d("TAG", "Number of times this is running"+position);
Log.d("TAG", "Address of the Spinner Object"+shownReminders[position]);
if(view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.reminder_spinner, parent, false);
}
Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminders_spinner);
reminderSpinner.setTag("1");
ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource(
parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item);
reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
reminderSpinner.setAdapter(reminderAdapter);
reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener());
shownReminders[position] = reminderSpinner;
TextView remove = (TextView)view.findViewById(R.id.remove_reminder);
remove.setTag(position);
removeSpinner.add(remove);
remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = Integer.parseInt(v.getTag().toString());
removeSpinner.remove(pos);
Spinner[] temp = new Spinner[shownReminders.length-1];
for(int i =0; i < shownReminders.length; i++) {
if(i == pos || i > pos) {
temp[i-1] = shownReminders[i];
} else {
temp[i] = shownReminders[i];
}
}
//Here i should refresh somewhow
}
});
return view;
}
public void addReminder() {
Spinner[] temp = new Spinner[shownReminders.length+1];
for(int i = 0; i < shownReminders.length; i++) {
temp[i] = shownReminders[i];
}
shownReminders = temp;
}
/*
* Listener for when the reminder spinner gets a value the user entered
* */
public class MyOnReminderSelectedListener implements OnItemSelectedListener{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
//does nothing for now
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing for now
}
}//end of MyOnReminderSelectedListener innerclass
我还有一个问题,为什么适配器运行得如此之多。例如,使用Log,我注意到它没有明显的原因两次调用getView()
。奇怪的是它有这种行为。我想我不明白BaseAdapter
。提前谢谢。
答案 0 :(得分:36)
如果将ListView放在ScrollView中,则会发生此错误。 ListView本身进行垂直滚动,因此不能将其放入ScrollView。
答案 1 :(得分:6)
当listView需要显示新项时,适配器将调用getView。因此,如果您的listView没有滚动,则不会创建新项目,也不会调用getView 但是您不应该存储所有微调器对象,或者在getView中创建新对象。那是因为它会很慢而且可能浪费记忆。