5

I am trying to implement similar zoom functionality like Instagram mobile app feed screen in xamarin cross-platform app. Actually I want to add pinch gesture on ImageView inside ListView cell, if user pinch on image, it should zoom-in over ListView. Once user release pinch it should automatically resize to original size and fit to cell.
Help me and provide solution.

Following sample code working but its zooming inside the cell, its not like Instagram zooming overlap/overlay effect.

XAML code

<ListView x:Name="listView" ItemSelected="PlayerList_OnItemSelected"  HasUnevenRows="false" RowHeight="300" BackgroundColor="#F6F3F6" 
RelativeLayout.XConstraint=
"{ConstraintExpression Type=RelativeToParent,
Property=Width, Factor=0}" 

RelativeLayout.YConstraint=
"{ConstraintExpression Type=RelativeToParent,
Property=Height, Factor=.09}"

RelativeLayout.HeightConstraint=
"{ConstraintExpression Type=RelativeToParent,
Property=Height, Factor=.91}"

RelativeLayout.WidthConstraint=
"{ConstraintExpression Type=RelativeToParent,
Property=Width, Factor=1}">
<ListView.ItemTemplate>
    <DataTemplate>
<ViewCell >
<Frame Margin="5" Padding="5"  OutlineColor="White" HasShadow="true">

<RelativeLayout >
<Label Font="Bold,20" Text="{Binding name}" TextColor="Black"
        RelativeLayout.YConstraint="{ConstraintExpression 
        Type=RelativeToParent,
        Property=Height,
        Factor=.0}"
        RelativeLayout.XConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width, 
        Factor=.02}"
        RelativeLayout.WidthConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width,
        Factor=.9}"/>

    <local:PinchToZoomContainer RelativeLayout.WidthConstraint="{ConstraintExpression
        Type=RelativeToParent,
        Property=Width, 
        Factor=1}"
        RelativeLayout.XConstraint="{ConstraintExpression
        Type=RelativeToParent,
        Property=Width, 
        Factor=0}" 

        RelativeLayout.YConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Factor=.15, 
        Property=Height}">

        <local:PinchToZoomContainer.Content>
                <Image x:Name="imgBg" HeightRequest="180" Aspect="AspectFill" BackgroundColor="#F0F3F4"  Margin="1,1,1,-1" Source="{Binding thumbnail, Converter={StaticResource GetFeedImage}}" />
            </local:PinchToZoomContainer.Content>
        </local:PinchToZoomContainer>


    <Label FontSize="10" TextColor="#96AAC0" HorizontalTextAlignment="Center" HeightRequest="40" Text="{Binding posted_at}" 
        RelativeLayout.YConstraint="{ConstraintExpression 
        Type=RelativeToParent,
        Property=Height,
        Factor=.02}"
        RelativeLayout.XConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width, 
        Factor=.81}"
        RelativeLayout.WidthConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width,
        Factor=.2}"/>

    <Label FontSize="12" TextColor="#5B636E" HorizontalTextAlignment="Start"  Text="{Binding description}" 
        RelativeLayout.YConstraint="{ConstraintExpression 
        Type=RelativeToParent,
        Property=Height,
        Factor=.87}"
        RelativeLayout.XConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width, 
        Factor=.01}"
        RelativeLayout.WidthConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Width,
        Factor=.98}"

        RelativeLayout.HeightConstraint="{ConstraintExpression 
        Type=RelativeToParent, 
        Property=Height,
        Factor=0,
        Constant=30}"/>
</RelativeLayout>
    </Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>

</ListView>

Zoom container class

public class PinchToZoomContainer : ContentView
{
double currentScale = 1;
double startScale = 1;
double xOffset = 0;
double yOffset = 0;

public PinchToZoomContainer ()
{
    var pinchGesture = new PinchGestureRecognizer ();
    pinchGesture.PinchUpdated += OnPinchUpdated;
    GestureRecognizers.Add (pinchGesture);

}

void OnPinchUpdated (object sender, PinchGestureUpdatedEventArgs e)
{
    if (e.Status == GestureStatus.Started) {
        // Store the current scale factor applied to the wrapped user interface element,
        // and zero the components for the center point of the translate transform.
        startScale = Content.Scale;
        Content.AnchorX = 0;
        Content.AnchorY = 0;
    }
    if (e.Status == GestureStatus.Running) {
        // Calculate the scale factor to be applied.
        currentScale += (e.Scale - 1) * startScale;
        currentScale = Math.Max (1, currentScale);

        // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
        // so get the X pixel coordinate.
        double renderedX = Content.X + xOffset;
        double deltaX = renderedX / Width;
        double deltaWidth = Width / (Content.Width * startScale);
        double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;

        // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
        // so get the Y pixel coordinate.
        double renderedY = Content.Y + yOffset;
        double deltaY = renderedY / Height;
        double deltaHeight = Height / (Content.Height * startScale);
        double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;

        // Calculate the transformed element pixel coordinates.
        double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
        double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);

        // Apply translation based on the change in origin.
        Content.TranslationX = targetX.Clamp (-Content.Width * (currentScale - 1), 0);
        Content.TranslationY = targetY.Clamp (-Content.Height * (currentScale - 1), 0);

        // Apply scale factor
        Content.Scale = currentScale;
    }
    if (e.Status == GestureStatus.Completed) {
        // Store the translation delta's of the wrapped user interface element.
        xOffset = Content.TranslationX;
        yOffset = Content.TranslationY;

    }
}
}
R15
  • 13,982
  • 14
  • 97
  • 173
Jyoti prakash
  • 1,047
  • 9
  • 8
  • Until you provide some code what you have tried, no one can help. People need to know the context, how your list cell look like..etc – R15 Aug 10 '18 at 08:52
  • 1
    Following sample code working but its zooming inside the cell, its not like Instagram zooming overlap/overlay effect. please check sample code i have added.alo its not smooth like Instagram app – Jyoti prakash Aug 10 '18 at 09:33
  • 1
    here is the instagram feed page video, I want exactly same features.https://www.dropbox.com/s/8ctwqjo86qpsqku/Video%20Aug%2010%2C%204%2014%2036%20PM.mp4?dl=0 – Jyoti prakash Aug 10 '18 at 11:03
  • HI did you got any solution for this? – Anand Oct 25 '20 at 12:28

0 Answers0