【问题标题】:How can ArrayAdapter.getView() be made to work on an ArrayList()?如何使 ArrayAdapter.getView() 在 ArrayList() 上工作?
【发布时间】:2020-04-03 22:33:59
【问题描述】:

我需要在微调器的特定位置显示值,但得到一个

java.lang.IllegalStateException: ArrayAdapter 需要资源 ID 成为一个TextView

错误,因为我的微调器使用了如下设置的简单列表:

    mSpinner = findViewById(R.id.spinner);
    TextView msgTv = findViewById(R.id.errorMessage);
    if (listTypes.size() > 0) {
        /*
        hide the error message
         */
        msgTv.setVisibility(View.GONE);
        /*
         *  the List has more than zero elements, so print them out in LogCat
         */
        for(int i = 0; i < listTypes.size(); i++) {
            Type type = listTypes.get(i);
            int id = type.getId();
            typeNameString = type.getType();
            Log.d(TAG, "type " + typeNameString + " with an ID of: " + id);
        }
        //create spinner List<> of Type names only for use with the spinner
        spinnerList =  new ArrayList<>();
        for (int i = 0; i < listTypes.size(); i++) {
            typeNameString = listTypes.get(i).getType();
            spinnerList.add(typeNameString);
            Log.d(TAG, "Type " + i + " typeNameString is: " + typeNameString);
        }
        /*
         * set the adapter to use 'this' context, the default Android spinner widget, typeCursor
         * tyepCursor column as the source (from), display in the 'to' destination, no flags
         */
        typeArrayAdapter = new ArrayAdapter<>(this, R.layout.support_simple_spinner_dropdown_item, spinnerList);
        mSpinner.setAdapter(typeArrayAdapter);
    } else{
        /*
         * no types exist in TABLE_TYPE, so add them
         */
        msgTv.setText(R.string.no_types);
        msgTv.setVisibility(View.VISIBLE);
    }

我生成微调器的代码如下:

private void setProviderInfo(){
    Log.d(TAG, "Entered setProviderInfo");
    .
    .
    .
    mSpinner.setAdapter(typeArrayAdapter);
    mSpinner.setSelection(spinnerList.indexOf(type), true);
    //TODO: try getView() to display the setSelection() value in spinner
    ViewGroup view = (ViewGroup) findViewById(android.R.id.content);
    typeArrayAdapter.getView(position, mSpinner, view);
    .
    .
    .
}

我的微调器的 xml 是:

<Spinner
    android:id="@+id/spinner"
    style="@style/Spinner"
    android:prompt="@string/select_provider_type"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvProviderTitle" />

风格是:

<style name="Spinner">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">50dp</item>
    <item name="android:layout_marginTop">8dp</item>
    <item name="android:background">@android:color/holo_blue_bright</item>
    <item name="android:layout_marginStart">8dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">10dp</item>
    <item name="android:layout_marginEnd">8dp</item>
    <item name="android:clickable">true</item>

我的微调器工作,这意味着 ArrayAdapter.getView() 工作在使用 R.layout.support_simple_spinner_dropdown_item 的微调器列表的 ArrayList 上,而不是 TextView。那么,我需要做什么才能直接调用getView() 以在setSelection() 显示值,就像Android 默认情况下那样?

我已阅读以下内容(还有更多内容),但没有发现任何有用的内容,因为对 ArrayAdapter.getView() 的初始默认调用在我的 xml 中没有 TextView 小部件的情况下有效:

ArrayAdapter requires the resource ID to be a TextView

“ArrayAdapter requires the resource ID to be a TextView” issue

ArrayAdapter requires the resource ID to be a TextView in DialogFragment

“ArrayAdapter requires the resource ID to be a TextView” xml problems

“ArrayAdapter requires the resource ID to be a TextView” error for AndroidX

Android ExpandableListAdapter: ArrayAdapter requires the resource ID to be a TextView

【问题讨论】:

  • 从一些调查看来,是的,ArrayAdapter.getView() 旨在用于实际显示显示由 setSelection() 指定的值的微调器。这在Android Adapter Tutorial: What Are Adapters in Android 进行了讨论。当我弄清楚这一点时,我会发布答案。
  • 如果我理解正确,您需要创建自己的自定义适配器。在那里,您将覆盖 getView 方法并做任何您想做的事情,并膨胀您需要的任何布局
  • @sebasira,我得出了这个结论,因为在执行调试并进入 ArrayAdapter.java 时,我在 cmets 中发现了这一点:“默认情况下,数组适配器通过调用{@link Object#toString()} 在您提供的集合中的每个数据对象上,并将结果放在 TextView 中。“所以,我需要引用默认的 TextView,我不认为这是我可以,但我会调查并发布我的最终答案。

标签: java android android-arrayadapter android-spinner


【解决方案1】:

好的,当您使用 Android 提供的资源时,您无法将微调器设置为特定值,例如 R.layout.support_simple_spinner_dropdown_item。正如我在原始问题下的 cmets 中指出的那样,ArrayAdapter 创建了一个您无法访问的视图。这要求您创建一个自定义适配器。在 web 和 stackoverflow 上有很多这样的例子。

这样做的核心是在 Activity 的 xml 布局文件中声明您的微调器,例如:

<Spinner
    android:id="@+id/spinner"
    style="@style/Spinner"
    android:prompt="@string/select_provider_type"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvProviderTitle" />

以及适配器会将您的 spinnerList 值写入其自己的 xml 文件中的 TextView 元素:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/typeName"
    style="@style/TypeName"/>

TextView 将由您的自定义适配器使用它的 getView() 方法填充,用于微调器本身,使用 getDropDownView() 方法填充单击时展开的列表:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Log.d(TAG, "Entered: getView");
    convertView = mLayoutInflater.inflate(R.layout.type_name_only, null);
    TextView typeName = convertView.findViewById(R.id.typeName);
    typeName.setText(types.get(position));
    return convertView;
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    Log.d(TAG, "Entered: getDropDownView");
    convertView = mLayoutInflater.inflate(R.layout.type_name_only, null);
    TextView typeName = convertView.findViewById(R.id.typeName);
    typeName.setText(types.get(position));
    typeName.setBackgroundColor(GREEN);
    typeName.setTextColor(BLUE);
    return convertView;
}

请注意,您还必须重写 getCont() 方法,以便适配器可以确定要向微调器添加多少元素:

@Override
public int getCount() {
    return yourList.size();
}

如果对你来说不是很明显,那一开始对我来说不是,你没有在你的 Activity 中声明或设置你的 TextView,只有你的微调器:

    mSpinner = findViewById(R.id.spinner);

在您的 Activity 中,将微调器设置为其列表中的特定元素,如下所示:

    mSelectTypeAdapter = new SelectTypeAdapter(mContext, R.id.spinner, spinnerList);
    mSpinner.setAdapter(mSelectTypeAdapter);
    mSpinner.setOnItemSelectedListener(this);
    mSpinner.setSelection(spinnerList.indexOf(itemToBeSelected), true);
    ViewGroup viewGroup = findViewById(android.R.id.content);
    mSelectTypeAdapter.getView(spinnerList.indexOf(itemToBeSelected), mSpinner, viewGroup);
  • mSpinner.setSelection() 选择要显示的特定列表索引,在 itemToBeSelected spinnerList item的这种情况
  • ViewGroup 是“this”Activity 的视图组
  • mSelectTypeAdapter.getView() 设置列表项是 根据其在微调器中的索引显示在 微调器列表

Android 将按照您在 Adapter 的 getView() 和 getDropDownView() 方法中的设置,在 Activity 的微调器中以自己的 TextView 显示每个列表元素。我让我的颜色变得非常丰富多彩和与众不同,以验证它是否像我想象的那样工作。

【讨论】:

    猜你喜欢
    • 2011-03-28
    • 1970-01-01
    • 2013-12-07
    • 2017-11-19
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 2015-05-13
    • 2015-02-13
    相关资源
    最近更新 更多