3

Ich werde etwas wie ChatView mit vordefinierten Nachrichten mit Xamarin Formen erstellen. Wenn ich auf dem Bildschirm klicken neue Nachricht erscheint (es einfach hinzugefügt Nachrichten beobachtbare Sammlung)Xamarin Formulare ListView Scroll-UI-Probleme

ich nächste benutzerdefinierte Zelle haben (Bubble)

<ViewCell x:Class="stori.es.Pages.Chat.Views.BubbleCell" 
     xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     xmlns:controls="clr-namespace:App.Platform.Forms.Controls;assembly=App.Platform" 
     x:Name="Root"> 
<ViewCell.View> 
    <AbsoluteLayout Padding="10" 
        HorizontalOptions="FillAndExpand" 
        VerticalOptions="FillAndExpand"> 

     <controls:ExtendedStackLayout x:Name="MessageLayout" 
             Padding="10" 
             AbsoluteLayout.LayoutBounds="0,0,1,1" 
             AbsoluteLayout.LayoutFlags="All" 
             BorderRadius="15"> 

      <Label x:Name="AuthorLabel" 
        FontSize="10" 
        HorizontalOptions="EndAndExpand" 
        VerticalOptions="StartAndExpand" /> 

      <Grid HorizontalOptions="FillAndExpand"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="*" /> 
       </Grid.ColumnDefinitions> 

       <Label x:Name="TextLabel" 
         FontSize="16" 
         HorizontalOptions="FillAndExpand" 
         VerticalOptions="FillAndExpand" /> 
      </Grid> 

     </controls:ExtendedStackLayout> 

    </AbsoluteLayout> 

</ViewCell.View> 

Mit hinter nächsten Code:

public partial class BubbleCell : ViewCell 
{ 
    public static readonly BindableProperty IsIncomingProperty = 
     BindableProperty.Create(nameof(IsIncoming), typeof(bool), typeof(BubbleCell), true); 

    public static readonly BindableProperty TextProperty = 
     BindableProperty.Create(nameof(Text), typeof(string), typeof(BubbleCell), string.Empty); 

    public static readonly BindableProperty AuthorProperty = 
     BindableProperty.Create(nameof(Author), typeof(string), typeof(BubbleCell), string.Empty); 

    public static readonly BindableProperty IncomingBackgoundColorProperty = 
     BindableProperty.Create(nameof(IncomingBackgoundColor), typeof(Color), typeof(BubbleCell), Color.White); 

    public static readonly BindableProperty IncomingTextColorProperty = 
     BindableProperty.Create(nameof(IncomingTextColor), typeof(Color), typeof(BubbleCell), Color.Black); 

    public static readonly BindableProperty OutcomingBackgoundColorProperty = 
     BindableProperty.Create(nameof(OutcomingBackgroundColor), typeof(Color), typeof(BubbleCell), Color.White); 

    public static readonly BindableProperty OutComingTextColorProperty = 
     BindableProperty.Create(nameof(OutcomingTextColor), typeof(Color), typeof(BubbleCell), Color.Black); 

    public static readonly BindableProperty IncomingAuthorTextColorProperty = 
     BindableProperty.Create(nameof(IncomingAuthorTextColor), typeof(Color), typeof(BubbleCell), Color.White); 

    public static readonly BindableProperty OutcomingAuthorTextColorProperty = 
     BindableProperty.Create(nameof(OutcomingAuthorTextColor), typeof(Color), typeof(BubbleCell), Color.Black); 

    public BubbleCell() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnBindingContextChanged() 
    { 
     base.OnBindingContextChanged(); 
     AbsoluteLayout.SetLayoutBounds(MessageLayout, IsIncoming ? new Rectangle(0, 0, 0.7,1) : new Rectangle(1, 1, 0.7,1)); 
     MessageLayout.BackgroundColor = LayoutBackgroundColor; 
     TextLabel.Text = Text; 
     AuthorLabel.Text = Author; 
     TextLabel.TextColor = TextColor; 
     AuthorLabel.TextColor = TextColor; 
    } 



    public bool IsIncoming 
    { 
     get => (bool) GetValue(IsIncomingProperty); 
     set => SetValue(IsIncomingProperty, value); 
    } 

    public string Text 
    { 
     get => (string)GetValue(TextProperty); 
     set => SetValue(TextProperty, value); 
    } 

    public string Author 
    { 
     get => (string)GetValue(AuthorProperty); 
     set => SetValue(AuthorProperty, value); 
    } 

    public Color IncomingBackgoundColor 
    { 
     get => (Color) GetValue(IncomingBackgoundColorProperty); 
     set => SetValue(IncomingBackgoundColorProperty, value); 
    } 

    public Color IncomingTextColor 
    { 
     get => (Color)GetValue(IncomingTextColorProperty); 
     set => SetValue(IncomingTextColorProperty, value); 
    } 

    public Color OutcomingBackgroundColor 
    { 
     get => (Color)GetValue(OutcomingBackgoundColorProperty); 
     set => SetValue(OutcomingBackgoundColorProperty, value); 
    } 

    public Color OutcomingTextColor 
    { 
     get => (Color)GetValue(OutComingTextColorProperty); 
     set => SetValue(OutComingTextColorProperty, value); 
    } 

    public Color IncomingAuthorTextColor 
    { 
     get => (Color)GetValue(IncomingAuthorTextColorProperty); 
     set => SetValue(IncomingAuthorTextColorProperty, value); 
    } 

    public Color OutcomingAuthorTextColor 
    { 
     get => (Color)GetValue(OutcomingAuthorTextColorProperty); 
     set => SetValue(OutcomingAuthorTextColorProperty, value); 
    } 


    [DependsOn(nameof(IsIncoming), nameof(IncomingTextColor), nameof(OutcomingTextColor))] 
    public Color TextColor => IsIncoming ? IncomingTextColor : OutcomingTextColor; 

    [DependsOn(nameof(IsIncoming), nameof(IncomingAuthorTextColor), nameof(OutcomingAuthorTextColor))] 
    public Color AuthorTextColor => IsIncoming ? IncomingAuthorTextColor : OutcomingAuthorTextColor; 

    [DependsOn(nameof(IsIncoming), nameof(IncomingBackgoundColor), nameof(OutcomingBackgroundColor))] 
    public Color LayoutBackgroundColor => IsIncoming ? IncomingBackgoundColor : OutcomingBackgroundColor; 

    [DependsOn(nameof(IsIncoming))] 
    public LayoutOptions CellContentHorizontalOptions => IsIncoming ? LayoutOptions.StartAndExpand : LayoutOptions.EndAndExpand; 

} 

Und ChatListView mit folgendem Code:

public class ChatListView : ListView 
{ 
    public ChatListView() 
    { 
     Initialize(); 
    } 

    public ChatListView(ListViewCachingStrategy cachingStrategy) : base(cachingStrategy) 
    { 
     Initialize(); 
    } 

    private void Initialize() 
    { 
     var chatElementTapGestureRecognizer = new TapGestureRecognizer { Command = new Command(OnTapped) }; 
     GestureRecognizers.Add(chatElementTapGestureRecognizer); 
    } 

    private async void OnTapped() 
    { 
     var lastElement = ItemsSource.Cast<object>().LastOrDefault(); 

     if (lastElement == null) 
     { 
      return; 
     } 
     try 
     { 
      Device.BeginInvokeOnMainThread(() => ScrollTo(lastElement, ScrollToPosition.Start, true)); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
     } 
    } 

und Nutzung von ChatListView ist nächste:

<chatviews:ChatListView HasUnevenRows="True" 
    HorizontalOptions="FillAndExpand" 
    ItemTemplate="{StaticResource MessageTemplateSelector}" 
    ItemsSource="{Binding Messages}" 
    SeparatorVisibility="None" 
    VerticalOptions="FillAndExpand"> 

    <ListView.GestureRecognizers> 
     <TapGestureRecognizer Command="{Binding TapCommand}" /> 
    </ListView.GestureRecognizers> 

    <ListView.Effects> 
     <effects:ListViewNoSelectionEffect /> 
    </ListView.Effects> 

    <chatviews:ChatListView.Footer> 
     <BoxView BackgroundColor="Transparent" 
      HeightRequest="200" 
      HorizontalOptions="FillAndExpand" 
      IsVisible="{Binding IsEndOfStoryReached, Converter={StaticResource InverseBooleanConverter}}" /> 
     </chatviews:ChatListView.Footer> 
    </chatviews:ChatListView> 

Wenn ich mehr als etwa 20 Elemente auf Liste habe ich nächstes Verhalten der Liste, wenn ich dynamisch neues Element hinzuzufügen. Ich weiß auch nicht, wie man das Problem mit falschen Wortumwicklungshöhenberechnungen löst.

Behavior on adding new element

Here is wide gif expierence

+0

Irgendwelche Vorschläge? – Dmitry

Antwort

0

Ich habe iPad und Test auf dem Gerät genommen und es ist kein Problem. Sieht aus wie magisch

Verwandte Themen