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

时间:2016-06-15 21:03:54

标签: java android android-layout listview android-spinner

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

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

在这些对象的布局中,标题为TextView,帮助TextView和Spinner。

当我在代码中动态添加这些对象时,如何引用这些单独的Spinner视图以便我可以获得所选的值?

我目前有一个Setting对象(列表将填充的内容):

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;
    }
}

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

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

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>

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

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

at 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'的视图(因此为null)。我正在错误地访问Spinner - 有人可以建议我应该怎么做吗?

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

1 个答案:

答案 0 :(得分:2)

你可能尝试的东西。将Spinner实例添加到Setting类:

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

然后,假设您可以访问“设置”列表,则可以访问与每个设置相关联的微调器。如果您找到一个带有空微调器的设置,那么它永远不会进入活动视图,这意味着用户永远不会更改它。但我不知道这是否真的是你想要的。

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