Выделите URL с помощью метки span - xamarin.forms - PullRequest
0 голосов
/ 17 января 2020

Я создаю приложение чата в xamarin.forms. Чего я добиваюсь, это когда сообщение, набранное пользователем, содержит URL, который должен быть выделен и предоставлен щелчок. Для этой функции я нашел Span в тексте метки. пользователь нажимает на кнопку отправки чата, я проверю URL и сделаю его еще одним пролетом. Я получил эту идею от Лукас Чжан - MSFT , задайте этот вопрос здесь .

Проблема в том, что я пытаюсь создать модель охвата в представлении, и отдельный пузырь чата находится в другой ячейке представления, которая будет вызываться как ItemTemplate в моем списке просмотра чата. Во всяком случае, охват не работает, как я задумал, т.е. не выделяется.

Мой взгляд Модель .

public Queue<Message> DelayedMessages { get; set; } = new Queue<Message>();
public ObservableCollection<Message> Messages { get; set; } = new  ObservableCollection<Message>();                                         
public string TextToSend { get; set; }

public ChatPageViewModel()
            {                        
                OnSendCommand = new Command(() =>
                {

                    if (!string.IsNullOrEmpty(TextToSend))
                    {

                        var urlStr = TextToSend;

                        int startIndex = 0, endIndex = 0;

                        if (urlStr.Contains("www."))
                        {
                            startIndex = urlStr.IndexOf("www.");
                        }

                        if (urlStr.Contains(".com"))
                        {
                            endIndex = urlStr.IndexOf(".com") + 3;
                        }

                        if (startIndex != 0 || endIndex != 0)
                        {
                            var formattedString = new FormattedString();

                            Span span1 = new Span() { Text = urlStr.Substring(0, startIndex), TextColor = Color.Black };

                            formattedString.Spans.Add(span1);

                            Span span2 = new Span() { Text = urlStr.Substring(startIndex, endIndex - startIndex + 1), TextColor = Color.LightBlue };
                            span2.GestureRecognizers.Add(new TapGestureRecognizer()
                            {
                                NumberOfTapsRequired = 1,
                                Command = new Command(() => {


                                })
                            });

                            formattedString.Spans.Add(span2);

                            Span span3 = new Span() { Text = urlStr.Substring(endIndex, urlStr.Length - 1 - endIndex), TextColor = Color.Black };
                            formattedString.Spans.Add(span3);
                            var message = new Message
                            {
                                Text = formattedString.ToString(),
                                IsIncoming = false,
                                MessageDateTime = DateTime.Now
                            };
                            Messages.Add(message);
                            TextToSend = string.Empty;
                        }

                        else
                        {                  
                            var message = new Message
                            {
                                Text = urlStr.ToString(),
                                IsIncoming = false,
                                MessageDateTime = DateTime.Now
                            };
                            Messages.Add(message);
                            TextToSend = string.Empty;
                        }               
                    }                                  
                });        
            }

Одиночный чат Bubble XAML

<Label  x:Name="OutgoingMessage" TextColor="White"  FormattedText="{Binding Text}" HorizontalOptions="End" >              
</Label>

Страница моего чата XAML

<Grid RowSpacing="0" Margin="0,20,0,0"
       ColumnSpacing="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="1" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ListView Grid.Row="0" 
             ItemTemplate="{StaticResource MessageTemplateSelector}" 
             ItemsSource="{Binding Messages,Mode=OneWay}" 
             Margin="0"       
             SelectionMode="None"                                  
             FlowDirection="RightToLeft"                               
             HasUnevenRows="True" x:Name="ChatList"
             VerticalOptions="FillAndExpand" 
             SeparatorColor="Transparent"
             >
     </ListView>
    <BoxView HorizontalOptions="FillAndExpand"
             HeightRequest="1"
             BackgroundColor="#F2F3F5"
             Grid.Row="1"/>
    <partials:ChatInputBarView Grid.Row="2"
                               Margin="0,0,0,0"
                               x:Name="chatInput"/>
</Grid>

ChatPage.xaml.cs

 public partial class ChatPage : ContentPage
    {
        ChatPageViewModel vm;
        public ChatPage()
        {
            InitializeComponent();
            this.BindingContext = vm= new ChatPageViewModel();                      
        }     
    }

Класс сообщений

 public class Message : ObservableObject
    {
        string text;
        public string Text
        {
            get { return text; }
            set { SetProperty(ref text, value); }
        }

        DateTime messageDateTime;

        public DateTime MessageDateTime
        {
            get { return messageDateTime; }
            set { SetProperty(ref messageDateTime, value); }
        }

        public string MessageTimeDisplay => MessageDateTime.Humanize();

        bool isIncoming;

        public bool IsIncoming
        {
            get { return isIncoming; }
            set { SetProperty(ref isIncoming, value); }
        }

    }

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ : Этот вопрос фактически был продолжением вопроса . Ранее я использовал AwesomeHyperLinkLabel из link . Проблема заключалась в том, что я не могу управлять событием щелчка этой метки. Именно поэтому я перешел с меткой span. Спасибо Лео Чжу - MSFT За изменения рендеринга.

Ответы [ 2 ]

1 голос
/ 17 января 2020

Для Android:

[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace App18.Droid
{
public class AwesomeHyperLinkLabelRenderer : LabelRenderer
{

    public AwesomeHyperLinkLabelRenderer(Context context) : base(context)
    {
    }
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            var view = (AwesomeHyperLinkLabel)Element;
            if (view == null) return;

            TextView textView = new TextView(Forms.Context);
            textView.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
            textView.SetTextColor(view.TextColor.ToAndroid());

            // Setting the auto link mask to capture all types of link-able data
            textView.AutoLinkMask = MatchOptions.All;
            // Make sure to set text after setting the mask
            textView.Text = view.Text;
            AddHyperlinksManually(textView);
            //textView.SetTextSize(ComplexUnitType.Dip, (float)view.FontSize);
            // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(textView);
        }
    public static void AddHyperlinksManually(TextView _tv)
    {
        SpannableStringBuilder currentSpan = new SpannableStringBuilder(_tv.Text);
        Linkify.AddLinks(currentSpan, MatchOptions.WebUrls);

        var objects = currentSpan.GetSpans(0, currentSpan.Length(), Java.Lang.Class.FromType(typeof(URLSpan)));
        var urlSpans = new URLSpan[objects.Length];
        for (var i = 0; i < urlSpans.Length; i++)
        {
            urlSpans[i] = objects[i] as URLSpan;
        }

        foreach (URLSpan _url in urlSpans)
        {
            int iStart = currentSpan.GetSpanStart(_url);
            int iEnd = currentSpan.GetSpanEnd(_url);

            currentSpan.RemoveSpan(_url);
            currentSpan.SetSpan(new CustomURLSpan(_url.URL), iStart, iEnd, SpanTypes.InclusiveInclusive);
            _tv.SetText(currentSpan, TextView.BufferType.Normal);

            _tv.MovementMethod = LinkMovementMethod.Instance;
        }
    }
    public class CustomURLSpan : ClickableSpan
    {
        string mTargetURL;

        public CustomURLSpan(string _url) {
            mTargetURL =_url;
    }

        public override void OnClick(Android.Views.View widget)
        {
            //here you could handle the click event,and you could use MessagingCenter to send mTargetURL to your Page.
            Console.WriteLine("Click");
        }
    }
}  
0 голосов
/ 17 января 2020

Ошибка была с моей моделью. Измененная строка в FormattedString, а также измененная в viewmodel

 public class Message : ObservableObject
    {
        FormattedString text;
        public FormattedString Text
        {
            get { return text; }
            set { SetProperty(ref text, value); }
        }

        DateTime messageDateTime;

        public DateTime MessageDateTime
        {
            get { return messageDateTime; }
            set { SetProperty(ref messageDateTime, value); }
        }

        public string MessageTimeDisplay => MessageDateTime.Humanize();

        bool isIncoming;

        public bool IsIncoming
        {
            get { return isIncoming; }
            set { SetProperty(ref isIncoming, value); }
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...