Hallo All,
我有一个ListView,它在每一行中都有一个RadioGroup和一个Button。 ListView效果很好。现在我想向ListView添加一个标题,以获得地址簿之类的效果。我从互联网上资助一个Java类,看起来像这样:
package com.aiquan.android.wljs_ncre3_free;
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
public class SeparatedListAdapter extends BaseAdapter {
public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
public void addSection(String sectionHeader, Adapter sectionAdapter) {
this.headers.add(sectionHeader);
this.sections.put(sectionHeader, sectionAdapter);
}
public Object getItem(int position) {
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return section;
if (position < size)
return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for (Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for (Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
public int getItemViewType(int position) {
int type = 1;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return TYPE_SECTION_HEADER;
if (position < size)
return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
// @Override
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return headers.getView(sectionnum, convertView, parent);
if (position < size)
return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
// @Override
public long getItemId(int position) {
return position;
}
}
我尝试使用这个类(没有任何改变)来解决我的问题。但是我得到了一个非常奇怪的效果:没有显示带有RadioGroup和Buttons的部分,但是带有字符串的部分正确显示!我没有收到Eclipse的错误消息。这是我的代码:
SeparatedListAdapter adapter = new SeparatedListAdapter(this);
adapter.addSection("Header 1", new ArrayAdapter<String>(this,
R.layout.list_item, new String[] { "First item", "Item two" }));
adapter.addSection("Header 2", new ExerciseAdapter(this,
R.layout.sc_for_exam, n_exercises));
adapter.addSection("Header 3", new ArrayAdapter<String>(this,
R.layout.list_item, new String[] { "lala", "lolo" }));
setListAdapter(adapter);
n_exercises是一个ArrayList,它包含List Items(每个列表项包含一个RadioGroup和一个Button)。 ExerciseAdapter从ArrayAdapter扩展。
现在我得到了这个效果:
有人知道什么是错的,我怎么能解决这个问题?非常感谢!!
这是ExerciseAdapter的代码。它们与上面的代码在同一个类中。
private class ExerciseAdapter extends ArrayAdapter<Exercise_SC> {
public ExerciseAdapter(Context context, int textViewResourceId,
ArrayList<Exercise_SC> exes) {
super(context, textViewResourceId, exes);
}
public View getView(final int position, View convertView,
ViewGroup parent) {
View row = convertView;
SC_ViewWrapper wrapper;
RadioGroup rg;
if (row == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Training")) {
row = vi.inflate(R.layout.sc_for_training, parent, false);
} else {
row = vi.inflate(R.layout.sc_for_exam, parent, false);
}
wrapper = new SC_ViewWrapper(row);
row.setTag(wrapper);
rg = wrapper.getRadioGroup();
RadioGroup.OnCheckedChangeListener l = new RadioGroup.OnCheckedChangeListener() {
// @Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
Integer myPosition = (Integer) group.getTag();
Exercise_SC eRow = getExerciseRow(myPosition);
eRow.setCheckedRB(checkedId);
switch (checkedId) {
case R.id.RB_A:
n_exercises.get(myPosition).setCustomerAnswer("A");
break;
case R.id.RB_B:
n_exercises.get(myPosition).setCustomerAnswer("B");
break;
case R.id.RB_C:
n_exercises.get(myPosition).setCustomerAnswer("C");
break;
case R.id.RB_D:
n_exercises.get(myPosition).setCustomerAnswer("D");
break;
default:
n_exercises.get(myPosition).setCustomerAnswer("");
}
}
};
rg.setOnCheckedChangeListener(l);
} else {
wrapper = (SC_ViewWrapper) row.getTag();
rg = wrapper.getRadioGroup();
}
Exercise_SC myExe = getExerciseRow(position);
int size = ChooseMode_Act.size;
wrapper.getTi().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVExer().setText(myExe.getExerciseText());
wrapper.getTVExer().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getA().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVA().setText(myExe.getAnswerA());
wrapper.getTVA().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getB().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVB().setText(myExe.getAnswerB());
wrapper.getTVB().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getC().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVC().setText(myExe.getAnswerC());
wrapper.getTVC().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getD().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getTVD().setText(myExe.getAnswerD());
wrapper.getTVD().setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
wrapper.getImageView().setImageResource(myExe.getImageSrc());
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Training")) {
wrapper.getButton().setOnClickListener(new OnClickListener() {
// @Override
public void onClick(View v) {
Toast toast = Toast.makeText(
getApplicationContext(),
"题-"
+ (position + 1)
+ ": "
+ n_exercises.get(position)
.getCorrectAnswer(),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
});
}
rg.setTag(new Integer(position));
rg.check(myExe.getCheckedRB());
return row;
}
}
答案 0 :(得分:0)
IMO SeparatedListAdapter.getView(...)
看起来很可疑。记录它(或调试)以研究它是如何工作的以及它返回的内容。看起来它永远不会从View
返回ExerciseAdapter
。
更新:第二个想法我意识到它会为ExerciseAdapter
调用View
。因此,可能会关注从ExerciseAdapter.getView(...)
上下文调用SeparatedListAdapter.getView(...)
返回的内容。你也可以发布ExerciseAdapter代码吗?
答案 1 :(得分:0)
试试这个:
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
//int total = 1;
//int total = 0;
int total = headers.getCount() + 1;
for (Adapter adapter : this.sections.values())
//total += adapter.getViewTypeCount();
total += (adapter.getCount() + 10);
return total;
}
不知道为什么但它对我有用。我从其他一些问题中读到了提示getItemViewType()
不能大于getViewTypeCount()
。