Как можно заставить ArrayAdapter.getView () работать с ArrayList ()? - PullRequest
0 голосов
/ 04 апреля 2020

Мне нужно отобразить значение в указанной позиции c в моем счетчике, но получить

java .lang.IllegalStateException: ArrayAdapter требует, чтобы идентификатор ресурса был 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 is:

<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 () работает с ArrayList, который является spinnerList с использованием R.layout.support_simple_spinner_dropdown_item, не TextView. Итак, что мне нужно сделать, чтобы мой прямой вызов getView() отобразил значение на setSelection(), как это происходит, когда Android делает это по умолчанию?

Я прочитал следующее (есть больше), но не нашел ничего полезного, так как первоначальный вызов по умолчанию ArrayAdapter.getView() работает без виджета TextView в моем xml:

ArrayAdapter требует, чтобы идентификатор ресурса был TextView

«ArrayAdapter требует, чтобы идентификатор ресурса был TextView»

ArrayAdapter требует, чтобы идентификатор ресурса был TextView в DialogFragment

«ArrayAdapter требует, чтобы идентификатор ресурса был TextView» xml проблемы

«ArrayAdapter требует, чтобы идентификатор ресурса был TextView» для AndroidX

Android ExpandableListAdapter: ArrayAdapter требует, чтобы идентификатор ресурса был TextView

1 Ответ

0 голосов
/ 11 апреля 2020

ОК, вы не можете установить спиннер в значение c, если вы используете Android предоставленные ресурсы, такие как R.layout.support_simple_spinner_dropdown_item. Как я отметил в комментариях к исходному вопросу, ArrayAdapter создал представление, к которому у вас нет доступа. Это требует, чтобы вы создали собственный адаптер. Есть много примеров этого в Интернете и в стеке.

Центральным моментом является объявление вашего блесна в файле макета 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" />

и элемент TextView, в который адаптер запишет значения вашего spinnerList в свой собственный файл xml:

<?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();
}

Если это не очевидно для вас, это не было для меня сначала, вы не объявляете и не устанавливаете свой TextView в своей Деятельности, только свой счетчик:

    mSpinner = findViewById(R.id.spinner);

В своей деятельности установите спиннер для указанного элемента c в своем списке следующим образом:

    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 () выбирает указанный список списка c для отображения, в этом в этом случае itemToBeSelected spinnerList item
  • ViewGroup относится к группе «this» Activity
  • mSelectTypeAdapter.getView () устанавливает элемент списка, который должен отображаться в счетчике в соответствии с его индексом в spinnerList

Android отобразит каждый из элементов вашего списка в своем собственном TextView в бланке Activity, как вы установили в методах getView () и getDropDownView () адаптера. Я сделал мой очень красочным и другим, чтобы убедиться, что он работает так, как я думал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...