簡體   English   中英

如何在 Xamarin.Forms 的列表視圖中獲取所選項目的坐標?

[英]How to get coordinates of the selected item in a list view in Xamarin.Forms?

我想獲取列表視圖中所選項目相對於屏幕的坐標(矩形邊界:x、y、寬度和高度)(假設列表視圖填滿整個屏幕),以便我可以在該位置創建一個對象並為其設置動畫以在我的 Xamarin.Forms 應用程序中顯示所選項目的一些詳細信息。

xaml 中的列表視圖:

<ListView ItemTapped="ItemTapped"
    AbsoluteLayout.LayoutFlags="All"
    AbsoluteLayout.LayoutBounds="0.5, 0.5, 1.0, 1.0">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell Height="50">              
                <AbsoluteLayout>
                    <Label Text="{Binding Info}"
                        AbsoluteLayout.LayoutFlags="All"
                        AbsoluteLayout.LayoutBounds="0.1, 0.5, 0.7, 0.5"/>
                </AbsoluteLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ItemTapped 事件的 c# 代碼:

void ItemTapped(object sender, EventArgs args)
{
    var listView = (ListView)sender; // the listview
    var selectedItem = args.Item; // the selected item

    // need to get selected item coordinates for the animation
    var selectedItemBounds = ...

    ...
}

最終,我想在 Xamarin.Forms 中使用列表視圖創建類似這樣的內容(列表視圖中的對象數量各不相同):

示例列表視圖動畫

我創建了一個依賴項,您可以使用它來獲取 iOS 和 Android 中 VisualElement 的絕對位置。 我將它用於類似的目的。 我們使用它來確定在列表視圖中點擊時要顯示的彈出窗口的位置。 完美運行:

依賴:

public interface ILocationFetcher
{
    System.Drawing.PointF GetCoordinates(global::Xamarin.Forms.VisualElement view);
}

iOS 實現:

 class LocationFetcher : ILocationFetcher
 {
    public System.Drawing.PointF GetCoordinates(global::Xamarin.Forms.VisualElement element)
    {
        var renderer = Platform.GetRenderer(element);
        var nativeView = renderer.NativeView;
        var rect = nativeView.Superview.ConvertPointToView(nativeView.Frame.Location, null);
        return new System.Drawing.PointF((int)Math.Round(rect.X), (int)Math.Round(rect.Y));
    }
}

安卓實現:

class LocationFetcher : ILocationFetcher
{
    public System.Drawing.PointF GetCoordinates(global::Xamarin.Forms.VisualElement element)
    {
        var renderer = Platform.GetRenderer(element);
        var nativeView = renderer.View;
        var location = new int[2];
        var density = nativeView.Context.Resources.DisplayMetrics.Density;

        nativeView.GetLocationOnScreen(location);
        return new System.Drawing.PointF(location[0] / density, location[1] / density);
    }
}

感謝@Emil,我們還有一個 UWP 實現:

public System.Drawing.PointF GetCoordinates(global::Xamarin.Forms.VisualElement element)
{
    var renderer = Xamarin.Forms.Platform.UWP.Platform.GetRenderer(element);
    var nativeView = renderer.GetNativeElement();
    var element_Visual_Relative = nativeView.TransformToVisual(Window.Current.Content);
    Point point = element_Visual_Relative.TransformPoint(new Point(0, 0));
    return new System.Drawing.PointF((int)Math.Round(point.X), (int)Math.Round(point.Y));
}

用法示例:

var locationFetcher = DependencyService.Get<ILocationFetcher>();
var location = locationFetcher.GetCoordinates(myVisualElement);

確保使用依賴屬性在 android 和 ios 中正確注冊依賴項(請參閱https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/ )。 否則 DependencyService.Get 將返回 null。

一個快速的想法:

有一個作為單例運行的視圖助手服務:

interface IViewHelper
{
   Rect GetScreenCoordinates(View view);
}

在 ListView 項模板和點擊事件處理程序調用中的 AbsoluteLayout 添加一個點擊手勢:

IViewHelper viewHelper = CrossViewHelper.Instance; 
Rect rcItem = viewHelper.GetScreenCoordinates((View)sender);

服務GetScreenCoordinates本機實現做了兩件事:

// Get the native view from the Xamarin Forms view 
var nativeView = Platform.GetRenderer(view);

// Call native functions to get screen coordinates
Android: nativeView.GetLocationOnScreen(coords)
iOS: Use nativeView.ConvertPoint(coords, null)

請參閱https://forums.xamarin.com/discussion/86941/get-xy-co-ordinates-in-tap-gesture-inside-listview

https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/PlatformRenderer.cs#L53

另請參閱: https : //michaelridland.com/xamarin/creating-native-view-xamarin-forms-viewpage/

我沒有完整的代碼,但我希望這可以幫助你。

我認為最后,在您實現動畫並顯示視圖之后,您可以將實現重構為一個很好的行為,您可以附加到任何視圖,它是否在列表視圖中都沒有關系,它會起作用。

PaulVrugt 的回答完全適用於 IOS 和 Android。 只是為任何人擴展他的實現也需要 UWP。

  public System.Drawing.PointF GetCoordinates(global::Xamarin.Forms.VisualElement element)
        {
            var renderer = Xamarin.Forms.Platform.UWP.Platform.GetRenderer(element);
            var nativeView = renderer.GetNativeElement();
            var element_Visual_Relative = nativeView.TransformToVisual(Window.Current.Content);
            Point point = element_Visual_Relative.TransformPoint(new Point(0, 0));
            return new System.Drawing.PointF((int)Math.Round(point.X), (int)Math.Round(point.Y));
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM