Я пытаюсь реализовать аналогичные функции масштабирования, такие как экран канала мобильного приложения Instagram, в кроссплатформенном приложении xamarin.
На самом деле я хочу добавить жест сжатия на ImageView
внутри ячейки ListView
, если пользователь ущипнет изображение, оно должно увеличиться над ListView
. Как только пользователь отпускает щипок, он должен автоматически измениться до исходного размера и соответствовать ячейке.
Помогите мне и предложите решение.
Следующий пример кода работает, но его масштабирование внутри ячейки не похоже на эффект перекрытия / наложения масштабирования в Instagram.
Код XAML
<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
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;
}
}
}
Следующий пример кода работает, но его масштабирование внутри ячейки не похоже на эффект перекрытия / наложения масштабирования в Instagram. пожалуйста, проверьте образец кода, который я добавил. не так гладко, как приложение Instagram
вот видео на странице канала Instagram, мне нужны точно такие же функции.dropbox.com/s/8ctwqjo86qpsqku/…
Привет, у вас есть какое-нибудь решение для этого?
Пока вы не предоставите код того, что вы пробовали, никто не сможет вам помочь. Людям необходимо знать контекст, как выглядит ваша ячейка списка и т. д.