ListView不会取消选择

时间:2018-04-06 04:52:41

标签: c# xamarin xamarin.forms xamarin.ios xamarin.android

我正在使用ListView处理Xamarin.Forms项目。

ListView的XAML是

<render:CustomListView x:Name="listview" ItemSelected="ItemSelected" ItemTapped="ItemTapped"></render:CustomListView>

C#是

public void ItemTapped(object sender, ItemTappedEventArgs e)
    {
        var Selected = e.Item as Classes.NavigationItem;
        //Handle clicked
        }
       ((ListView)sender).SelectedItem = null;

    }

    private void ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        ((ListView)sender).SelectedItem = null;
    }

我的自定义渲染器

Android(自定义列表视图):

public class NavigationListViewAndroid : ListViewRenderer
{
    #pragma warning disable CS0618 // Type or member is obsolete
    public NavigationListViewAndroid() { }
    #pragma warning restore CS0618 // Type or member is obsolete

    public NavigationListViewAndroid(Context context) : base(context)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
    {
        base.OnElementChanged(e);
        Control.SetSelector(Android.Resource.Color.DarkerGray);
    }

}

iOS(ViewCell):

public class NavigationViewCelliOS : ViewCellRenderer
{
    public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
    {
        var cell = base.GetCell(item, reusableCell, tv);
        cell.SelectionStyle = UITableViewCellSelectionStyle.Gray;

        return cell;
    }
}

我的问题是:

Android:它选择了行但保持选中状态,直到你点击另一行(两者都有),我希望它在你放手时取消选择

iOS:即使按住

,也永远不会突出显示灰色

4 个答案:

答案 0 :(得分:3)

要将背景颜色应用于列表视图所选项目,请按以下步骤操作:

进行自定义控制:

using Xamarin.Forms;

namespace xamformsdemo.CustomControls
{
  public class ExtendedViewCell : ViewCell
  {
    public static readonly BindableProperty SelectedBackgroundColorProperty =
    BindableProperty.Create("SelectedBackgroundColor", 
                            typeof(Color), 
                            typeof(ExtendedViewCell), 
                            Color.Default);

    public Color SelectedBackgroundColor
    {
       get { return (Color)GetValue(SelectedBackgroundColorProperty); }
       set { SetValue(SelectedBackgroundColorProperty, value); }
    }
  }
}

Android渲染器:

[assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))]
namespace xamformsdemo.Droid.CustomRenderers
{
  public class ExtendedViewCellRenderer : ViewCellRenderer
  {

private Android.Views.View _cellCore;
private Drawable _unselectedBackground;
private bool _selected;

protected override Android.Views.View GetCellCore(Cell item, 
                                                  Android.Views.View convertView, 
                                                  ViewGroup parent, 
                                                  Context context)
{
  _cellCore = base.GetCellCore(item, convertView, parent, context);

  _selected = false;
  _unselectedBackground = _cellCore.Background;

  return _cellCore;
}

protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
  base.OnCellPropertyChanged(sender, args);

  if (args.PropertyName == "IsSelected")
  {
    _selected = !_selected;

    if (_selected)
    {
      var extendedViewCell = sender as ExtendedViewCell;
      _cellCore.SetBackgroundColor(extendedViewCell.SelectedBackgroundColor.ToAndroid());
    }
    else
    {
      _cellCore.SetBackground(_unselectedBackground);
    }
  }
}
  }

}

iOS渲染器:

[assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))]
namespace xamformsdemo.iOS.CustomRenderers
{
  public class ExtendedViewCellRenderer : ViewCellRenderer
  {
    public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
   {
      var cell = base.GetCell(item, reusableCell, tv);
      var view = item as ExtendedViewCell;
      cell.SelectedBackgroundView = new UIView
       {
         BackgroundColor = view.SelectedBackgroundColor.ToUIColor(),
       };

      return cell;
    }

  }
}

在XAML中使用:

<ListView.ItemTemplate>
  <DataTemplate>
    <customControls:ExtendedViewCell SelectedBackgroundColor="Teal">
      <ViewCell.View>
        <StackLayout HorizontalOptions="FillAndExpand" 
                     VerticalOptions="FillAndExpand" Orientation="Vertical" 
                     Padding="4" Spacing="8">
          <Label TextColor="White" Text="{Binding .ItemName}"/>
          <Label TextColor="Yellow" Text="{Binding .LastUpdated, StringFormat='Last seen: {0:HH:mm:ss}'}"/>
        </StackLayout>
      </ViewCell.View>
    </customControls:ExtendedViewCell>
  </DataTemplate>
</ListView.ItemTemplate>

您可以参考以下链接解决问题:https://blog.wislon.io/posts/2017/04/11/xamforms-listview-selected-colour

答案 1 :(得分:1)

我有同样的问题,我使用的是ItemSelected,但是除非直到我选择ListView中的任何其他项目,否则所选的项目不会被取消选择。 我用ItemTapped替换ItemSelected。它对我有用。

答案 2 :(得分:1)

我更喜欢使用SelectedItem属性来处理简单点击。这与平台无关,一切都可以在视图模型代码中完成。

诀窍是再次将属性设置为null以在评估后立即取消选择该项(在hte示例中,我将其用于初始化另一个视图模型)。

<强> XAML:

<ListView ItemsSource="{Binding Items}" 
    SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">

<强> ViewModel.cs:

public Command<IProduct> ViewDetailsCommand;
public ViewModel()
{
     ViewDetailsCommand = new Command<IProduct>(async s => await ViewDetails(s));
}

public IProduct SelectedProduct
{
    get { return _selectedProduct; }
    set
    {
        if (value != _selectedProduct)
        {
            SetProperty(ref _selectedProduct, value);
            if (value != null)
            {
                ViewDetailsCommand.Execute(value);
            }
        }
    }
}

private async Task ViewDetails(IProduct product)
{
    var viewModel = AppContainer.Container.Resolve<ProductDetailsViewModel>();
    viewModel.Initialise(this, product as ShoppingListItemViewModel);
    SelectedProduct = null;
    await _pageNavigator.PushModalAsync(viewModel);
}

答案 3 :(得分:1)

在Android上如果您只想在使用时更改颜色,请单击ListView的项目。您可以修改样式:

在Api 21之前,在drawable文件夹中创建一个xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@color/colorPrimary" android:state_pressed="false"/>  
  <item android:drawable="@color/colorAccent" android:state_pressed="true"/>  
  <item android:drawable="@color/colorPrimary"/>                              
</selector>

在Api 21+上,在drawable-v21文件夹下创建具有相同名称的文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorAccent">
  <item android:drawable="@color/colorPrimaryDark"/>
</ripple>

然后在渲染器中更改样式:

// f_selector is the xml file's name
Control.SetSelector(Resource.Drawable.f_selector);

最后更改资源文件 colors.xml 中的颜色:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="colorPrimary">#3F51B5</color> <!--original background color api21- -->
  <color name="colorPrimaryDark">#FFFFFF</color> <!--original background color api21+ -->
  <color name="colorAccent">#FF313030</color> 
</resources>