在MvvmCross中以编程方式创建和绑定Android Spinners

我正在构建一个需要动态生成和绑定Spinner控件的跨平台应用程序.我能够在iOS和 Windows平台上做到这一点,但是与 Android有关系.如果我正确理解,我必须向MvxSpinner的上下文和attrs的构造函数传递一些参数,但是我无法弄清楚我该怎么做,应该在那里传递什么.另外,我不知道如何绑定ItemsSource和SelectedItem.我想要创建一个新的绑定集(与iOS版本相似),但是我无法在Android上找到它.你能给我一些方向吗

这是我的源代码从Windows版本:

private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
{
    ColourAtlas selected = message.SelectedColourAtlas;
    var vm = viewmodel as ColorMatchviewmodel;

    List<ComboBox> newComboBoxes = new List<ComboBox>();
    var currentCount = ColourPickersContainer.Children.Count;
    for ( int i = currentCount; i < message.ColourCodePartCount; i++ )
    {
        ComboBox cb = new ComboBox { Margin = new Thickness( 0,10,0 ),PlaceholderText = "choose" };
        Binding itemsSourceBinding = new Binding();
        itemsSourceBinding.Path = new PropertyPath( "ColourPartLists[" + i + "]" );
        Binding selectedItembinding = new Binding();
        selectedItembinding.Path = new PropertyPath( "SelectedColourCodeParts[" + i + "]" );
        selectedItembinding.Mode = BindingMode.TwoWay;
        cb.Tag = i;
        ColourPickersContainer.Children.Add( cb );
        cb.SetBinding( ComboBox.ItemsSourceProperty,itemsSourceBinding );
        cb.SetBinding( ComboBox.SelectedItemProperty,selectedItembinding );
        cb.SelectionChanged += cb_SelectionChanged;                                
        BindingOperations.SetBinding( cb,ComboBox.SelectedItemProperty,selectedItembinding );
        newComboBoxes.Add( cb );
    }
    while ( ColourPickersContainer.Children.Count > message.ColourCodePartCount )
    {
        ColourPickersContainer.Children.RemoveAt( ColourPickersContainer.Children.Count - 1 );
    }
    _comboBoxes = newComboBoxes;            
}

void cb_SelectionChanged( object sender,SelectionChangedEventArgs e )
{
    var cb = sender as ComboBox;
    int changedindex = ( int )cb.Tag;
    if ( e.AddedItems.Count > 0 )
    {
        ( DataContext as ColorMatchviewmodel ).ColourCodePartChangedCommand.Execute( changedindex );
    }
}

而这里是iOS版本(或多或少是同样的事情 – 虽然它只是清除现有的旋转器,而不是重用它们):

private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
{
    ColourAtlas selected = message.SelectedColourAtlas;
    ClearPickers();
    var currentSet = this.CreateBindingSet<ColorMatchView,ColorMatchviewmodel>();
    for ( int i = 0; i < message.ColourCodePartCount; i++ )
    {
        var j = i;
        UIPickerView picker = new UIPickerView();
        var pickerviewmodel = new MvxPickerviewmodel( picker );
        picker.Model = pickerviewmodel;
        picker.ShowSelectionIndicator = true;
        pickerviewmodel.selecteditemchanged += vm_selecteditemchanged;
        var textView = new PaddedUITextField( new RectangleF( 10,50 + i * 40,300,30 ) );
        Add( textView );
        textView.InputView = picker;
        _pickers.Add( picker );
        _textViews.Add( textView );
        currentSet.Bind( textView ).For( t => t.Text ).To( "SelectedColourCodeParts[" + i + "]" );
        currentSet.Bind( pickerviewmodel ).For( p => p.ItemsSource ).To( "ColourPartLists[" + i + "]" );
        currentSet.Bind( pickerviewmodel ).For( p => p.SelectedItem ).To( "SelectedColourCodeParts[" + i + "]" );
        currentSet.Bind( pickerviewmodel ).For( p => p.SelectedChangedCommand ).To( vm => vm.ColourCodePartChangedCommand ).CommandParameter( j );
    }
    currentSet.Apply();
    UpdateLayout( View.Frame.Size );
}

private void ClearPickers()
{
    foreach ( var picker in _pickers )
    {
        var vm = picker.Model as MvxPickerviewmodel;
        vm.selecteditemchanged -= vm_selecteditemchanged;
        picker.RemoveFromSuperview();
    }
    foreach ( var textView in _textViews )
    {
        textView.RemoveFromSuperview();
    }
    _pickers.Clear();
    _textViews.Clear();
}

我现在的Android版本的部分(而不是功能)大纲如下:

private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
        {
            ColourAtlas selected = message.SelectedColourAtlas;
            var layout = FindViewById<LinearLayout>( Resource.Id.spinnerList );
            ClearPickers();

            for ( int i = 0; i < message.ColourCodePartCount; i++ )
            {
                MvxSpinner spinner = new MvxSpinner( Context??,Attrs??);
                MvxAdapter adapter = new MvxAdapter( this );

                spinner.ItemSelected += spinner_ItemSelected;
                layout.AddView( spinner );
                _spinners.Add( spinner );
            }
        }

        void spinner_ItemSelected( object sender,AdapterView.ItemSelectedEventArgs e )
        {
            var changedindex = _spinners.IndexOf( sender as MvxSpinner );
            ( DataContext as ColorMatchviewmodel ).ColourCodePartChangedCommand.Execute( changedindex );
        }

        private void ClearPickers()
        {
            var layout = FindViewById<LinearLayout>( Resource.Id.spinnerList );
            foreach ( var spinner in _spinners )
            {
                spinner.ItemSelected -= spinner_ItemSelected;
            }
            layout.RemoveAllViews();
            _spinners.Clear();
        }

解决方法

以下是关于如何通过Activity.OnCreate中的代码创建mvxspinner的示例:
_bindingContext = new MvxAndroidBindingContext(this,new LayoutInflaterProvider(LayoutInflater),_viewmodel);
var view = (LinearLayout)_bindingContext.BindingInflate(Resource.Layout.Main,null);
SetContentView(view);
var spinner = new MvxSpinner(this,null,new MvxAdapter(this,_bindingContext));
view.AddView(spinner);

那么如果你想要你的LayoutInflaterProvider可能看起来像这样:

public class LayoutInflaterProvider
    : IMvxLayoutInflater
{
    public LayoutInflaterProvider(LayoutInflater layoutInflater)
    {
        LayoutInflater = layoutInflater;
    }

    public LayoutInflater LayoutInflater { get; private set; }
}

我最初是在看这个tutorial.

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...