Flutter에서 PageView로 심층 분석 (사용자 정의 전환 사용)

PageView 위젯 탐색 및 사용자 정의 페이지 전환 작성

이 기사는 Flutter의 내장 위젯에 대해 자세히 살펴 보는 기사 시리즈 중 7 번째 기사입니다.

  1. ListView / ScrollPhysics
  2. 텍스트 필드
  3. FloatingActionButtons
  4. 영웅 위젯
  5. 변형 위젯
  6. 드래그 가능 / 끌기 대상

이 기사에서는 PageView를 살펴보고 나중에 몇 가지 사용자 정의 효과를 만듭니다.

참고 : ListView Deep Dive는이 기사의 전조입니다. 이 기사에서 다루는 요소는 거의 동일하므로 반복되지 않습니다. 내 ListView 기사를 여기에서 읽을 수 있습니다

페이지 뷰 탐색

PageView는 화면에 스크롤 가능한 페이지를 생성하는 위젯입니다. 고정 된 페이지 목록 또는 반복 페이지를 작성하는 빌더 기능 일 수 있습니다. PageView는 요소 구성 측면에서 ListView와 유사하게 작동합니다.

PageView의 유형은 다음과 같습니다.

  1. 페이지보기
  2. PageView.builder
  3. PageView.custom

PageView (기본 생성자)

이 유형은 고정 된 하위 (페이지) 목록을 가져 와서 스크롤 가능하게 만듭니다.

페이지보기(
  어린이 : <위젯> [
    컨테이너(
      색상 : Colors.pink,
    ),
    컨테이너(
      색상 : Colors.cyan,
    ),
    컨테이너(
      색상 : Colors.deepPurple,
    ),
  ],
)

위의 코드는 다음과 같은 결과를 생성합니다.

PageView.builder

이 생성자는 itemBuilder 함수와 ListView.builder와 비슷한 itemCount를 사용합니다.

PageView.builder (
  itemBuilder : (문맥, 위치) {
    return _buildPage ();
  },
  itemCount : listItemCount, // null 일 수 있음
)

ListView.builder와 마찬가지로 요청시 어린이를 빌드합니다.

itemCount가 널 (설정되지 않음)로 설정되면 무한 페이지 목록이 생성 될 수 있습니다.

예를 들어이 코드는 다음과 같습니다.

PageView.builder (
  itemBuilder : (문맥, 위치) {
    반품 컨테이너 (
      색상 : 위치 % 2 == 0? Colors.pink : Colors.cyan,
    );
  },
)

분홍색과 청록색이 번갈아 나타나는 무한한 페이지 목록을 제공합니다.

참고 : PageView.custom은 ListView.custom (이전 Deep Dive에서 논의)과 같은 방식으로 작동하며 여기서는 설명하지 않습니다.

정위

모든 유형의 페이지보기에는 가로 또는 세로 스크롤 페이지가있을 수 있습니다.

페이지보기(
  어린이 : <위젯> [
    // 여기에 아이들을 추가하십시오
  ],
  scrollDirection : Axis.vertical,
)

위의 코드는 다음을 제공합니다.

PageSnapping

페이지 스냅을 사용하면 페이지를 중간 값으로 유지할 수 있습니다. pageSnapping 속성을 해제하면됩니다. 이 경우 페이지는 정수 위치로 스크롤되지 않으며 일반 ListView처럼 동작합니다.

페이지보기(
  어린이 : <위젯> [
    // 여기에 아이들을 추가하십시오
  ],
  pageSnapping : false,
)

스크롤 물리

PageView는 ListView와 같은 방식으로 사용자 정의 스크롤 동작을 가질 수 있습니다. 다른 유형의 ScrollPhysics는 ListView Deep Dive에서 논의되므로 반복하지 않습니다.

물리 매개 변수를 사용하여 ScrollPhysics를 변경할 수 있습니다.

페이지보기(
  어린이 : <위젯> [
    // 여기에 아이들을 추가하십시오
  ],
  물리학 : BouncingScrollPhysics (),
)

PageView 제어

PageController를 연결하여 프로그래밍 방식으로 PageView를 제어 할 수 있습니다.

// 외부 빌드 방법
PageController controller = PageController ();
// 내부 빌드 방법
페이지보기(
  컨트롤러 : 컨트롤러,
  어린이 : <위젯> [
    // 자녀 추가
  ],
)

컨트롤러를 사용하여 스크롤 위치, 현재 페이지 등을 확인할 수 있습니다.

참고 : controller.currentPage는 double 값을 반환합니다. 예를 들어, 페이지를 스 와이프 할 때 값이 1에서 2로 점차 이동하고 2로 즉시 이동하지 않습니다.

페이지 뷰에 사용자 정의 전환 추가

Transform + PageView를 사용하여 페이지에 몇 가지 사용자 지정 전환을 추가하는 방법에 대해 설명하겠습니다. 이 부분에서는 변형 위젯을 광범위하게 사용하므로 위젯에서 여러 기사 중 하나를 읽는 것이 좋습니다.

내가 추천 한 것은 내가 작성한 Deep Dive와 WM Leler의 Transform 기사입니다.

전환 1

설정

먼저 기본 PageView.builder를 사용합니다.

PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
  },
  품목 개수 : 10,
)

지금은 10 개의 아이템이 있습니다.

우리는 PageController와 currentPage의 값을 보유하는 변수를 사용합니다.

PageController 및 변수 정의

PageController controller = PageController ();
var currentPageValue = 0.0;

PageView가 스크롤 될 때 변수를 업데이트합니다.

controller.addListener (() {
  setState (() {
    currentPageValue = 컨트롤러. 페이지;
  });
});

마지막으로 PageView를 구성합니다.

이제 세 가지 조건을 확인하겠습니다.

  1. 페이지가 스 와이프중인 페이지 인 경우
  2. 페이지가 스 와이프중인 페이지 인 경우
  3. 페이지가 페이지 오프 화면 인 경우
PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
    if (position == currentPageValue.floor ()) {
    } else if (위치 == currentAnimationValue.floor () + 1) {
      
    } else {
      
    }
  },
  품목 개수 : 10,
)

이제 동일한 페이지를 반환하지만 페이지를 스 와이프 할 때 페이지를 변환하기 위해 변형 위젯에 래핑되었습니다.

PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
    if (position == currentPageValue.floor ()) {
      리턴 변환 (
        변환 : Matrix4.identity () .. rotateX (currentPageValue-위치),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else if (위치 == currentPageValue.floor () + 1) {
      리턴 변환 (
        변환 : Matrix4.identity () .. rotateX (currentPageValue-위치),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else {
      반품 컨테이너 (
        색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
        어린이 : 센터 (
          아이 : 텍스트 (
            "페이지",
            스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
          ),
        ),
      );
    }
  },
  품목 개수 : 10,
)

여기에서 스 와이프중인 페이지와 스 와이프중인 페이지를 변환합니다.

currentPageValue.floor ()는 왼쪽에 페이지를 제공하고

currentPageValue.floor ()는 오른쪽에 페이지를 제공합니다

이 예에서는 currentPageValue 값에서 지수를 뺀 값으로 스 와이프하여 페이지를 X 방향으로 회전시킵니다. 이 값을 곱하여 효과를 증폭시킬 수 있습니다.

이 변형 및 변형 정렬을 조정하여 여러 유형의 새 페이지 전환을 제공 할 수 있습니다.

전환 2

다른 변형을 가진 비슷한 코드 구조 :

PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
    if (position == currentPageValue.floor ()) {
      리턴 변환 (
        변환 : Matrix4.identity () .. rotateY (currentPageValue-position) .. rotateZ (currentPageValue-position),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else if (위치 == currentPageValue.floor () + 1) {
      리턴 변환 (
        변환 : Matrix4.identity () .. rotateY (currentPageValue-position) .. rotateZ (currentPageValue-position),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else {
      반품 컨테이너 (
        색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
        어린이 : 센터 (
          아이 : 텍스트 (
            "페이지",
            스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
          ),
        ),
      );
    }
  },
  품목 개수 : 10,
)

여기에서는 Y 축과 Z 축을 중심으로 회전합니다.

전환 3

이것은 지난 시간과 비슷한 유형이지만 3D 효과가 추가되었습니다.

PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
    if (position == currentPageValue.floor ()) {
      리턴 변환 (
        변환 : Matrix4.identity () .. setEntry (3, 2, 0.004) .. rotateY (currentPageValue-position) .. rotateZ (currentPageValue-position),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else if (위치 == currentPageValue.floor () + 1) {
      리턴 변환 (
        변환 : Matrix4.identity () .. setEntry (3, 2, 0.004) .. rotateY (currentPageValue-position) .. rotateZ (currentPageValue-position),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else {
      반품 컨테이너 (
        색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
        어린이 : 센터 (
          아이 : 텍스트 (
            "페이지",
            스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
          ),
        ),
      );
    }
  },
  품목 개수 : 10,
)

라인

..setEntry (3, 2, 0.004)

페이지에 3D와 같은 효과를줍니다.

전환 4

PageView.builder (
  컨트롤러 : 컨트롤러,
  itemBuilder : (문맥, 위치) {
    if (position == currentPageValue.floor ()) {
      리턴 변환 (
        정렬 : Alignment.center,
        변환 : Matrix4.identity () .. setEntry (3, 2, 0.001)
          ..rotateX (currentPageValue-위치)
          ..rotateY (currentPageValue-위치)
          ..rotateZ (currentPageValue-위치),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else if (위치 == currentPageValue.floor () + 1) {
      리턴 변환 (
        정렬 : Alignment.center,
        변환 : Matrix4.identity () .. setEntry (3, 2, 0.001)
          ..rotateX (currentPageValue-위치)
          ..rotateY (currentPageValue-위치)
          ..rotateZ (currentPageValue-위치),
        아이 : 컨테이너 (
          색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
          어린이 : 센터 (
            아이 : 텍스트 (
              "페이지",
              스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
            ),
          ),
        ),
      );
    } else {
      반품 컨테이너 (
        색상 : 위치 % 2 == 0? Colors.blue : Colors.pink,
        어린이 : 센터 (
          아이 : 텍스트 (
            "페이지",
            스타일 : TextStyle (색상 : Colors.white, fontSize : 22.0),
          ),
        ),
      );
    }
  },
  품목 개수 : 10,
)

회전 각도, 축, 정렬 및 평행 이동 만 변경하면 훨씬 더 많은 유형을 만들 수 있습니다.

PageView를 사용한 데모 앱

Flutter에서 PageView를 사용하여 간단한 앱을 시연하기 위해 GRE 용 단어를 연구하는 예제 앱을 만들었습니다. 이 앱은 사용자가 SQLite를 사용하여 가장 어려운 단어를 저장하고 저장하도록합니다. 또한 단어 자체를 발음하는 텍스트 음성 변환 기능이 있습니다.

https://github.com/deven98/FlutterGREWords에서이 앱을 찾을 수 있습니다.

이 기사가 끝났습니다! 나는 당신이 그것을 즐기기를 바랍니다. Flutter 기사를 더 보려면 저를 따르고이 기사에 대한 의견이 있으면 의견을 보내주십시오.

다른 프로파일과 기사도 자유롭게 확인하십시오.

내 다른 기사 중 일부