【发布时间】:2016-06-15 21:03:54
【问题描述】:
我正在尝试为应用创建一个简单的设置页面。
我想创建一个对象列表,我在 XML 文件中定义其布局。
在这些对象的布局中是一个标题 TextView、一个帮助 TextView 和一个 Spinner。
当我在代码中动态添加这些对象时,如何引用这些单独的 Spinner 视图以便获得选定的值?
我目前有一个设置对象(列表将被填充的内容):
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>
当我启动与设置页面布局对应的 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 - 有人可以建议我应该如何做到这一点吗?
我想获取 Spinner 对象以获取所选项目。
【问题讨论】:
-
R.id.spinner不是listview内部的布局而是内部View的布局,每一行都有一个新的Spinner实例,为什么Activity中需要spinner ? (还有哪一个?第一行的那个?第二行?等等)
-
“是内部视图的布局”是什么意思?我知道你在说每一行都有一个新实例 - 我将如何访问每个单独的列表项?在这种情况下,我想要第一项的微调器(因为我在列表中只有一个设置...)
-
我想在活动中使用微调器,以便我可以拉出所选项目并更改不同活动的行为。
-
在您的代码中,您尝试在 Activity 的 onCreate 方法中获取每个微调器的选定项。那是您要阅读所选项目的地方吗?如果没有,您可以将回调对象传递给您的
SettingsAdapter,并在微调器的setOnItemSelectedListener中使用该对象。这将允许您在更改每个微调器时执行您希望执行的任何操作。 -
@Matthew 因此,在我的设置适配器中,我创建了一个 OnClickListener,每次创建一个项目时,我都会将它的监听器设置为这个变量。在这个变量中,我切换了单击视图的 TitleText(设置的标题),以便确定它是哪个项目。这(几乎)有效(我认为其他地方肯定存在错误,因为设置并不总是正确更改)。这是完成我想做的事情的“最佳”方式吗?它看起来很长,并且倾向于意大利面条代码 - 很多功能都无处不在。
标签: java android android-layout listview android-spinner