部分文本可在Xamarin标签中单击

hor*_*ski 7 xamarin xamarin.forms

我正在寻找一种方法,使Xamarin Forms中Label的部分文本可单击,执行不同的功能,理想情况下具有不同的格式.我知道可点击的标签很简单,可以这样做:

Label label = new Label { Text = "Click me" };
label.Click += () => { label.Text = "Clicked"; };
Run Code Online (Sandbox Code Playgroud)

从本质上讲,我希望模仿我在原生Android中完成的应用中的行为.我的应用必须适用于Android和iOS,最适合UWP.在Android中,CharSequence对象可以添加到TextView(类似于Label的控件).在Android中,我可能会创建一个CharSequence对象,如下所示:

    Runnable doSomething; //equivalent to C# Action; assuming initialized somewhere
    String myString = "My Clickable String"; //the clickable string
    Spannable span = Spannable.Factory.getInstance().newSpannable(myString); //this is the clickable text to add to TextView
        span.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View v) {
                doSomething.run(); //perform the action
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                ds.setUnderlineText(true); //make underlined
                ds.setColor(Color.rgb(color.r, color.g, color.b)); //change the color
                ds.setFakeBoldText(true); //make it bold
                ds.setTextSize((float) largeFont); //change the text size
            }
        }, 0, a.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //style and function for the entire string
Run Code Online (Sandbox Code Playgroud)

如您所见,它执行一个函数并具有样式属性.然后我可以将它添加到TextView(Spannable实现Spanned,它实现CharSequence).我可以根据需要添加多个CharSequences以及不可点击的字符串.

我希望能在Xamarin中做到这一点,但我还没有找到解决方案.我已经考虑过自定义渲染器的可能性,但我觉得如果可能的话,跨平台解决方案会更好.我对iOS的熟悉程度要低得多,但似乎可以将NSMutableAttributedString对象添加到UILabel中以达到类似的效果.我也看过FancyLabel对象.我不太确定如何为UWP做这件事,因为我在研究中找不到多少.

任何帮助将非常感谢!

Tom*_*Tom 6

只是为了使用 Xamarin Forms 3.4(及更高版本)提供更新的答案。您可以使用FormattedText的特性LabelXamarin Docs 中有关于如何使用它的深入概述。

从根本上说,它是这样工作的:

<Label 
    LineBreakMode="WordWrap">
    <Label.FormattedText>
        <FormattedString>
            <Span 
                Text="Red Bold, " 
                TextColor="Red" 
                FontAttributes="Bold" />
            <Span 
                Text="default, " 
                Style="{DynamicResource BodyStyle}">                          
                <Span.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding TapCommand}" />
                </Span.GestureRecognizers>
            </Span>
            <Span 
                Text="italic small." 
                FontAttributes="Italic" 
                FontSize="Small" />
        </FormattedString>
    </Label.FormattedText>
</Label>
Run Code Online (Sandbox Code Playgroud)

在上面,点击文本default将执行TapCommand


eth*_*ane 3

这个答案可能是事后的,但可能会在未来帮助其他人。

我所做和测试的是使用网格,并适当分割字符串,假设您想更改单词的行为:
在您的 ViewModel/View 中:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/> //for first few words
        <ColumnDefinition Width="Auto"/> //the target word
        <ColumnDefinition Width="Auto"/> //the rest of the string
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/> //one row for one line of text
    </Grid.RowDefinitions>

    <Label Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Text="First part of string"/>
    <Label Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0" Text="TARGET-WORD">
        <Label.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding <YOUR_COMMAND>}"/>
        </Label.GestureRecognizers>  
    </Label>
    <Label Grid.Column="2" Grid.ColumnSpan="1" Grid.Row="0" Text="rest of the string"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以隔离网格的特定部分并修改行为/美学(数据触发器、样式、手势)。请记住,<Span></Span>标签并不支持<Label></Label>.

显然,在 XAML 中您需要知道单词的位置,或者如果字符串是动态的,您可以动态搜索它并在后面的代码中构造您的网格。

*在 Xamarin.Forms 2.3.4.247 上测试