ListView 용법 에서 스크롤 과 관련 된 수요 실현
예 를 들 어 개발 중인 애플 리 케 이 션 에 이러한 수요 가 있다 면 사용자 가 목록 페이지(ListView 컨트롤 포함)에서 이전 페이지 로 돌아 갈 때 사용자 가 ListView 의 내용 을 어느 위치 와 어느 항목 으로 탐색 하고 있 는 지 알려 주 고 최근 탐색 항목 을 다시 열 수 있 도록 해 야 합 니 다.마지막 으로 탐색 한 위치 에서 계속 탐색 합 니 다.다음 그림:
본 고 는 상술 한 수 요 를 실현 하 는 방법 을 소개 하 였 다.구체 적 으로 말 하면 이 수 요 는 두 가지 작은 수요 로 나 눌 수 있다.즉,
단추:Items Page 로 탐색 할 수 있 습 니 다.
최근 탐색 정보 영역:마지막 으로 탐색 한 항목 을 볼 수 있 고 목록 페이지 에서 마지막 으로 탐색 한 항목 으로 탐색 할 수 있 는 단 추 를 제공 합 니 다.
목록 페이지 는 ListView 컨트롤 을 포함 하여 여러 항목 을 보 여 줍 니 다.
1.ListView 의 스크롤 위 치 를 가 져 오고 설정 합 니 다.
ListView 의 스크롤 위 치 를 가 져 오고 설정 하 는 것 에 대해 마이크로 소프트 는 관련 예 을 제 공 했 습 니 다.저 는 이 데모 에서 직접 사 용 했 습 니 다.이 기능 은 주로 ListViewPersistenceHelper 을 통 해 이 루어 진 것 으로 다음 과 같은 두 가지 방법 을 제공한다.
// ListView
public static string GetRelativeScrollPosition(ListViewBase listViewBase, ListViewItemToKeyHandler itemToKeyHandler)
// ListView
public static IAsyncAction SetRelativeScrollPositionAsync(ListViewBase listViewBase, String relativeScrollPosition, ListViewKeyToItemHandler keyToItemHandler)
이 두 가지 방법 중 하 나 는 의뢰 유형 으로 각각 ListViewItemToKeyHandler 과 ListViewKeyToItemHandler 이다.이들 의 역할 은 목록 항목 과 Key 의 대응 관 계 를 어떻게 처리 하 는 지 알려 주 고 이 유형 이 스크롤 위 치 를 정확하게 얻 거나 설정 할 수 있 도록 하 는 것 이다.여기 서 Key 는 ListView Item 이 대표 하 는 항목 의 속성(예 를 들 어 Demo 에서 Item 류 의 Id 속성)입 니 다.이 속성의 값 은 전체 목록 에서 유일 합 니 다.아 이 템 은 아 이 템 대상 자체 에 있 습 니 다.데모 에서 그들의 실현 은 다음 과 같다.
private string ItemToKeyHandler(object item)
{
Item dataItem = item as Item;
if (dataItem == null) return null;
return dataItem.Id.ToString();
}
private IAsyncOperation<object> KeyToItemHandler(string key)
{
Func<System.Threading.CancellationToken, Task<object>> taskProvider = token =>
{
var items = listView.ItemsSource as List<Item>;
if (items != null)
{
var targetItem = items.FirstOrDefault(m => m.Id == int.Parse(key));
return Task.FromResult((object)targetItem);
}
else
{
return Task.FromResult((object)null);
}
};
return AsyncInfo.Run(taskProvider);
}
이 두 가지 방법 을 실현 한 후 목록 페이지 를 다시 불 러 옵 니 다. OnNavigatingFrom 방법 은 다음 코드 를 추가 하여 스크롤 위 치 를 가 져 오고 저장 합 니 다.
string position = ListViewPersistenceHelper.GetRelativeScrollPosition(this.listView, ItemToKeyHandler);
NavigationInfoHelper.SetInfo(targetItem, position);
페이지 에 Loaded 이 벤트 를 계속 등록 하고 Loaded 이벤트 에 다음 코드 를 추가 하여 스크롤 위 치 를 설정 합 니 다.
if (navigationParameter != null)
{
if (NavigationInfoHelper.IsHasInfo)
{
await ListViewPersistenceHelper.SetRelativeScrollPositionAsync(listView, NavigationInfoHelper.LastPosition, KeyToItemHandler);
}
}
여기 서 주의해 야 할 것 은 스크롤 위 치 를 설정 하 는 방법 은 비동기 적 이기 때문에 Loaded 방법 은 async 수식 자 를 추가 해 야 합 니 다.상기 코드 에서 navigation Parameter 파라미터 에 대한 판단 은 네 비게 이 션 을 할 때 최근 에 탐색 한 위치 로 위 치 를 정 했 는 지,Demo 의 코드 를 구체 적 으로 참고 할 수 있 습 니 다.2.ListView 스크롤 위치 항목 가 져 오기
두 번 째 수요 의 실현 에 대해 우 리 는 먼저 다음 과 같은 세 가 지 를 알 아야 한다.
public static List<T> GetAllVisibleItems<T>(this ListViewBase listView)
{
var scrollViewer = listView.GetScrollViewer();
if (scrollViewer == null)
{
return null;
}
List<T> targetItems = new List<T>();
foreach (T item in listView.Items)
{
var itemContainer = listView.ContainerFromItem(item) as FrameworkElement;
bool isVisible = IsVisibileToUser(itemContainer, scrollViewer, true);
if (isVisible)
{
targetItems.Add(item);
}
}
return targetItems;
}
상기 코드 의 foreach 순환 중의 부분 은 바로 우리 가 상술 한 사고방식 의 구현 이다.그 중에서 호출 된 IsVisibleToUser 방법 은 특정한 ListView Item 이 ScrollViewer 에서 현재 볼 수 있 는 지 여 부 를 어떻게 판단 합 니까?그 코드 는 다음 과 같다.
/// <summary>
/// Code from here:
/// https://social.msdn.microsoft.com/Forums/en-US/86ccf7a1-5481-4a59-9db2-34ebc760058a/uwphow-to-get-the-first-visible-group-key-in-the-grouped-listview?forum=wpdevelop
/// </summary>
/// <param name="element">ListViewItem or element in ListViewItem</param>
/// <param name="container">ScrollViewer</param>
/// <param name="isTotallyVisible">If the element is partially visible, then include it. The default value is false</param>
/// <returns>Get the visibility of the target element</returns>
private static bool IsVisibileToUser(FrameworkElement element, FrameworkElement container, bool isTotallyVisible = false)
{
if (element == null || container == null)
return false;
if (element.Visibility != Visibility.Visible)
return false;
Rect elementBounds = element.TransformToVisual(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect containerBounds = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
if (!isTotallyVisible)
{
return (elementBounds.Top < containerBounds.Bottom && elementBounds.Bottom > containerBounds.Top);
}
else
{
return (elementBounds.Bottom < containerBounds.Bottom && elementBounds.Top > containerBounds.Top);
}
}
우 리 는 두 개의 Rect 값 을 얻 을 수 있 음 을 알 수 있다.Rect 유형의 값 은 직사각형 구역 의 위치 와 크기 를 대표 합 니 다.우 리 는 이 두 값 을 비교 한 후에 최종 결 과 를 되 돌려 줍 니 다.ListView Item 의 Rect 값 을 가 져 옵 니 다:element.TransformToVisual(container)이 돌아 온 결 과 는 GeneralTransform 형식 입 니 다.이 값 은 ListView Item 이 Container(즉 ScrollViewer)의 위치 변환 정 보 를 나 타 냅 니 다.GeneralTransform 유형 은 우리 가 잘 모 르 겠 지만,그것 에서 파생 된 이러한 유형:Scale Transform,Translate Transform,우 리 는 잘 알 고 있 습 니 다.GeneralTransform 은 바로 그들의 기본 클래스 입 니 다.General Transform 은 다음 과 같은 두 가지 중요 한 방법 을 포함한다.
ScrollViewer 의 Rect 값 가 져 오기:Rect 를 직접 예화 합 니 다.0,0 을 왼쪽 상단 의 좌표 위치 로 하고 ScrollViewer 의 ActualWidth 와 ActualHeight 를 크기 로 합 니 다.
다음은 비교 과정 이다.여기 서 우 리 는 요소(ListView Item)가 부분 만 있 는 것 이 아니 라 스크롤 뷰 어 에 있 는 지 판단 했다.부분 적 인 표 시 를 요구 하면 요소 의 Top 이 Container 의 Bottom 값 보다 적 고 요소 의 Bottom 이 Container 의 Top 보다 크다.모든 디 스 플레이 를 요구 하면 알고리즘 은 요소 의 Top 이 Container 의 Top 보다 크 고 요소 의 Bottom 이 Container 의 Bottom 보다 작 습 니 다.언어 설명 이나 코드 를 아직 모 르 시 면 종이 에 그 려 서 비교 하 셔 도 됩 니 다.
그 다음 에 우 리 는 GetAllVisbleItems 방법의 사고방식 에 따라 GetFirst Visible Item 방법 을 실현 할 수 있 습 니 다.즉,목록 에서 첫 번 째 로 볼 수 있 는 항목 을 얻 을 수 있 습 니 다.코드 는 Demo 의 원본 코드 를 참고 할 수 있 습 니 다.여기 서 더 이상 군말 하지 않 겠 습 니 다.
이전에 다시 불 러 오 는 방법 인 OnNavigatingFrom 에 이 코드 를 추가 하면 사용자 가 위 치 를 탐색 하 는 곳 에 있 는 것 을 얻 을 수 있 습 니 다.
var targetItem = this.listView.GetFirstVisibleItem<Item>();
이로써 모든 주요 기능 이 기본적으로 완성 되 었 다.결어
본 고 는 ListView 의 스크롤 위 치 를 어떻게 얻 고 설정 하 는 지,그리고 스크롤 위 치 를 가 져 오 는 지 를 소개 했다.전 자 는 주로 ListView PersistenceHelper 를 통 해 이 루어 졌 고 후 자 는 ListView Item 과 ScrollViewer 의 Rect 값 을 얻 고 비교 한 결과 실 현 된 것 이다.더 좋 은 방법,다른 것 을 볼 수 있다 면 메 시 지 를 남기 고 함께 교류 하 세 요.
원본 코드 다운로드
참고 자료:
ListView Sample
How to get the first visible group key in the grouped listview
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Flutter의 ListTile에서 높이를 지정하면 레이아웃이 무너지는 문제현재 업무로 1개월 반 정도 Flutter를 사용하고 있습니다. 아주 좋은 팀으로, 최근에는 Flutter 자체에도 열중해 왔습니다. title, subtitle, leading, trailing 등을 설정하는 것만...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.