Android 使用微调器对象时,使用视图填充ArrayList

Android 使用微调器对象时,使用视图填充ArrayList,android,android-arrayadapter,android-spinner,getview,Android,Android Arrayadapter,Android Spinner,Getview,我一直在android中使用ListView和ExpandableListView。我知道如何通过制作一个customAdaper和adapterclass扩展(例如Arrayadapter),用图像和文本填充ListView 在我正在开发的这个应用程序中,我使用了一个微调器和一个ArrayAdapter。在ArrayAdapter的子类中,我重写了getView方法,用文本和图像填充视图 但问题是getView只被调用一次——对于应用程序启动时以及从列表中选择项目时显示的第一个listitem

我一直在android中使用ListView和ExpandableListView。我知道如何通过制作一个customAdaper和adapterclass扩展(例如Arrayadapter),用图像和文本填充ListView

在我正在开发的这个应用程序中,我使用了一个微调器和一个ArrayAdapter。在ArrayAdapter的子类中,我重写了getView方法,用文本和图像填充视图

但问题是getView只被调用一次——对于应用程序启动时以及从列表中选择项目时显示的第一个listitem。在这里它似乎起作用了。但是,当我通过列表扩展列表时,不会调用getView方法——只有字符串中的名称才会放入列表中

字符串[]字符串={“SSON”、“维纳斯”、“地球”、“三月”}

我想要的是完全控制视图,这样我就可以用我自己的图标、文本等填充整个列表——就像以前使用ListView和可扩展的ListView对象所做的那样

我知道我在这里做错了什么,我可以看到getView方法只调用第一个/所选项的逻辑。但是我想调用所有视图,这样我就有了一个很好的列表,其中有图像图标和经过处理的文本

在扩展活动的类中

 Spinner spinner = (Spinner) findViewById(R.id.planets_spinner);

 String[] string = {"sun", "venus", "earth", "march"};
 MyArrayAdapter adapter = new MyArrayAdapter(this, string);
 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 spinner.setAdapter(adapter);
和CustomAdapter

public class MyArrayAdapter extends ArrayAdapter <String> {

   private final String[] values;
   private final Context context;

   public MyArrayAdapter(Context context, String[] values) {
      super (context, R.layout.celestial_list, values);
      this.values = values;
      this.context = context;
   }

   private static class ViewHolder {
       TextView textView;
       ImageView imageView;
       ImageView infoView;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {


       View view = null;
       ViewHolder viewHolder;

       if (convertView == null) {
       LayoutInflater inflater = (LayoutInflater)  context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.celestial_list, parent, false);
        viewHolder = new ViewHolder();
        viewHolder.textView = (TextView) view.findViewById(R.id.label);
        viewHolder.imageView = (ImageView) view.findViewById(R.id.icon);
        view.setTag(viewHolder);
       } else {
           view = convertView;
           viewHolder = (ViewHolder) view.getTag();
       }

       System.out.println("view = " + view + " för position " + position);
       viewHolder.textView.setText(values[position]);

            switch (position) {
       case 0:
           viewHolder.imageView.setImageResource(R.drawable.sun);
           break;
       case 1:
           viewHolder.imageView.setImageResource(R.drawable.sun);
           break;
       case 2:
           viewHolder.imageView.setImageResource(R.drawable.sun);
           break;
       case 3:
           viewHolder.imageView.setImageResource(R.drawable.sun);
           break;
       }


       return view;
 }

}
公共类MyArrayAdapter扩展了ArrayAdapter{
私有最终字符串[]值;
私人最终语境;
公共MyArrayAdapter(上下文,字符串[]值){
super(上下文、R.layout.u列表、值);
这个值=值;
this.context=上下文;
}
私有静态类视图持有者{
文本视图文本视图;
图像视图图像视图;
图像视图信息视图;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图=空;
持票人持票人;
if(convertView==null){
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
视图=充气机。充气(R.layout.u列表,父项,false);
viewHolder=新的viewHolder();
viewHolder.textView=(textView)view.findViewById(R.id.label);
viewHolder.imageView=(imageView)view.findViewById(R.id.icon);
view.setTag(viewHolder);
}否则{
视图=转换视图;
viewHolder=(viewHolder)view.getTag();
}
System.out.println(“view=“+view+”för position“+position”);
viewHolder.textView.setText(值[位置]);
开关(位置){
案例0:
viewHolder.imageView.setImageResource(R.drawable.sun);
打破
案例1:
viewHolder.imageView.setImageResource(R.drawable.sun);
打破
案例2:
viewHolder.imageView.setImageResource(R.drawable.sun);
打破
案例3:
viewHolder.imageView.setImageResource(R.drawable.sun);
打破
}
返回视图;
}
}
截图1。看起来还可以-getView被称为

屏幕截图2,但仅适用于选定的listobject-不适用于其他对象。此处仅使用字符串[]

我假设(大部分情况下是肯定的)您没有使用片段,因此您实际上不需要微调器的自定义适配器来更改映像,因为两者都位于一个活动中

你应该

  • 确保活动类
    实现了OnItemSelectedListener
  • 添加
    onimselected
    ,如果需要
    onNothingSelected
    ,将
  • 图像选择器代码登录已选中(请记住使用
    parent.getItemAtPosition(pos)
    获取当前位置)

微调器适配器的工作原理有点不同:

您必须添加:

public class MyArrayAdapter  extends BaseAdapter implements SpinnerAdapter {

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = newDropDownView(parent);
    }

    bindDropDownView(position, convertView);
    return convertView;

}

protected View newDropDownView(ViewGroup parent) { ... }

protected void bindDropDownView(int position, View view) { ... }


@Override
public View getView(int position, View convertView, ViewGroup parent) { ... }


}
因此,将为当前选定项调用getView(),该项在微调器未展开时可见。而将为微调器列表中的每个元素调用getDropDownView()。这就是你要找的

顺便说一句,这里有一些有用的适配器类(使用dagger进行依赖项注入,但您可以复制代码并擦除注入器类):

好的,谢谢-但我得到了一个非法状态例外:ArrayAdapter要求资源ID为textView。这可能是我对传递resourceid的基类构造函数进行超级调用的地方。我通过了整个布局。只要我使用getView方法就可以了。但是现在当我使用getDropDownView方法时,我得到了这个异常并崩溃。问题是如何在那里获得文本视图?我必须像在getView中那样膨胀xml文件吗?使用
BaseAdapter
而不是
ArrayAdapter
,然后在newDropDownView()中,必须膨胀xml布局(设置视图持有者等)……我已更改为BaseAdapter,但现在的问题是没有调用getView和getDropDownView。我不能再使用setDropDownViewResource();