java - 当我将 Spinner 动态添加到 ListView 时,如何访问 Spinner 的选定项目?

标签 java android android-layout listview android-spinner

我正在尝试为应用程序创建一个简单的设置页面。

我想创建一个对象列表,我在 XML 文件中定义其布局。

这些对象的布局中有一个标题 TextView、一个帮助 TextView 和一个 Spinner。

当我在代码中动态添加这些对象时,如何引用这些单独的 Spinner View 以便获取选定的值?

我当前有一个设置对象(列表将填充什么):

public class Setting {

    private String name;
    private String description;
    private String[] values;

    public Setting(String name, String description, String[] values) {
        this.name = name;
        this.description = description;
        this.values = values;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public String[] getValues() {
        return values;
    }
}

将设置对象转换为 View 的自定义 ArrayAdapter:

(R.layout.spinner_row_text_layout.xml 只是一个 TextView ,用于定义微调器项目的布局)

public class SettingsAdapter extends ArrayAdapter<Setting> {

    public SettingsAdapter(Context context, ArrayList<Setting> settings) {
        super(context, 0, settings);
    }

    @Override
    // Takes the position in the array, the view to convert, and the parent of the view as parameters
    public View getView(int position, View convertView, ViewGroup parent) {

        // Get the item in this position
        Setting setting = getItem(position);

        // Check if a view is being reused, otherwise inflate the view (look at view recycling in lists)
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.settings_row_view, parent, false);
        }

        // findViewById in the given view to convert
        TextView title   = (TextView) convertView.findViewById(R.id.titleText);
        TextView help    = (TextView) convertView.findViewById(R.id.helpText);
        Spinner  spinner = (Spinner)  convertView.findViewById(R.id.spinner);

        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_row_text_layout, setting.getValues());
        spinner.setAdapter(spinnerAdapter);

        title.setText(setting.getName());
        help.setText(setting.getDescription());

        return convertView;
    }
}

以及以下布局文件...

设置页面布局:

<RelativeLayout

    android:id="@+id/relativeLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.cgillions.counter.SettingsActivity">

    <ListView
        android:id="@+id/settingsList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:choiceMode="singleChoice"
        android:divider="@color/black"
        android:dividerHeight="5dp"/>

</RelativeLayout>

每个 ListView 项目的布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1">

        <TextView
            android:id="@+id/titleText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="Hello"
            android:textSize="20sp"
            android:textColor="@color/black"

            android:gravity="center_vertical"/>

        <TextView
            android:id="@+id/helpText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="@string/animation_settings_hint"
            android:textSize="12sp"
            />

    </LinearLayout>

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1.5"/>

</LinearLayout>

当我启动与“设置”页面布局相对应的 Activity 时,出现以下错误:

在 junit.framework.Assert.assertNotNull(Assert.java:211)

在 com.example.cgillions.counter.SettingsActivity.onCreate(SettingsActivity.java:46)

在 android.app.Activity.performCreate(Activity.java:5990)

这是我的 onCreate() 方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_settings);

    setTitle("Settings");

    // Create a new Setting object in order to populate list
    animSetting = new Setting("Animation", getResources().getString(R.string.animation_settings_hint), getResources().getStringArray(R.array.anim_values));

    settings = new ArrayList<>();
    settings.add(animSetting);

    ListView settingsList = (ListView) findViewById(R.id.settingsList);
    assertNotNull(settingsList);
    settingsList.setAdapter(new SettingsAdapter(this, settings));

    animSpinner = (Spinner) settingsList.findViewById(R.id.spinner);
    assertNotNull(animSpinner);
}

错误发生在最后一行 - 例如找不到 ID 为“spinner”的 View (因此为空)。我错误地访问了 Spinner - 有人可以建议我应该如何执行此操作吗?

我想获取 Spinner 对象以便获取所选项目。

最佳答案

你可以尝试的东西。将 Spinner 实例添加到您的设置类中:

public class Setting {

    private String name;
    private String description;
    private String[] values;
    private Spinner spinner;

    public Setting(String name, String description, String[] values) {
        this.name = name;
        this.description = description;
        this.values = values;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public String[] getValues() {
        return values;
    }

    public void setSpinner(Spinner s) {
        spinner = s;
    }

    public Spinner getSpinner() {
        return spinner;
    }
}

然后,在 getView() 方法中,为您的设置实例提供 Spinner:

ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_row_text_layout, setting.getValues());
spinner.setAdapter(spinnerAdapter);
if (setting.getSpinner() == null) {
    setting.setSpinner(spinner);
}

然后,假设您可以访问设置列表,则可以访问与每个设置关联的微调器。如果您发现一个带有空微调器的设置,那么它永远不会在 Activity 中出现,这意味着用户从未更改过它。但我不知道这是否真的是你想要的。

这将允许您访问每个设置的微调器,但您没有用于存储用户选择或在微调器中设置所选项目的逻辑。即,如果旋转器有选项 A、B 和 C,并且用户选择了 B,您现在可以读取 B,但没有地方存储它。设置类应该有一个用于保存所选值的字段。并且您的 getView() 方法应该调用 spinner.setSelection() 来告诉它将 B 显示为当前值。否则,无论用户之前选择了什么,它都将始终显示 A。

关于java - 当我将 Spinner 动态添加到 ListView 时,如何访问 Spinner 的选定项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37845735/

相关文章:

c# - "volatile"关键字是做什么用的?

android - '缺少类型或命名空间名称'

android - 在android中使用opencv加载YAML模型文件时出错

android - flutter 中的 FCM 自定义通知图标

android - 框架布局不调整布局权重

android - 在 android 中使用 View 寻呼机滚动具有文本描述的图像

java - Java 中的问题模板类

java - 我怎样才能在一个对象上 wait() 然后在另一个对象上 notifyAll?

java - 反序列化对象而无需访问Java中的类字节码

android - 在 API 11 之前捕获布局调整大小