안 드 로 이 드 는 네트워크 의 엄격 한 탭 표시 줄 미끄럼 효 과 를 실현 합 니 다.

탭 표시 줄 은 매우 흔히 볼 수 있 는 컨트롤 이 며,비교적 간단 한 컨트롤 인 것 같 지만,탭 아래 에 밑줄 을 치면 꽤 많은 꽃 을 피 울 수 있다.

왕 이 엄 선 된 태그 표시 줄 은 아주 잘 만 들 었 습 니 다.그 안에 많은 세부 사항 이 숨 어 있 습 니 다.
  • 수 동 으로 페이지 를 미 끄 러 뜨리 면 밑줄 이 미 끄 러 집 니 다.
  • 탭 을 선택 하면 밑줄 이 미 끄 러 지 는 애니메이션 이 있 습 니 다.
  • 에서 가장 왼쪽 이나 가장 오른쪽 에 있 는 탭 을 선택 하면 탭 표시 줄 이 미 끄 러 지 며 탭 을 가운데 로 붙 입 니 다(미 끄 러 질 수 있다 면).
  • 자세히 분석 하면 간단 한 탭 표시 줄 을 바탕 으로 다음 과 같은 논 리 를 실현 해 야 한다.
  • 밑줄 을 긋다.
  • 수 동 슬라이딩 페이지 이 벤트 를 감청 하고 밑줄 친 위 치 를 실시 간 으로 업데이트 합 니 다.
  • 탭 을 전환 할 때 밑줄 을 그 어 미 끄 러 지 는 애니메이션 을 시작 하고 탭 표시 줄 을 동시에 미 끄 러 뜨 릴 지 여 부 를 판단 합 니 다.

  • 저 는 샘플 프로그램 을 만 들 었 는데 그 중에서 어 려 운 점 은 밑줄 친 위치 와 밑줄 친 애니메이션 효 과 를 계산 하 는 것 입 니 다.
    
    //        tab,  indicator         
    private Pair<Float, Float> getIndicatorTargetLeftRight(int position, float positionOffset) { 
      View tab = tabsContainer.getChildAt(position); 
      Pair<Float, Float> indicator = getIndicatorLeftRight(tab); 
      float targetLeft = indicator.first; 
      float targetRight = indicator.second; 
      //   positionOffset  0,indicator     tab  ,              
      if (positionOffset > 0f && position < tabCount - 1) { 
        View nextTab = tabsContainer.getChildAt(position + 1); 
        Pair<Float, Float> indicatorForNextTab = getIndicatorLeftRight(nextTab); 
        float left = indicatorForNextTab.first; 
        float right = indicatorForNextTab.second; 
        targetLeft = (positionOffset * left + (1f - positionOffset) * targetLeft); 
        targetRight = (positionOffset * right + (1f - positionOffset) * targetRight); 
      } 
      return new Pair<>(targetLeft, targetRight); 
    } 
     
    private Pair<Float, Float> getIndicatorLeftRight(View tab) { 
      float left = tab.getLeft(); 
      float right = tab.getRight(); 
      if (indicatorMode == IndicatorMode.WRAP && tab instanceof TextView) { 
        TextView tabTextView = (TextView) tab; 
        paint.setTextSize(tabTextView.getTextSize()); 
        float textLength = paint.measureText(tabTextView.getText().toString()); 
        float middle = (left + right) / 2f; 
        left = middle - textLength / 2f; 
        right = middle + textLength / 2f; 
      } 
      return new Pair<>(left, right); 
    } 
    
    위 는 밑줄 친 위 치 를 계산 하 는 코드 입 니 다.onPageScrolled()에 들 어 오 는 position 과 position Offset 을 통 해 밑줄 친 위 치 를 계산 합 니 다.주의해 야 할 것 은 각 라벨 의 길이 가 다 를 수 있 기 때문에 밑줄 의 길 이 는 미끄럼 중 에 도 변화 가 생 길 수 있 으 므 로 밑줄 의 left 와 right 를 각각 계산 해 야 한다.
    
    private boolean isAnimateRunning = false; 
    private static final String TARGET_LEFT = "targetLeft"; 
    private static final String TARGET_RIGHT = "targetRight"; 
     
    private void startIndicatorAnimate(final float targetLeft, final float targetRight) { 
      //  indicator       ,             
      float move = 0; 
      if (indicatorCurrentRight < getScrollX()) { 
        move = getScrollX() - indicatorCurrentRight; 
      } else if (indicatorCurrentLeft > getScrollX() + DimenUtil.getScreenWidth(getContext())) { 
        move = getScrollX() + DimenUtil.getScreenWidth(getContext()) - indicatorCurrentLeft; 
      } 
      indicatorCurrentLeft += move; 
      indicatorCurrentRight += move; 
     
      PropertyValuesHolder valuesHolderLeft = PropertyValuesHolder.ofFloat( 
          TARGET_LEFT, indicatorCurrentLeft, targetLeft); 
      PropertyValuesHolder valuesHolderRight = PropertyValuesHolder.ofFloat( 
          TARGET_RIGHT, indicatorCurrentRight, targetRight); 
      ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(valuesHolderLeft, valuesHolderRight) 
          .setDuration(SCROLL_DURATION); 
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
        @Override 
        public void onAnimationUpdate(ValueAnimator animation) { 
          if (indicatorCurrentLeft != targetLeft) { 
            indicatorCurrentLeft = (float) animation.getAnimatedValue(TARGET_LEFT); 
          } 
          if (indicatorCurrentRight != targetRight) { 
            indicatorCurrentRight = (float) animation.getAnimatedValue(TARGET_RIGHT); 
          } 
          if (indicatorCurrentLeft == targetLeft && indicatorCurrentRight == targetRight) { 
            isAnimateRunning = false; 
          } 
          invalidate(); 
        } 
      }); 
      animator.start(); 
      isAnimateRunning = true; 
    } 
    
    이것 은 탭 을 전환 할 때 밑줄 을 그 어 미끄럼 애니메이션 을 실행 하 는 코드 입 니 다.ValueAnimator 를 사용 하여 이 루어 지고 밑줄 이 경 계 를 초과 하 는 상황 에 대해 특수 처 리 를 하여 미끄럼 거리 가 너무 클 때 미끄럼 속도 가 너무 빠 르 지 않도록 합 니 다.
    더 많은 세부 사항 은 https://github.com/wlkdb/page_sliding 을 보십시오.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기