Xamarin Forms Rotated ListView Spins on Redraw - xamarin

To make a chat page, I followed an example I found that sets the ListView rotation to 180, so the list builds from the bottom and then set things in the DataTemplate to rotate 180, so the items will be upright. It's a great solution, but when the keyboard opens, the ListView gets shorter which causes a redraw. During the redraw, the ListView initially appears with rotation 0 and I see an animation as if RotateTo(360) is being called. After initially displaying, I get to watch the list view rotate around in full circle. Click off the message editor, and the ListView gets taller, and it does it again.
Has anyone seen this?
Here's what the Xaml looks like. I can't make a gif of what it looks like, but imagine watching:
MessageList.Rotation = 0;
MessageList.RotateTo(360, 500, Easing.Linear);
each time the keyboard shows and hides, and you'll get the idea...
<ListView
X:Name="MessageList"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
Rotation="180"
ItemsSource="{Binding ChatMessages}"
SelectionMode="None"
HasUnevenRows="True"
SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame
BackgroundColor="LightGray"
FlowDirection="LeftToRight"
Rotation="180"
Padding="10"
HasShadow="false"
Margin="80,2,0,5">
<Label Text="{Binding ChatText}"/>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

I followed the same tutorial you mentioned and you are probably using a ContentPage renderer to handle your keyboard layout updates on iOS. If you check the sample project https://github.com/rdelrosario/ChatUIXForms you'll notice he resizes the keyboard ContentView with a ContentView renderer for the Editor box at the bottom using the Margin property, rather than the entire ContentPage. Which doesn't trigger the above issue.

What I wound up doing was to make a custom ListView renderer that was keyboard aware in iOS and sets a translation X to move the top of the listview up when the keyboard appears and back down when it goes away. As a result, the listview is not getting resized, and thus does not redraw.
It may be messy, but it makes it work...

Related

Custom RecyclerView for Forms

I'm having an issue when displaying a large number of visual elements in a scroll viewer, and I've tried every possible way to achieve the same approach, either with 3rd party horizontal list views (Can't find one with variable column/element width) or with rotated native list view (gives weird results).
The only approach that gives the result is via stacklayout docked in scrollviewer where I populate that stacklayout from code. Now the problem is all elements are rendered even if they were not displayed, so it makes the application either very slow.
I thought about having a recyclerview (which exists in native android) but I can't find an approach for it forms as it only exists in android. Now can anyone help me with that? Maybe a custom view where it uses recycler view on android and any similar approach or maybe a regular scrollviewer on iOS ?
Thanks in advance.
Update #1
I could do the rotated listview option using this code -Inspired by this answer-
<RelativeLayout>
<ListView ItemsSource="{Binding Entries}" Rotation="-90" HasUnevenRows="True"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=-37}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=-0.5, Constant=37}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<BoxView Rotation="90" BackgroundColor="Beige" WidthRequest="200"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativeLayout>
But I can never make this box view fill the while cell, there is always empty space -The box view is a place holder instead of other custom control-.
Is there a method to make the box view always fill the whole cell height and fill and expand it to it's WidthRequest property -Which will be dynamic according to a binding later- ?
I have found a workaround for such an issue by using a listview with custom template, where I inside of it I used several scrollviews and linked their movement together. Refer to my answer here: How to make multiple list views scroll together?

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

long list selector not scrolling properly

My LongListSelector is not scrolling properly. When I scroll the list, it automatically reaching back to the top with its rubber band effect.
xaml is
<Grid x:Name="ContentPanel" Height="2000">
<toolkit:LongListSelector x:Name="ItemList" DataContext="Item" IsFlatList="True" StretchingBottom="LoadMoreData">
<toolkit:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Tag="{Binding ItemID}" Loaded="Grid_Loaded" MaxWidth="361" MaxHeight="100">
// some xaml code
</DataTemplate>
</toolkit:LongListSelector.ItemTemplate>
</toolkit:LongListSelector>
</Grid>
can anyone help me ?
thanku
It's not scrolling correctly because you set the Height of the parent Grid to 2000. This causes the LongListSelector to take as much space as it may need as long as it's less than 2000 and only then starts scrolling. Considering you only have 800 (or a bit more) of height, you don't see the scrolling properly.

How to create and run animation for RadSlideView item in WP7?

I have an image in Telerik slideView control and a Button on the AppBar. When AppBar Button is tapped I change image source of the active Image. Everything works well but I need an Animation for changing image source. I'm using MVVMlight. Coul anybody help me with animation image appearance by tap on appBar button. Any information would be useful.
<telerikPrimitives:RadSlideView
x:Name="slideView"
ItemsSource="{Binding Covers}"
SelectedItem="{Binding CurrentCover ,Mode=TwoWay}"
ItemRealizationMode="ViewportItem" >
<telerikPrimitives:RadSlideView.ItemTemplate>
<DataTemplate>
<Image x:Name="DisplayImage" Source="{Binding FullCover}">/Image>
</DataTemplate>
</telerikPrimitives:RadSlideView.ItemTemplate>

How to make a scrollviewer gain focus when selected

I have a project where I have multiple scrollviews in one:
I can scroll up and down through a single item, and also through multiple items horizontally.
Normally, the webview is not hittestvisible.
Moving horizontally works fine, but when I scroll down, I give focus and hittestvisibility to the single item, but it won't scroll down. Only when I scroll down the second time, it will scroll, I think because when the ManipulationStartedevent was fired, it was caught by the scrollview, which had focus at the time, and only later the webview takes the focus, therefore, it has no started position. Is there a workaround for this problem?
<ScrollViewer x:Name="Scroller"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled"
ManipulationMode="Control"
Grid.Row="1" Grid.RowSpan="2" >
<StackPanel Name="WebScrollView" Orientation="Horizontal" >
<UserControl Name="LeftContentControl" MinWidth="480" />
<UserControl Name="MiddleContentControl" MinWidth="480" />
<UserControl Name="RightContentControl" MinWidth="480" />
</StackPanel>
</ScrollViewer>
So, Left, Middle and Right are the three controls which will hold the webviews as their content. When scrolled to the left( for example ), the left content is placed over the middle content, and the middle content is set into view again, so it seems like an endless list of webviews, but really are three.
I use a mediator to achieve the animation of the webviews.
Thanks in advance.
GeekPeek

Resources