Android Xamarin C#:实现MaterialSpinner选中项点击添加至ListView
问题描述
我希望点击assignstaffButton按钮时,将MaterialSpinner中选中的员工名称添加到ListView中。Spinner里的员工名称来自数据库,只需要把选中项添加到ListView即可,但我不知道正确的语法,也不确定是否需要转成字符串。当前代码无法实现需求,求帮助。
附当前Fragment代码和布局文件:
using AdamsonsEDApp.Adapters; using AdamsonsEDApp.Data_Models; using AdamsonsEDApp.Helpers; using AdamsonsEDApp.Listeners; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Util; using Android.Views; using Android.Widget; using Firebase.Annotations; using Firebase.Database; using FR.Ganfra.Materialspinner; using Java.Util; using System; using System.Collections.Generic; using System.Linq; using System.Text; using SupportV7 = Android.Support.V7.App; namespace AdamsonsEDApp.Fragments { public class AssigningStaffFragment : Android.Support.V4.App.DialogFragment { MaterialSpinner assignstaffnameSpinner; Button assignstaffButton, assignstaffregisterButton, assignstaffremoveButton, assignstaffclearButton; ImageView exitFragmentButton; ListView assignstaffListView; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your fragment here } public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.Inflate(Resource.Layout.newassignstaff, container, false); this.Dialog.SetCanceledOnTouchOutside(false); assignstaffnameSpinner = (MaterialSpinner)view.FindViewById(Resource.Id.assignstaffnameSpinner); assignstaffButton = (Button)view.FindViewById(Resource.Id.assignstaffButton); assignstaffListView = (ListView)view.FindViewById(Resource.Id.assignstaffListView); exitFragmentButton = (ImageView)view.FindViewById(Resource.Id.exitfragmentButton); assignstaffremoveButton = (Button)view.FindViewById(Resource.Id.assignstaffremoveButton); assignstaffclearButton = (Button)view.FindViewById(Resource.Id.assignstaffclearButton); assignstaffregisterButton = (Button)view.FindViewById(Resource.Id.assignstaffregisterButton); assignstaffListView.ItemClick += AssignstaffListView_ItemClick; assignstaffregisterButton.Click += AssignstaffregisterButton_Click; assignstaffButton.Click += AssignstaffButton_Click; assignstaffremoveButton.Click += AssignstaffremoveButton_Click; assignstaffclearButton.Click += AssignstaffclearButton_Click; exitFragmentButton.Click += ExitFragmentButton_Click; RetrieveStaffNameData(); return view; } private void AssignstaffclearButton_Click(object sender, EventArgs e) { assignstaffListView.clear(); } private void AssignstaffremoveButton_Click(object sender, EventArgs e) { //remove selected item } private void AssignstaffListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e) { //select item } //add spinner value to listview private void AssignstaffButton_Click(object sender, EventArgs e) { MaterialSpinner assignstaffspinner = (MaterialSpinner)sender; assignstaffListView.Add(assignstaffnameSpinner.GetItemAtPosition(e.Position).ToString()); if (staffnameadapter != null) { staffnameadapter.Dispose(); } staffnameadapter = new ArrayAdapter<string>(this.Activity, Android.Resource.Layout.SimpleListItem1, assignstaffListView); FindViewById(Resource.Id.assignstaffListView).Adapter = staffnameadapter; } private void ExitFragmentButton_Click(object sender, EventArgs e) { this.Dismiss(); } public void SetupStaffNameSpinner() { staffnameList = new List<string>(); foreach (var staffname in stafffullnameList) { staffnameList.Add(staffname.staffFullName); } staffnameadapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleSpinnerDropDownItem, staffnameList); staffnameadapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem); assignstaffnameSpinner.Adapter = staffnameadapter; assignstaffnameSpinner.ItemSelected += AssignstaffnameSpinner_ItemSelected; } private void AssignstaffnameSpinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e) { staffname = staffnameList[e.Position]; } public void RetrieveStaffNameData() { staffListeners = new StaffListeners(); staffListeners.Create(); staffListeners.StaffRetrieved += StaffListeners_StaffRetrieved; } private void StaffListeners_StaffRetrieved(object sender, StaffListeners.StaffDataEventArgs e) { stafffullnameList = e.Staffs; SetupStaffNameSpinner(); } } }
</RelativeLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#e2e2e2"/> <LinearLayout android:padding="16dp" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fr.ganfra.materialspinner.MaterialSpinner android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/assignstaffnameSpinner" app:ms_enableFloatingLabel="true" app:ms_floatingLabelText="Select Event" app:ms_hint="Select Event" app:ms_alignLabels="true"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/assignstaffButton" android:layout_width="0dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:text="ASSIGN" android:layout_weight="1" android:background="?android:attr/colorPrimary" android:textColor="#fff" android:layout_margin="10px" android:layout_marginTop="20dp"/> <Button android:id="@+id/assignstaffremoveButton" android:layout_width="0dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:text="REMOVE" android:layout_weight="1" android:background="?android:attr/colorPrimary" android:textColor="#fff" android:layout_margin="10px" android:layout_marginTop="20dp"/> <Button android:id="@+id/assignstaffclearButton" android:layout_width="0dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:text="CLEAR" android:layout_weight="1" android:background="?android:attr/colorPrimary" android:textColor="#fff" android:layout_margin="10px" android:layout_marginTop="20dp"/> </LinearLayout> <ListView android:id="@+id/assignstaffListView" android:hint="Staff Names" android:layout_width="match_parent" android:layout_height="300dp" android:layout_marginTop="20dp" android:textSize="18sp" android:background="#edede0" android:textColor="#000"/> <Button android:id="@+id/assignstaffregisterButton" android:layout_width="300dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:text="REGISTER DETAILS" android:background="?android:attr/colorPrimary" android:textColor="#fff" android:layout_marginTop="20dp"/> </LinearLayout> </LinearLayout>
问题分析
现有代码存在以下关键错误:
AssignstaffButton_Click方法错误将按钮(sender)强制转换为MaterialSpinner,实际sender是点击的Button控件- 试图直接调用
ListView.Add()方法,ListView本身无该方法,必须通过数据源+适配器的方式更新列表 - 未维护独立的ListView数据源列表,错误将ListView对象传给ArrayAdapter
assignstaffListView.clear()方法不存在,ListView清空需通过数据源和适配器完成- 类中多个成员变量未声明,导致编译错误
修正后的完整Fragment代码
using AdamsonsEDApp.Adapters; using AdamsonsEDApp.Data_Models; using AdamsonsEDApp.Helpers; using AdamsonsEDApp.Listeners; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Util; using Android.Views; using Android.Widget; using Firebase.Annotations; using Firebase.Database; using FR.Ganfra.Materialspinner; using Java.Util; using System; using System.Collections.Generic; using System.Linq; using System.Text; using SupportV7 = Android.Support.V7.App; namespace AdamsonsEDApp.Fragments { public class AssigningStaffFragment : Android.Support.V4.App.DialogFragment { // 控件绑定变量 MaterialSpinner assignstaffnameSpinner; Button assignstaffButton, assignstaffregisterButton, assignstaffremoveButton, assignstaffclearButton; ImageView exitFragmentButton; ListView assignstaffListView; // ListView专用数据源与适配器 private List<string> _assignedStaffList; private ArrayAdapter<string> _assignedStaffAdapter; // Spinner相关变量 private List<string> staffnameList; private ArrayAdapter<string> staffnameadapter; private List<Staff> stafffullnameList; private StaffListeners staffListeners; private string staffname; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 初始化ListView数据源 _assignedStaffList = new List<string>(); } public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.Inflate(Resource.Layout.newassignstaff, container, false); this.Dialog.SetCanceledOnTouchOutside(false); // 绑定控件 assignstaffnameSpinner = view.FindViewById<MaterialSpinner>(Resource.Id.assignstaffnameSpinner); assignstaffButton = view.FindViewById<Button>(Resource.Id.assignstaffButton); assignstaffListView = view.FindViewById<ListView>(Resource.Id.assignstaffListView); exitFragmentButton = view.FindViewById<ImageView>(Resource.Id.exitfragmentButton); assignstaffremoveButton = view.FindViewById<Button>(Resource.Id.assignstaffremoveButton); assignstaffclearButton = view.FindViewById<Button>(Resource.Id.assignstaffclearButton); assignstaffregisterButton = view.FindViewById<Button>(Resource.Id.assignstaffregisterButton); // 初始化ListView适配器并绑定 _assignedStaffAdapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleListItem1, _assignedStaffList); assignstaffListView.Adapter = _assignedStaffAdapter; // 绑定事件 assignstaffListView.ItemClick += AssignstaffListView_ItemClick; assignstaffregisterButton.Click += AssignstaffregisterButton_Click; assignstaffButton.Click += AssignstaffButton_Click; assignstaffremoveButton.Click += AssignstaffremoveButton_Click; assignstaffclearButton.Click += AssignstaffclearButton_Click; exitFragmentButton.Click += ExitFragmentButton_Click; RetrieveStaffNameData(); return view; } private void AssignstaffclearButton_Click(object sender, EventArgs e) { // 清空数据源并通知适配器更新UI _assignedStaffList.Clear(); _assignedStaffAdapter.NotifyDataSetChanged(); } private void AssignstaffremoveButton_Click(object sender, EventArgs e) { // 获取选中项位置,无效则不执行 int selectedPosition = assignstaffListView.CheckedItemPosition; if (selectedPosition != ListView.InvalidPosition) { _assignedStaffList.RemoveAt(selectedPosition); _assignedStaffAdapter.NotifyDataSetChanged(); assignstaffListView.SetItemChecked(selectedPosition, false); } } private void AssignstaffListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e) { // 设置点击项为选中状态,方便后续移除操作 assignstaffListView.SetItemChecked(e.Position, true); } // 将Spinner选中项添加到ListView private void AssignstaffButton_Click(object sender, EventArgs e) { int selectedPosition = assignstaffnameSpinner.SelectedItemPosition; // 校验选中位置有效性 if (selectedPosition != Spinner.InvalidPosition) { string selectedStaffName = staffnameList[selectedPosition]; // 避免重复添加 if (!_assignedStaffList.Contains(selectedStaffName)) { _assignedStaffList.Add(selectedStaffName); // 通知适配器更新UI _assignedStaffAdapter.NotifyDataSetChanged(); } } } private void ExitFragmentButton_Click(object sender, EventArgs e) { this.Dismiss(); } public void SetupStaffNameSpinner() { staffnameList = new List<string>(); foreach (var staffname in stafffullnameList) { staffnameList.Add(staffname.staffFullName); } staffnameadapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleSpinnerDropDownItem, staffnameList); staffnameadapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem); assignstaffnameSpinner.Adapter = staffnameadapter; assignstaffnameSpinner.ItemSelected += AssignstaffnameSpinner_ItemSelected; } private void AssignstaffnameSpinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e) { staffname = staffnameList[e.Position]; } public void RetrieveStaffNameData() { staffListeners = new StaffListeners(); staffListeners.Create(); staffListeners.StaffRetrieved += StaffListeners_StaffRetrieved; } private void StaffListeners_StaffRetrieved(object sender, StaffListeners.StaffDataEventArgs e) { stafffullnameList = e.Staffs; SetupStaffNameSpinner(); } private void AssignstaffregisterButton_Click(object sender, EventArgs e) { // 可在此实现提交选中员工数据到数据库的逻辑 } } }
关键修改说明
- 新增ListView专用数据源:添加
_assignedStaffList作为ListView的数据源,_assignedStaffAdapter作为对应适配器,初始化时绑定到ListView - 修正Assign按钮逻辑:
- 从
assignstaffnameSpinner直接获取选中位置,不再错误转换sender - 直接从
staffnameList取选中的字符串(无需额外转换,Spinner数据源本身就是字符串列表) - 添加数据到数据源后,调用
NotifyDataSetChanged()通知UI更新 - 增加重复判断,避免同一员工被多次添加
- 从
- 完善清空/移除功能:通过操作数据源+通知适配器的方式实现列表清空和选中项移除
- 补充成员变量声明:添加所有缺失的类成员变量,确保代码可编译
内容的提问来源于stack exchange,提问作者Zeno
相关产品推荐
相关产品推荐

