【问题标题】:How to show label to appear off the page when using StackLayout使用 StackLayout 时如何显示标签以显示在页面外
【发布时间】:2018-05-02 21:40:11
【问题描述】:

我有一个向左滑动的手势,我希望标签看起来像是从屏幕上滑出一样。

如何使用 xamarin 表单实现这一目标?

例如在下图中选择的项目是“检查伦敦-巴黎的火车时刻表”

当项目被选中时,文本会出现在屏幕之外。我也想达到同样的效果

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    用 2 列创建一个可爱的网格。

    EDIT 该网格将位于水平滚动视图内。这就是使走出屏幕的技巧成为可能的原因。 现在,如果您想禁止用户手动滚动 ScrollView,请使用自定义渲染器。但是,如果您希望用户能够左右滑动控件,则不需要这样做,它会很自然地运行。因此,在下面的 XAML 代码中,您可以只使用 ScrollView 而不是 controls:DisabledScrollView

    第一列是您在屏幕上看到的内容。 第二列是隐藏在屏幕之外的内容。 第一个 col 宽度 = ScreenSize。在代码中定义,因为它可以在屏幕旋转时动态变化。 第二列宽 - 随意。在您的情况下,仅此 TrashCan 图标就很小。 我在网格的 OnSize 更改事件中管理它,从 XAML 调用 OnSizeChanged_TitleBarMain

                cNavBarSlider.ColumnDefinitions.Clear();    
                cNavBarSlider.ColumnDefinitions.Add(
                    new ColumnDefinition { Width = new GridLength(ScreenWidth, GridUnitType.Absolute) }
                    );
                cNavBarSlider.ColumnDefinitions.Add(
                    new ColumnDefinition { Width = new GridLength(ScreenWidth - popupSearchOffset, GridUnitType.Absolute) }
                );
    
                //reposition scroll if needed (on screen rotation)
                if (IsPopupSearchVisible)
                {
                    await cNavBarSlider.TranslateTo(-ScreenWidth + popupSearchOffset, 0, 0, null);
                }
    

    用 TranslateTo 左右滑动这个表格,在我的例子中是:

    await cNavBarSlider.TranslateTo(-cTitleBarMain.Width + popupSearchOffset, 0, PopupOptionsTimeIn, Easing.CubicInOut);
    

    IconSearch 和 Cancel 热点(使用热点,我希望更大的区域来响应触摸,而不是用户试图点击一些小图标或小字)调用相同的方法:

    private bool _tapped;
        //-------------------------------------------------------------
        private async void OnTapped_SearchIcon(object sender, EventArgs e)
        //-------------------------------------------------------------
        {
            if (_tapped) return;
            _tapped = true;
            if (!IsPopupSearchVisible) await PopupSearchShow();
            else await PopupSearchHide();
            _tapped = false;
        }
    //-------------------------------------------------------------------
    public async Task PopupSearchShow()
    //-------------------------------------------------------------------
    {
        await PopupSearchInit();
        await cNavBarSlider.TranslateTo(-cTitleBarMain.Width + popupSearchOffset, 0, PopupOptionsTimeIn, Easing.CubicInOut);
        IsPopupSearchVisible = true;
        ControlSearchEntry.Focus();
    }
    //-------------------------------------------------------------------
    public async Task PopupSearchHide(bool animate = true)
    //-------------------------------------------------------------------
    {
        uint d = PopupOptionsTimeOut;
        if (!animate) d = 0;
        await cNavBarSlider.TranslateTo(0, 0, d, Easing.CubicInOut);
        IsPopupSearchVisible = false;
    }
    

    可使用的 XAML 方案:

            <!--  SWIPE CONTAINER  -->
            <controls:DisabledScrollView Orientation="Horizontal" VerticalOptions="FillAndExpand">
                <Grid
                    x:Name="cNavBarSlider"
                    ColumnSpacing="0"
                    HorizontalOptions="Fill">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
    
                    <!--  this in on screen, going to swipe -->
                    <Grid
                        x:Name="cTitleBarMain"
                        Grid.Column="0"
                        SizeChanged="OnSizeChanged_TitleBarMain">
                        <!--  put ur stuff here  -->
                    </Grid>
    
                    <StackLayout
                        x:Name="cTitleBarSearch"
                        Grid.Column="1"
                        Orientation="Horizontal">
                        <!-- your hidden content to appear put here --!>
                    <StackLayout>
    
                </Grid>
            </controls:DisabledScrollView>
    

    编辑

    这是您在列表中的代码(Android 模拟器)注意,您可以实现滑动来限制滚动坐标,使其粘在边界上:

    列表视图:

        <ListView
            x:Name="MainList"
            ItemsSource="{Binding Items}"
            BackgroundColor="{StaticResource ColorListView}"
            HasUnevenRows="False"
            RowHeight="40"
            HorizontalOptions="FillAndExpand"
            IsVisible="{Binding IsOffline, Converter={StaticResource not}}"
            ItemSelected="MainList_OnItemSelected"
            RefreshCommand="{Binding ForceRefreshCommand}">
            <ListView.SeparatorColor>
                <OnPlatform
                    x:TypeArguments="Color"
                    WinPhone="{StaticResource ListSeparator}"
                    iOS="{StaticResource ListSeparator}" />
            </ListView.SeparatorColor>
    
            <ListView.ItemTemplate>
                <DataTemplate>
    
                    <appoMobi:CellJessica/>
    
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    

    单元格 XAML:

    <?xml version="1.0" encoding="utf-8" ?>
    <ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="AppoMobi.CellJessica"
          x:Name="MyViewCell">
        <!--  SWIPE CONTAINER  -->
        <StackLayout SizeChanged="OnSizeChanged_TitleBarMain" x:Name="cCell" HorizontalOptions="FillAndExpand">
    
            <ScrollView x:Name="scrollView" 
                            Orientation="Horizontal" 
                            VerticalOptions="FillAndExpand">
                <Grid x:Name="cNavBarSlider"
                          ColumnSpacing="0"
                          HorizontalOptions="Fill">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
    
                    <!--  this in on screen, going to swipe -->
                    <Grid 
                        x:Name="cTitleBarMain"
                        Grid.Column="0">
                        <!--  put ur stuff here  -->
                        <Label x:Name="txtLabel" TextColor="Black" />
                    </Grid>
    
                    <StackLayout
                        x:Name="cTitleBarSearch"
                        Grid.Column="1"
                        Orientation="Horizontal">
                        <Image Source="cake" HeightRequest="35" WidthRequest="35"   VerticalOptions="Center" HorizontalOptions="Start" />
                    </StackLayout>
    
                </Grid>
            </ScrollView>
    
        </StackLayout>
    </ViewCell>
    

    单元格代码:

       public partial class CellJessica
        {
            public CellJessica()
            {
                InitializeComponent();
            }
            //-------------------------------------------------------------
            protected override void OnBindingContextChanged()
            //-------------------------------------------------------------
            {
                SetupCell();
                base.OnBindingContextChanged();
            }
    
            private bool first_setup = true;
            //-------------------------------------------------------------
            public void SetupCell()
            //-------------------------------------------------------------
            {
    
                var item = BindingContext as CSalonListItemEx;
                if (item == null) return;
    
    
                txtLabel.Text = item.Name;
    
            }
            private bool _titlebar_changingsize = false;
    
            private double popupSearchOffset = 0;
            //-------------------------------------------------------------------
            private async void OnSizeChanged_TitleBarMain(object sender, EventArgs e)
                //-------------------------------------------------------------------
            {
                if (_titlebar_changingsize) return;
                _titlebar_changingsize = true;
    
                cNavBarSlider.ColumnDefinitions.Clear();
                cNavBarSlider.ColumnDefinitions.Add(
                    new ColumnDefinition { Width = new GridLength(cCell.Width, GridUnitType.Absolute) }
                );
                cNavBarSlider.ColumnDefinitions.Add(
                //new ColumnDefinition { Width = new GridLength(cCell.Width - popupSearchOffset, GridUnitType.Absolute) }
                    new ColumnDefinition { Width = new GridLength(40, GridUnitType.Absolute) }
                );
    
                //todo
                //reposition scroll if rotated when hidden barea is shown
                //if (IsPopupSearchVisible)
                //{
                //    await cNavBarSlider.TranslateTo(-cCell.Width + 40, 0, 0, null);
                //}
    
                _titlebar_changingsize = false;
            }
        }
    

    【讨论】:

    • 嗨尼克,这看起来很有希望 - 你知道是否可以使用 xaml 标记吗?还有你的 cTitleBarMain 会发生什么?我也很好奇你是如何恢复正常状态的?你的取消按钮有什么作用,它只显示第一列吗?
    • 如您所见,cTitleBarMain 只是按代码滑动... 上面编辑的帖子更清楚。我不好这个页面使用了禁用的滚动视图,请尽快编辑上面的帖子。
    • 相信还有很多其他的解决方案,尤其是使用绝对布局,这只是其中之一..
    • 非常感谢您提供此示例。我在让它工作时遇到问题。也许问题是这在 ViewCell 中不起作用?我基本上复制了上面的大部分代码,但它似乎没有按预期工作。只显示我在
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多