核心代码如下:
ArrayAdapter<ResolveInfo> adapter=new ArrayAdapter<ResolveInfo>(getActivity(), android.R.layout.activity_list_item,android.R.id.text1,activities){ @Override public View getView(int position, View convertView, ViewGroup parent) { PackageManager pm=getActivity().getPackageManager(); View view=super.getView(position, convertView, parent); TextView tv= (TextView) view.findViewById(android.R.id.text1); tv.setText(getItem(position).loadLabel(pm)); ImageView imageView= (ImageView) view.findViewById(android.R.id.icon); imageView.setImageDrawable(getItem(position).loadIcon(pm)); return view; } };
activity_list_item:该文件由android系统提供,直接使用即可
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="1dip" android:paddingBottom="1dip" android:paddingStart="8dip" android:paddingEnd="8dip"> <ImageView android:id="@+id/icon" android:layout_width="24dip" android:layout_height="24dip"/> <TextView android:id="@android:id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:paddingStart="?android:attr/listPreferredItemPaddingStart" /> </LinearLayout>从代码中看出适合显示一张图片和一个文本
再看看ArrayAdapter,为什么在本例中选择下面这个构造方法
public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId, @NonNull List<T> objects) {。。。。。。。}因为重写ArrayAdapter的getview()时,执行了父类的方法,父类的getview()具体实现如下:
public View getView(int position, View convertView, ViewGroup parent) { return createViewFromResource(mInflater, position, convertView, parent, mResource); } private View createViewFromResource(LayoutInflater inflater, int position, View convertView, ViewGroup parent, int resource) { View view; TextView text; if (convertView == null) { view = inflater.inflate(resource, parent, false); } else { view = convertView; } try { if (mFieldId == 0) { // If no custom field is assigned, assume the whole resource is a TextView text = (TextView) view; } else { // Otherwise, find the TextView field within the layout text = (TextView) view.findViewById(mFieldId); } } catch (ClassCastException e) { Log.e("ArrayAdapter", "You must supply a resource ID for a TextView"); throw new IllegalStateException( "ArrayAdapter requires the resource ID to be a TextView", e); } T item = getItem(position); if (item instanceof CharSequence) { text.setText((CharSequence)item); } else { text.setText(item.toString()); } return view; }看红色部分的说明,如果mFieldId=0,就认为整个资源是个TextView,那么这个 mFieldId是什么呢?经过查找,初值为0,另外只在上面的构造函数中赋值
mFieldId = textViewResourceId;是一个textView的索引,显然 activity_list_item是个线性布局,不是TextView, 所以mFieldId不能等于0,所以需要给 mFieldId赋值,所以只能用这个构造函数。另外源代码对 mFieldId也做了说明:
If the inflated resource is not a TextView, {@link #mFieldId} is used to find * a TextView inside the inflated views hierarchy. This field must contain the * identifier that matches the one defined in the resource file.