Xamarin.Android 在 C# Visual Studio 中:多个微调器使用同一个适配器?
Xamarin.Android in C# Visual Studio: Multiple Spinners using the very same adapter?
我有一个布局,我想多次膨胀到 Alertdialog
。我有一个列表来保存膨胀的视图,我从 Resources/values/Strings.xml 中定义的资源创建了一个 Adapter
。
这是Strings.xml的相关部分:
<string name="day_prompt">Choose a day</string>
<string-array name="days_array">
<item>Monday</item>
<item>Tuesday</item>
<item>Wednesday</item>
<item>Thursday</item>
<item>Friday</item>
<item>Saturday</item>
<item>Sunday</item>
</string-array>
下面是用于创建适配器和列表的代码:
//create a list to hold Views
List<View> chooseElements = new List<View>();
//create a new adapter to be fed with data defined in vals/Strings
var adapter = ArrayAdapter.CreateFromResource(this, Resource.Array.days_array, Android.Resource.Layout.SimpleSpinnerItem);
//set its source to prev mentioned
adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
for (int i = 0; i < numberOfDays; i++)
{
//creating a custom number of elements
SetUpItems(Resource.Id.dayPicker, Resource.Layout.ChoosingDay, alertHolder, adapter, chooseElements);
}
我想在列表中的实际(最新)ViewGroup
元素中找到 Spinner
元素的 ID,我设法做到了。但是,我的问题是,我只能设置首先创建的 Spinner
的适配器,所有其他元素似乎都没有附加适配器,好像 一个适配器 可以仅用于 一个 元素。
这是相关代码:
void SetUpItems(int idOfSpinner, int idOfElement, View alertDialogHolder, ArrayAdapter ad, List<View> list)
{
list.Add(LayoutInflater.Inflate(idOfElement, alertDialogHolder.FindViewById<LinearLayout>(Resource.Id.mainHolder)));
#region Spinner
Spinner spinner = new Spinner(this);
//spinner = alertDialogHolder.FindViewById<Spinner>(idOfSpinner);
spinner = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(Spinner_ItemSelected);
//var adapter = ArrayAdapter.CreateFromResource(this, Resource.Array.days_array, Android.Resource.Layout.SimpleSpinnerItem);
//adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Adapter = ad;
#endregion
}
我是 Xamarin 的新手,所以我真的不知道如何使用同一个适配器处理多个 Spinners
(或者如果它真的可能的话)。我尝试了很多解决方案都无济于事,而且我找不到任何有关使用同一适配器处理多个 Spinner
的资源。有人可以给我一些建议吗?
以防以后有人遇到同样的问题,我找到了解决办法。它不是很干净,但是可以用。抱歉,我不是一个非常有经验的开发人员。
主要问题似乎出在以下代码上:
spinner = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
这本身没有问题,但如果您还想将 FindViewById 找到的视图分配给其他元素,您将面临问题,因为 所有生成的元素都将具有相同的 ID。出于某种原因,这不算是错误(甚至不是警告),因此您的程序将通过始终返回列表中具有请求 ID 的第一个元素来编译和解决问题。实际上,这意味着在像我这样的程序中,相同的第一个元素将被一遍又一遍地重新定义,而其他元素将被忽略。
如果您以编程方式为您的元素分配一个新 ID,则可以解决该问题。在我的代码中,我使用了列表,以便我可以访问每个元素以便将来将数据传输到另一个 activity,但我想这样做是可能的 w/o 它,这是分配新的唯一元素的关键元素编号.
list.Add(LayoutInflater.Inflate(idOfElement, alertDialogHolder.FindViewById<LinearLayout>(Resource.Id.mainHolder)));
//creating a temp list for spinners
List<Spinner> spinners = new List<Spinner>();
//adding a new element
spinners.Add(new Spinner(this));
//capturing the current element, this way, I dont have to re-call it every time
int currentElement = spinners.Count - 1;
//assign a new lineear layout from another list
spinners[currentElement] = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
//IMPORTANT: generate a new UNIQUE id
spinners[currentElement].Id = View.GenerateViewId();
//subscribe to the event
spinners[currentElement].ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(Spinner_ItemSelected);
//set the adapter
spinners[currentElement].Adapter = ad;
你为什么不使用 ActionSheet?按照此操作link,您将找到所需的解决方案。
看看代码示例
using Android.Widget;
using Android.OS;
using Xamarin.ActionSheet;
using Android.Support.V4.App;
using System.Collections.Generic;
using Android.App;
namespace ActionSheetTest
{
[Activity (Label = "ActionSheetTest", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : FragmentActivity,ActionSheet.IActionSheetListener
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
var actionSheet = new ActionSheet ();
actionSheet.Other_Button_Title = new List<string> (){ "Option1", "Option2" };
actionSheet.SetActionSheetListener (this);
actionSheet.Show (SupportFragmentManager);
};
}
public void onDismiss (ActionSheet actionSheet, bool isCancel)
{
System.Console.WriteLine ("onDismiss");
}
public void onOtherButtonClick (ActionSheet actionSheet, int index)
{
System.Console.WriteLine (index);
}
}
}
我有一个布局,我想多次膨胀到 Alertdialog
。我有一个列表来保存膨胀的视图,我从 Resources/values/Strings.xml 中定义的资源创建了一个 Adapter
。
这是Strings.xml的相关部分:
<string name="day_prompt">Choose a day</string>
<string-array name="days_array">
<item>Monday</item>
<item>Tuesday</item>
<item>Wednesday</item>
<item>Thursday</item>
<item>Friday</item>
<item>Saturday</item>
<item>Sunday</item>
</string-array>
下面是用于创建适配器和列表的代码:
//create a list to hold Views
List<View> chooseElements = new List<View>();
//create a new adapter to be fed with data defined in vals/Strings
var adapter = ArrayAdapter.CreateFromResource(this, Resource.Array.days_array, Android.Resource.Layout.SimpleSpinnerItem);
//set its source to prev mentioned
adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
for (int i = 0; i < numberOfDays; i++)
{
//creating a custom number of elements
SetUpItems(Resource.Id.dayPicker, Resource.Layout.ChoosingDay, alertHolder, adapter, chooseElements);
}
我想在列表中的实际(最新)ViewGroup
元素中找到 Spinner
元素的 ID,我设法做到了。但是,我的问题是,我只能设置首先创建的 Spinner
的适配器,所有其他元素似乎都没有附加适配器,好像 一个适配器 可以仅用于 一个 元素。
这是相关代码:
void SetUpItems(int idOfSpinner, int idOfElement, View alertDialogHolder, ArrayAdapter ad, List<View> list)
{
list.Add(LayoutInflater.Inflate(idOfElement, alertDialogHolder.FindViewById<LinearLayout>(Resource.Id.mainHolder)));
#region Spinner
Spinner spinner = new Spinner(this);
//spinner = alertDialogHolder.FindViewById<Spinner>(idOfSpinner);
spinner = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(Spinner_ItemSelected);
//var adapter = ArrayAdapter.CreateFromResource(this, Resource.Array.days_array, Android.Resource.Layout.SimpleSpinnerItem);
//adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Adapter = ad;
#endregion
}
我是 Xamarin 的新手,所以我真的不知道如何使用同一个适配器处理多个 Spinners
(或者如果它真的可能的话)。我尝试了很多解决方案都无济于事,而且我找不到任何有关使用同一适配器处理多个 Spinner
的资源。有人可以给我一些建议吗?
以防以后有人遇到同样的问题,我找到了解决办法。它不是很干净,但是可以用。抱歉,我不是一个非常有经验的开发人员。
主要问题似乎出在以下代码上:
spinner = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
这本身没有问题,但如果您还想将 FindViewById 找到的视图分配给其他元素,您将面临问题,因为 所有生成的元素都将具有相同的 ID。出于某种原因,这不算是错误(甚至不是警告),因此您的程序将通过始终返回列表中具有请求 ID 的第一个元素来编译和解决问题。实际上,这意味着在像我这样的程序中,相同的第一个元素将被一遍又一遍地重新定义,而其他元素将被忽略。
如果您以编程方式为您的元素分配一个新 ID,则可以解决该问题。在我的代码中,我使用了列表,以便我可以访问每个元素以便将来将数据传输到另一个 activity,但我想这样做是可能的 w/o 它,这是分配新的唯一元素的关键元素编号.
list.Add(LayoutInflater.Inflate(idOfElement, alertDialogHolder.FindViewById<LinearLayout>(Resource.Id.mainHolder)));
//creating a temp list for spinners
List<Spinner> spinners = new List<Spinner>();
//adding a new element
spinners.Add(new Spinner(this));
//capturing the current element, this way, I dont have to re-call it every time
int currentElement = spinners.Count - 1;
//assign a new lineear layout from another list
spinners[currentElement] = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);
//IMPORTANT: generate a new UNIQUE id
spinners[currentElement].Id = View.GenerateViewId();
//subscribe to the event
spinners[currentElement].ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(Spinner_ItemSelected);
//set the adapter
spinners[currentElement].Adapter = ad;
你为什么不使用 ActionSheet?按照此操作link,您将找到所需的解决方案。
看看代码示例
using Android.Widget;
using Android.OS;
using Xamarin.ActionSheet;
using Android.Support.V4.App;
using System.Collections.Generic;
using Android.App;
namespace ActionSheetTest
{
[Activity (Label = "ActionSheetTest", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : FragmentActivity,ActionSheet.IActionSheetListener
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
var actionSheet = new ActionSheet ();
actionSheet.Other_Button_Title = new List<string> (){ "Option1", "Option2" };
actionSheet.SetActionSheetListener (this);
actionSheet.Show (SupportFragmentManager);
};
}
public void onDismiss (ActionSheet actionSheet, bool isCancel)
{
System.Console.WriteLine ("onDismiss");
}
public void onOtherButtonClick (ActionSheet actionSheet, int index)
{
System.Console.WriteLine (index);
}
}
}