我在Xamarin表单中创建了一个翻转视图的控件(如卡片样式)。这两个视图都有某种输入(EX:按钮列表),如果你进行交互,将会翻转" Card"控制到下一个视图。我能够使用Android,但是当我使用IOS进行测试时,控件似乎被禁用,我无法点击任何事件。现在我通过使用e.NativeView.UserInteractionEnabled属性解决了类似的问题。唯一的问题是这个属性只能在初始化视图时使用,我希望能够使用更具动态性的类似东西。
IOS问题略有进展。
<?xml version="1.0" encoding="utf-8" ?>
<TemplatedView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="minto.qm.mobile.Views.Controls.PanelView">
<TemplatedView.ControlTemplate>
<ControlTemplate>
<AbsoluteLayout>
//the last item in this list will be the dominant control on runtime
//the other views input will not work
<ContentView Content="{TemplateBinding BackContent}" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional,PositionProportional" AnchorX="0.5" AnchorY="0.5"></ContentView>
<ContentView Content="{TemplateBinding FrontContent}" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional,PositionProportional" AnchorX="0.5" AnchorY="0.5"></ContentView>
</AbsoluteLayout>
</ControlTemplate>
</TemplatedView.ControlTemplate>
</TemplatedView>
有没有人知道这样的任何功能?
更新
这是控件的后面代码:
public partial class PanelView : TemplatedView
{
public event EventHandler FrontContentAppeared;
public event EventHandler BackContentAppeared;
public static readonly BindableProperty FrontContentProperty = BindableProperty.Create(nameof(FrontContent), typeof(View), typeof(PanelView), defaultValue: null, propertyChanged: OnFrontContentChanged);
public static readonly BindableProperty BackContentProperty = BindableProperty.Create(nameof(BackContent), typeof(View), typeof(PanelView), defaultValue: null, propertyChanged: OnBackContentChanged);
public static readonly BindableProperty SwitchViewProperty = BindableProperty.Create(nameof(SwitchView), typeof(bool), typeof(PanelView), defaultValue: false, propertyChanged: OnSwitchViewChanged);
private bool _isFrontView = true;
public PanelView()
{
InitializeComponent();
}
private async void SwitchCurrentView()
{
if (_isFrontView)
{
BackContent.IsVisible = true;
//BackContent.InputTransparent = true;
FrontContent.Unfocus();
BackContent.Focus();
await Task.WhenAll(
FrontContent.FadeTo(0, 500, Easing.Linear),
BackContent.FadeTo(1, 500, Easing.Linear),
this.RotateYTo(GetRotation(0, 180), 250, Easing.Linear)
);
FrontContent.IsVisible = false;
//FrontContent.InputTransparent = false;
BackContentAppeared?.Invoke(this, EventArgs.Empty);
}
else
{
FrontContent.IsVisible = true;
//FrontContent.InputTransparent = true;
FrontContent.Focus();
BackContent.Unfocus();
await Task.WhenAll(
FrontContent.FadeTo(1, 500, Easing.Linear),
BackContent.FadeTo(0, 500, Easing.Linear),
this.RotateYTo(GetRotation(180, 180), 250, Easing.Linear)
);
BackContent.IsVisible = false;
//BackContent.InputTransparent = false;
FrontContentAppeared?.Invoke(this, EventArgs.Empty);
}
_isFrontView = !_isFrontView;
SwitchView = false;
}
private static void OnFrontContentChanged(BindableObject bindable, object oldValue, object newValue)
{
var self = (PanelView)bindable;
self.SetFrontContentView((View)newValue);
}
private static void OnBackContentChanged(BindableObject bindable, object oldValue, object newValue)
{
var self = (PanelView)bindable;
self.SetBackContentView((View)newValue);
}
private static void OnSwitchViewChanged(BindableObject bindable, object oldValue, object newValue)
{
var self = (PanelView)bindable;
self.SwitchView = (bool)newValue;
if (self.SwitchView)
{
self.SwitchCurrentView();
}
}
private void SetFrontContentView(View view)
{
FrontContent = view;
if (!_isFrontView)
{
FrontContent.IsVisible = false;
view.FadeTo(0, 1, Easing.Linear);
}
}
private void SetBackContentView(View view)
{
view.FadeTo(0, 1, Easing.Linear);
view.RotateYTo(180, 1, Easing.Linear);
BackContent = view;
if (_isFrontView)
{
BackContent.IsVisible = false;
}
}
private double GetRotation(double start, double amount)
{
var rotation = (start + amount) % 360;
return rotation;
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (FrontContent != null)
{
SetInheritedBindingContext(FrontContent, BindingContext);
}
if (BackContent != null)
{
SetInheritedBindingContext(BackContent, BindingContext);
}
}
public View FrontContent
{
get { return (View)GetValue(FrontContentProperty); }
set { SetValue(FrontContentProperty, value); }
}
public View BackContent
{
get { return (View)GetValue(BackContentProperty); }
set { SetValue(BackContentProperty, value); }
}
public bool SwitchView
{
get { return (bool)GetValue(SwitchViewProperty); }
set { SetValue(SwitchViewProperty, value); }
}
}
当可绑定的bool变量SwitchView更改时,动画运行
private void OnRoomTypeTapped(object sender, GliderItemTappedEventArgs e)
{
if (e.IsSelected && e.IsSelected == e.LastSelection)
{
PanelView.SwitchView = true;
}
}
更新
Xaml Page示例。注意:(基本:ExtendedPage是一个自定义内容页面)和(控件:滑翔机是自定义视图,上面有按钮列表)
<?xml version="1.0" encoding="utf-8" ?>
<base:ExtendedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:minto.qm.mobile.Views.Controls;assembly=minto.qm.mobile"
xmlns:base="clr-namespace:minto.qm.mobile.Views.Pages.Base;assembly=minto.qm.mobile"
x:Class="minto.qm.mobile.Views.Pages.RoomPage"
Navigation="{Binding Navigation, Mode=OneWayToSource}"
Title="Room">
<base:ExtendedPage.Content>
<ScrollView>
<StackLayout Spacing="0">
<ContentView BackgroundColor="#3498DB" Padding="10">
<Label Text="{Binding SelectedRoomName}" FontAttributes="Bold" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"></Label>
</ContentView>
<StackLayout Spacing="5" Padding="10, 20, 10, 10">
<controls:PanelView x:Name="PanelView">
<controls:PanelView.FrontContent>
<controls:Glider ItemsSource="{Binding RoomTypes}" DisplayProperty="Name" SelectedIndex="0" ItemSelected="OnRoomTypeSelected" ItemTapped="OnRoomTypeTapped" Orientation="Vertical" Lines="3" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"></controls:Glider>
</controls:PanelView.FrontContent>
<controls:PanelView.BackContent>
<controls:Glider ItemsSource="{Binding Rooms}" DisplayProperty="Name" SelectedIndex="0" ItemSelected="OnRoomSelected" ItemTapped="OnRoomTapped" Orientation="Horizontal" Lines="5" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"></controls:Glider>
</controls:PanelView.BackContent>
</controls:PanelView>
<StackLayout Orientation="Horizontal">
<Label Text="Room annotation:" FontAttributes="Bold" Margin="5, 0, 0, 0" VerticalTextAlignment="Center"></Label>
<Button Text="<" FontAttributes="Bold" HorizontalOptions="EndAndExpand" VerticalOptions="Center" BackgroundColor="Transparent" WidthRequest="50" HeightRequest="50" Clicked="OnExpandButtonClicked" FontSize="Medium" AnchorX="0.5" AnchorY="0.5"></Button>
</StackLayout>
<Entry x:Name="AnnotationEditor" HorizontalOptions="FillAndExpand" BackgroundColor="#4D4D4D" TextChanged="Entry_OnTextChanged"/>
<Button Text="Next" Command="{Binding NextPageCommand}" HorizontalOptions="FillAndExpand" />
</StackLayout>
</StackLayout>
</ScrollView>
</base:ExtendedPage.Content>
<base:ExtendedPage.Overlay>
<controls:Tombstone Token="{Binding DeficiencyToken}" BackgroundColor="#444444"></controls:Tombstone>
</base:ExtendedPage.Overlay>
<base:ExtendedPage.ToolbarItems>
<ToolbarItem Text="Details" Order="Primary" Priority="0" Clicked="DetailsClicked"></ToolbarItem>
</base:ExtendedPage.ToolbarItems>
</base:ExtendedPage>
public partial class RoomPage : ExtendedPage
{
public ViewModels.Pages.RoomPage ViewModel => _vm ?? (_vm = BindingContext as ViewModels.Pages.RoomPage);
private ViewModels.Pages.RoomPage _vm;
private bool _buttonExpanded;
public RoomPage()
{
InitializeComponent();
BindingContext = new ViewModels.Pages.RoomPage();
}
protected override void OnAppearing()
{
base.OnAppearing();
ViewModel.OnAppearing();
HandleCaching();
}
private async void HandleCaching()
{
await Task.Run(() =>
{
var pageCache = Services.Caches.Pages.GetInstance();
pageCache.Preload(nameof(InspectionGalleryPage), new InspectionGalleryPage());
});
}
private void DetailsClicked(object sender, EventArgs e)
{
ShowOverlay = !ShowOverlay;
}
private void Entry_OnTextChanged(object sender, TextChangedEventArgs e)
{
ViewModel.RoomAnnotations = e.NewTextValue;
}
private void OnRoomTypeSelected(object sender, GliderItemSelectedEventArgs e)
{
ViewModel.SelectedRoomTypeName = e.Item.ToString();
}
private void OnRoomTypeTapped(object sender, GliderItemTappedEventArgs e)
{
if (e.IsSelected && e.IsSelected == e.LastSelection)
{
PanelView.SwitchView = true;
}
}
private void OnRoomSelected(object sender, GliderItemSelectedEventArgs e)
{
ViewModel.SelectedRoomName = e.Item.ToString();
}
private void OnRoomTapped(object sender, GliderItemTappedEventArgs e)
{
if (e.IsSelected && e.IsSelected == e.LastSelection)
{
PanelView.SwitchView = true;
}
}
private void AnimateHeight(View view, double end)
{
view.Animate("Expander", value => view.HeightRequest = value, view.Height, end, 2, 250, Easing.Linear);
}
private void OnExpandButtonClicked(object sender, EventArgs e)
{
var button = (Button) sender;
if (_buttonExpanded)
{
button.RotateTo(0, 250, Easing.Linear);
AnimateHeight(AnnotationEditor, 45.5);
}
else
{
button.RotateTo(-90, 250, Easing.Linear);
AnimateHeight(AnnotationEditor, 300);
}
_buttonExpanded = !_buttonExpanded;
}
}
答案 0 :(得分:0)
正如我所说,“某事”正在覆盖你的按钮。这是有问题的声明
<AbsoluteLayout>
<ContentView Content="{TemplateBinding BackContent}" BackgroundColor="Transparent" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional,PositionProportional" AnchorX="0.5" AnchorY="0.5"></ContentView>
<ContentView Content="{TemplateBinding FrontContent}" BackgroundColor="Transparent" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional,PositionProportional" AnchorX="0.5" AnchorY="0.5"></ContentView>
</AbsoluteLayout>
您的FrontContent ContentView涵盖BackContent ContentView。当您旋转和隐藏内容时,您实际使用按钮而不是视图。我发现这个设计比它应该更复杂,但不管这不是问题。以下是解决方案。当您隐藏内容(含义按钮)时,也会隐藏您的父视图并在显示按钮时显示它。
private async void SwitchCurrentView()
{
if (_isFrontView)
{
BackContent.IsVisible = true;
((ContentView)BackContent.Parent).IsVisible = true;//************************
FrontContent.Unfocus();
BackContent.Focus();
await Task.WhenAll(
FrontContent.FadeTo(0, 500, Easing.Linear),
BackContent.FadeTo(1, 500, Easing.Linear),
this.RotateYTo(GetRotation(0, 180), 250, Easing.Linear)
);
FrontContent.IsVisible = false;
((ContentView)FrontContent.Parent).IsVisible = false;//******************
BackContentAppeared?.Invoke(this, EventArgs.Empty);
}
else
{
FrontContent.IsVisible = true;
((ContentView)FrontContent.Parent).IsVisible = true;
FrontContent.Focus();
BackContent.Unfocus();
await Task.WhenAll(
FrontContent.FadeTo(1, 500, Easing.Linear),
BackContent.FadeTo(0, 500, Easing.Linear),
this.RotateYTo(GetRotation(180, 180), 250, Easing.Linear)
);
BackContent.IsVisible = false;
((ContentView)BackContent.Parent).IsVisible = false;
FrontContentAppeared?.Invoke(this, EventArgs.Empty);
}
_isFrontView = !_isFrontView;
SwitchView = false;
}