Change part of a label in Titanium or Alloy / Appcelerator - titanium

I want to change part of a label dynamically.
This is my code:
<View top="0" height="115">
<Label id="lblMiles" left="15" textAlign="right" right="15" top="0" height="55">
{distance} Miles
</Label>
</View>
I want to be able to change the {distance} portion dynamically.
However currently I can only change the whole thing like this:
$.lblMiles.text = "10 Miles";
In HTML we normally use a span tag like so:
<div id="lblMiles"><span id="distance"></span> Miles</div>
How can I do something similar in Alloy?

If it were up to me, i wouldn't worry about updating only half the label, just reset the whole text,
$.lblMiles.text = "10 Miles";
// and then later on to update it to 15
$.lblMiles.text = "15 Miles";
if for some reason you need to update only half, then you could use two labels and put them in a view with layout set to horizontal.
something looking like this :
<View top="0" height="115">
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" layout="horizontal">
<Label id="dynamicLabel" />
<Label id="lblMiles" > Miles</Label>
</View>
</View>
and then in your code, just update the dynamic label setting the actual value:
$.dynamicLabel.text = "15";
Now to position the labels on the screen you should play on the attributes of their container's left, right, top and bottom.

You can do this by two three ways
Have two different labels and set it from controller
You can use attributed strings as well.
More reference is here http://docs.appcelerator.com/platform/latest/#!/guide/Attributed_Strings

Related

How to show up all title and description in List.Accordion and List.Item with react-native-paper

I'm developing a mobile app with react-native-paper, and I'm using List in react-native-paper.
I would like to show up whole message on the List.
In default, List omits the part of the message if the message is too long like the gif below.
https://gyazo.com/d60defc5f46b51408d68e793f9365172
I have already tried to change the parameters(head, middle, tail, and clip) of titleEllipsizeMode.
However, these parameters didn't work as I expected.
This is my code.
<List.Section theme={{ colors: { primary: 'black' }}}>
<List.Accordion
title='Loooooooooooooooooooooooooooong title title title'
expanded={this.state.expanded}
onPress={this._handlePress}
>
<List.Item
title='Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong title title title'
expanded={this.state.expanded}
titleEllipsizeMode='tail'
titleStyle={{ fontSize: 10 }}
/>
</List.Accordion>
</List.Section>
First of all the list title should not be too long as it's against the design guidelines.
Normally if you need to have a subtext then it would move underneath it as in the picture below.
Gmail-guidelines
If you want to have control over the entire styling of the list title and even list item title is to pass a component to the title prop then style the component:
<List.Accordion title={<View><Text>Accordion title</Text></View>}>
<List.Item title="item title"/>
</List.Accordion>
Then you can style the View & Text components

Nested Text Components Props

In React Native, I am trying to output a small blurb that generally takes up 2-3 lines of text. In this text, I want some parts to be bolded and pressable, and so I have come up with the following approach to separate the normal text and the special text:
<Text>
<Text style = {{fontSize:12}}>
{"Tried "}
</Text>
<Text style = {{fontSize:12}}>Beef and Shrimp Fried Noodle </Text>
<Text style = {{fontSize:12}}>{"for $10.25 at "}</Text>
<Text style = {{fontSize:12}}>JoyYee Restaurant</Text>
<Text style = {{fontSize:12}}>{" which is a 15 min walk from you"}</Text>
</Text>
I'm trying to alter the line-height of the 2-3 lines of text, but passing the lineHeight prop to the parent, or simply all of the children, has no effect. Is there a proper way of solving this? Or should I take a completely different approach to my text blurb?
To make the desired out come more clear: The text blurb should all be together, as such:
"Tried Beef and Shrimp Fried Noodle for $10.25 at JoyYee Restaurant which is a 15 min walk from you"
In order to keep the multiple text components in line, I had to wrap everything in a parent text; but now I am unable to control the line height of this small paragraph.
After much trial: The error lies in the fact that lineHeight is not a prop but is a style of the Text component. Therefore, the proper method was to write:
<Text style = {{lineHeight: 30}}>Hello etc. etc.</Text>
Hopefully this can help others avoid this issue as well!

How to reduce space between content in Flex layout, if content is placed in row direction?

My questions are:
How to reduce space between two rows?
How to reduce space between items, if number of items are less than privous row items?
My xaml code:
<FlexLayout Wrap="Wrap" AlignItems="Start" Direction="Row" JustifyContent="SpaceAround" HorizontalOptions="StartAndExpand">
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
</FlexLayout>
Output:
What I want is:
I ran into this issue and eventually I found out the reason.
The reason why it will look like this is that the flex layout will expand itself to the maximum in default like what a Grid does, regardless of the children.
The spacing is based on the area left after allocating all the children. You got a lot of area left vertically so the space between rows got larger. If you use Xamarin.UWP or Xamarin.WPF and resize the app window you can see the space between rows is changing.
So, HorizontalOptions="StartAndExpand" is unnecessary.
Add VerticalOptions="Start" to the flex layout (Or sometimes if you wrap the flex layout inside another auto-expand control like ScrollView, then add this to the parent ScrollView) and the problem is solved, at least in my case.
When it comes to the third line, I just added JustifyContent="Start" AlignItems="Start".
Edit:
Apply Margin property to each item, to get space between items.
Set
AlignContent="Start"
in FlexLayout.
By setting this property, the child elements are aligned without row space.
http://tecsack.com/xamarin-forms-flex-layout/
I've never used FlexLayout in Xamarin, but from my HTML/CSS days I would suggest that your issue is with JustifyContent="SpaceAround". Try to change SpaceAround to FlexStart
By default FlexLayout doesn't have RowSpacing or other parameter. What you need to do is define column nubers eg. 4, then dived your FlexLayout width by your column number and programmatically add elements to your FlexLayout. You can use OnSizeChanged event to do that and start adding child items to FlexLayout. Then you should set:
Direction: Row
Wrap: Wrap
FlowDirection: LeftToRight
JustifyContent: Start
AlignItems: Start
Some Example of code could be:
private void FlexGallery_SizeChanged(object sender, EventArgs e)
{
//imageDimension = Math.Round(FlexGallery.Width / 4) ..round it with desired method
foreach (var it in documents.OrderBy(a => a.DateCreated))
{
if (Path.GetExtension(it.Url) == ".png" || Path.GetExtension(it.Url) == ".jpg")
{
Image img = new Image
{
HeightRequest = imageDimension,
WidthRequest = imageDimension,
Margin = new Thickness(5, 5, 5, 5),
Source = ImageSource.FromUri(new Uri(it.Url))
};
FlexGallery.Children.Add(img);
}
else
{
}
}
}
Where imageDimension is your FlexLayout divided by desired numbers of columns, and rounded with Math.Round.
Approach by adding it programmatically is different from approach where number of items is alerady known and defined in xaml.
This approach is only for items with scale factor 1:1 .
You should get something like this (this is tabbed view so ignore white line at center):

Fixed View at bottom (variable height) and fill remaining height with other View

I want to build a chat. In the view for the messages are the messages and the input field for the message. The Inputbox should be at the bottom and should use the height it needs. The height of the Inputbox can change if the user enters multi-line text. The msgs-View should fill the rest of the height (above). I don't want to position the Input absolute because the message's FlatList should be always in the "visible" area.
<View style={styles.wrapper}>
<View style={styles.msgs}>Messages (FlatList)</View>
<View style={styles.input}>Inputbox</View>
</View>
Don't give flex style to your input.
Give your wrapper and list a flex: 1 style. Wrapper will take up all the space in its parent (which I assume is the screen). And list will take all the space in wrapper. And input will sit in the bottom.

Toggle visibility for React Native elements?

In React Native, is there a way to toggle visibility of an element?
For example:
<Text visibility={this.state.isVisible}>Visibility depends on state</Text>
this might be crude but it works.
under render
var visibletext = null;
if (this.state.isVisible) {
visibletext = (<Text>Visibility depends on state</Text>);
}
then, under return part
<View style={styles.container}>
{visibletext}
</View>
There are various ways to do this. See the Conditional Rendering guide at the React.js website, which explains different options.
One simple way is to use the && operator inline:
{this.state.isVisible &&
<Text>Something</Text>
}
Note that with the conditional rendering approach, if you have (for example) some views centered vertically, this views will suddenly move up or down when the text appears (to give room for the new view). Another approach that avoids this jump is to either change the text color or set the text to empty string:
// Change the text color
<Text style={this.state.isVisible ? {color: 'black'} : {color: 'white'}}>Something</Text>
// Set text to empty string
<Text>{this.state.isVisible ? "Something" : ""}</Text>
Changing the color of the text is the best way to make sure that the other views don't suddenly move when showing the text, given that the text is already occupying the layout space it needs.