Android:SeperatedList(如何获取地址簿效果?)

时间:2011-01-08 22:07:02

标签: android listview addressbook

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扩展。

现在我得到了这个效果: alt text

有人知道什么是错的,我怎么能解决这个问题?非常感谢!!

这是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;
    }
}

2 个答案:

答案 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()