C#Visual Studio中的Xamarin.Android:多个Spinners使用相同的适配器?

时间:2017-02-28 16:59:19

标签: c# android xamarin spinner android-arrayadapter

我想要多次向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>

以下是用于创建adpter和列表的代码:

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

我想在列表中的实际(最新)Spinner元素中找到ViewGroup元素的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的资源。有人可以给我一些建议吗?

2 个答案:

答案 0 :(得分:0)

如果将来有人遇到同样的问题,我找到了解决方案。它不是很干净,但它的工作原理。对不起,我不是一个非常有经验的开发人员。

主要问题似乎是以下代码:

 spinner = list[list.Count - 1].FindViewById<Spinner>(idOfSpinner);

本身没有问题,但是如果你想将FindViewById找到的视图分配给其他元素,你将面临问题,因为所有生成的元素将具有相同的ID 。出于某种原因,这不算错误(甚至不是警告),因此您的程序将通过始终从列表中返回具有所请求ID的第一个元素来编译并解决问题。实际上,这意味着在像我这样的程序中,相同的第一个元素将被反复重新定义,而其他元素则被忽略。

如果您为元素分配新的ID程序,则可以解决问题。在我的代码中,我使用了列表,以便我可以访问每个元素以便将来数据传输到另一个活动,但我想它可以用它来完成,这是分配新的唯一ID的关键元素。

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;

答案 1 :(得分:-1)

为什么不使用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);
    }
}
}