How to implement a visual busy/working indicator in Exrin? - xamarin

Context
I am discovering step by step Exrin infrastructure. I explored that there are many ready to use infra element to implement command execution in background. Among those I see IsBusyDelay, VisualState.IsBusy, Timeout message, etc. I also know that Exrin does not depend on Xamarin.Forms, so I suppose, no real visual implementation should be provided by Exrin, that very last step remains on me. (which is cool, let me decide the UI experience)
In my ViewModel I set IsBusyDelay = 1000;. The background task is started by Execution.ViewModelExecute(... my task here ..., currently 5000msec delay )
Question
I suppose now I have to implement somewhere a handler(s) or override(s) which will be called automatically, and implement some visual UX to show and hide the a busy/inprogress UX feedback. I just do not know where and how...

This is something you would implement yourself in the view. For example, if you wanted something that covered the whole screen, with a loading indicator, you would add this to your UI.
<Grid HorizontalOptions="FillAndExpand"
IsVisible="{Binding VisualState.IsBusy}"
BackgroundColor="#E6272C30"
VerticalOptions="FillAndExpand">
<Grid HorizontalOptions="Center" VerticalOptions="CenterAndExpand"
Height="200">
<ActivityIndicator Grid.Row="0"
IsRunning="{Binding VisualState.IsBusy}"
IsVisible="{Binding VisualState.IsBusy}">
<ActivityIndicator.Scale>
<OnPlatform x:TypeArguments="x:Double" Android="1" iOS="1.3" />
</ActivityIndicator.Scale>
</ActivityIndicator>
</Grid>
</Grid>
You would add this at the bottom of the page, inside your existing Grid.
Then when IsBusy is trigger, it shows this as an overlay, with the activity indicator.
Of course that is only one way to do it. You could just have an activityindicator next to, or inside a button that was just clicked, or anything similar. It all depends on your UI design.

Related

Position of buttons and designs in Xamarin

Scenario 1:
I'm trying to create a mobile application using Xamarin. I want the position of my buttons and design to be in its place. I tried to run it on my smartphone, and the buttons and designs' position looks good, but when I tried to run it on another smartphone, they all got messed up. It changes its position. I used stacklayout here.
Scenario 2:
Then some people say they used grid. So, I tried using a grid in creating my login page. The problem is when I click on the entry box to type a username/password, of course the keyboard will pop up, but the whole UI will go higher/above its original position. When I tried to not type username/password or click the back button from the keyboard, the UI will go back to its original position.
How to fix any of these?
I tried to run it on my smartphone, and the buttons and designs'
position looks good, but when I tried to run it on another smartphone,
they all got messed up. It changes its position.
Xamarin.Forms XAML Support :
Xamarin.Forms use the platform-specific mechanisms to calculate the absolute pixel dimensions. Xamarin.Forms uses xaml as it's base markup language for renderng displays, and converts this into the native counterparts at runtime. Usually, you don't have to care about the resolution, it will adjust the views based on your layout and constraints.
Some useful link about Xamarin.Forms multi-device support :
Bringing Xamarin.Forms Apps to Tablets
Provides a few nice helper methods to extend the app for a better tablet experience
Xamarin.Forms Device Class
The Device class contains a number of properties and methods to help developers customize layout and functionality on a per-platform basis.
Layout for Tablet and Desktop apps
Discuss about the supported device types, and how to optimize layouts for tablets versus phones.
For Scenario 2
The problem is when I click on the entry box to type a
username/password, of course the keyboard will pop up, but the whole
UI will go higher/above its original position. When I tried to not
type username/password or click the back button from the keyboard, the
UI will go back to its original position.
I don't know what's the detail of your app, but you can refer to the following code,which does not present the problem you mentioned.
<Grid Margin="20" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10" Grid.Row="0" Grid.ColumnSpan="2" />
<Entry Grid.Row="0" Grid.Column="0" MaxLength="30" Placeholder="User Name:" ClearButtonVisibility="WhileEditing" />
<Image Source="head.png" Scale="0.6" Grid.Row="0" Grid.Column="1"/>
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10" Grid.Row="1" Grid.ColumnSpan="2"/>
<Entry Grid.Row="1" Grid.Column="0" MaxLength="30" Placeholder="Password:" ClearButtonVisibility="WhileEditing" IsPassword="True"/>
<Image Source="Lock.png" Scale="0.6" Grid.Row="1" Grid.Column="1"/>
</Grid>
<Button Text="Login"/>
The result is:
Update
Since your controls(e.g. the two Entry ) are at the bottom of the page,when you want to enter something, the keyboard will pop up. The keyboard will surely take up some space on the screen. The system makes a decision as to how it should adjust the visible portion of your UI, but it might not get it right. To ensure the best behavior for your app, you should specify how you'd like the system to display your UI in the remaining space.
From the Android Developer Site link, we know
"adjustResize"
The activity's main window is always resized to make room for the soft
keyboard on screen.
"adjustPan"
The activity's main window is not resized to make room for the soft
keyboard. Rather, the contents of the window are automatically panned
so that the current focus is never obscured by the keyboard and users
can always see what they are typing. This is generally less desirable
than resizing, because the user may need to close the soft keyboard to
get at and interact with obscured parts of the window.
In xamarin, you can change the value of WindowSoftInputModeAdjust in class Application
<Application ...
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:Application.WindowSoftInputModeAdjust="Resize">
...
</Application>
For more details, you can check:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/platform/android/soft-keyboard-input-mode .
https://developer.android.com/training/keyboard-input/visibility

HeightRequest on ListView calculates weird?

I've heard a couple things about ListView.
it takes up the full height of its container
on iOS it just goes ahead and adds empty rows until it takes up the full height
you have to use HasUnevenRows=True to be able to set its height even if all your rows are the same height.
It sure would be great if there were a way to get ListView to not display those extra empty rows though, right? Well, that's what I am trying to do.
<ListView
BackgroundColor="Green"
ItemsSource="{Binding Things}"
HasUnevenRows="True"
HeightRequest="5"> <!-- In the real code I am setting this in a ValueConverter. It's hard coded here for simplicity. -->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="This is text." />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Except I don't even know what it could possibly be doing. Here I use HeightRequest=5 and HeightRequest=50 there is a difference. But I can't tell what it is.
What's going on here?
Now this is a very interesting question. We have had similar issues with ListViews as unfortunately that unlimited scrolling is actually a standard behaviour on iOS, so you have to think of way around it. The way we have done it is basically count the amount of items within the list, this is pretty straight forward, because you only have to call for ListOfItems.Count. Next thing you want to do, you want to get the Height of your Single DataTemplate item. When you do that then just multiple count of your items by Height of single item and set that Value to HeightRequest. It is not ideal, but it does a job.
I understand why this works. What I don't understand is why the 50 other ways I tried did not work. So from that point of view I have no idea why this works.
Wrap it in a StackLayout:
<StackLayout>
<ListView
BackgroundColor="Green"
ItemsSource="{Binding Things}"
HasUnevenRows="True"
HeightRequest="5"> <!-- In the real code I am setting this in a ValueConverter. It's hard coded here for simplicity. -->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="This is text." />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
It might seem relevant at first but I'm not sure. My ListView was in a grid so it had
<ListView
Grid.Row="1"
Grid.Column="1"
... />
Which got moved into the StackLayout. Again, I know that seems glaringly relevant but I have my doubts. Unfortunately I don't have the time to rip everything out just to test that idea out.

How to animate the movement of a button between 2 positions in xaml, UWP

I have two buttons. One is an edit button that when clicked allows the editing of other objects on the page. My hope is to have the second button appear only once this "edit state" has been initiated. That part isn't very difficult. However, I don't want to just alter the 1st button's alignment from right to left to make space for the 2nd button (a cancel button) to the 1st button's right - I want to animate this movement, as if to make it appear that the moving of the 1st button to the left, is uncovering the 2nd button.
I've been searching for hours trying to find out how to do this, and there's a multitude of options for WPF, but not many solutions for UWP applications.
So far, I've found this:
<Button x:Name="EoIdButton" Grid.Row="0" Grid.Column="2" view:EventHandlers.Attach="Click" BorderBrush="DarkGray" FontFamily="Segoe MDL2 Assets" Content="{Binding EoIdButtonContent, Mode=TwoWay, Converter={StaticResource SegoeConverter}}" Style="{StaticResource CircleButtonStyle}" Visibility="{Binding EoVis, Mode=TwoWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding SomeProperty, Mode=TwoWay}">
<core:ChangePropertyAction></core:ChangePropertyAction>
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Button>
So, while I can change a property using this, I don't see how to create an animation. My guess, based on my searching would be to use a Storyboard, but again, most of the solutions I've found pertain to WPF and/or don't work because the scenario is too different. If someone has a solution for this, it'd be great.
For additionaly clarity
I have button 1:
(EditButton)
When (EditButton) is clicked, I want edit button to rendertransform/animate left and the result to look like so:
(EditButton)(CancelButton)
When either edit button or cancel button are clicked, I want it to return to the original state

Side scrolling menu with gesture removable items

I am trying to create a menu (currently a ListBox containing Images) for an app (WP8 specifically, but general principal will be the same for other environments) with the behavior determined by the initial part of each gesture:
dragging/swiping the menu left or right will cause the menu to scroll left or right
dragging an item up from the menu (which is at bottom of screen) will allow it to be detached (or recreated) and placed in another container.
Roughly speaking, I understand how to drag-and-drop the element, and to make a side-scrolling menu, but I am having difficulties in putting the two together and determining whether to be in "menu scroll" mode, or "drag and drop" mode, and how to switch between the two programmatically.
<ListBox Height="100"
ItemsSource="{Binding}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
Grid.Row="1"
Name="MainMenuPicker">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal">
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=Source}" Tap="Image_Tap"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Currently, horizontal scrolling is taken care of by ScrollViewer.HorizontalScrollBarVisibility="Auto"
I attempted to have a ManipluationStarted, ManipulationDelta etc to determine direction of gesture, but didn't get very far. I currently have a Tap event handler on the Image that moves moving to another parent container.
Questions:
1. How can I determine if a gesture is a side-to-side movement on the menu (ListBox) as a whole, or a drag (upwards) of an Image within the ListBox?
How can I programmatically set each case so that the functionality behaves as described?
Thanks in advance!
In this case you need to use Flick events,and use HorizaltalVelocity and vertcalvelocity to detect and distinguish between left-right and top-down swipes.
check this sample for better understanding

WP7 - ListPicker in StackPanel in ScrollViewer

Just started with developing for WP7 and came across the following. I have a pivot application with a few pivotitems. On the first pivotitem (see code below) I want to be able to adjust a lot of settings. For this question all items to be set are called 'TextBox' and the choice in the ListPicker is either A,B or C.
Now if I do NOT use the ScrollViewer and I tap any of the listpickers I get to see all three options BUT I can not scroll through all listpickers.
If I DO use the ScrollViewer, I CAN see all listpickers but only the top one (that's visible) will expand and give me the options A,B and C, they others stay collapsed.
How can I get every listpicker to expand and show me the avaiable options AND be able to scroll to every listpicker on the page?
PS In code below copy the stackpanel between start and end about 15 times.
Thanks in advance for any help!
<controls:PivotItem Header="blabla">
<ScrollViewer>
<StackPanel Margin="0,0,36,0" VerticalAlignment="Top" d:LayoutOverrides="Width">
// start
<StackPanel Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Text="TextBox" Width="80" TextAlignment="Right" Margin="10,22,20,0" HorizontalAlignment="Right" VerticalAlignment="Top" />
<toolkit:ListPicker Margin="0" Width="275">
<toolkit:ListPickerItem Content="A"/>
<toolkit:ListPickerItem Content="B"/>
<toolkit:ListPickerItem Content="C"/>
</toolkit:ListPicker>
</StackPanel>
// end - copy/paste code code between start and end about 15 times right here
</StackPanel>
</ScrollViewer>
</controls:PivotItem>
This is, apparently, a common issue with Listpicker and ScrollViewer. You can find a workaround here
Should anybody stumble upon this, this has been fixed since the november 2011 release of the wP7 silverlight toolkit.

Resources