Android,위 챗 첫 페이지 좌우 슬라이딩 전환 효과 구현

여러분 은 위 챗 의 첫 페이지 전환 효과 가 매우 현란 하 다 고 생각 하 십 니까?미끄럼 전환,아래쪽 bar 를 클릭 하여 순간 전환,미끄럼 전환 그 라 데 이 션 효과,온라인 효과 그림:

전에 도 블 로그 에서 다른 사람의 실현 을 보고 다시 한 번 최 적 화 를 했 습 니 다.먼저 실현 원리,대신 생략,o(s□t)o
페이지 에서 보 이 는 세 페이지 는 세 개의 Fragment 입 니 다.좌우 로 미 끄 러 지 며 viewpager 를 사용 합 니 다.여러분 도 이렇게 재 활용 할 것 이 라 고 믿 습 니 다.그러면 밑 에 사용 하 는 기술 은 무엇 입 니까?밑 에 그 라 데 이 션 은 바로 ImageView 를 다시 쓴 것 입 니 다.그리고 좌우 로 미 끄 러 질 때 TextView 의 색상 값 을 바 꾸 었 습 니 다.간단 하지 않 습 니까? 
1.사용자 정의 ImageView: 

 /**
  *        bitmap       
  * @param normal normals
  * @param selected focus
  */
 public final void init(int normal, int selected, int width, int height) {
  this.mNormalIcon = createBitmap(normal);
  this.mSelectedIcon = createBitmap(selected);
  this.mNormalRect = new Rect(0, 0, width, height);
  this.mSelectedRect = new Rect(0, 0, width, height);
  this.mPaint = new Paint(1);
 }

여기 서 두 개의 비트 맵 을 정의 합 니 다.초점 을 얻 을 때 와 초점 을 잃 을 때 표시 되 는 비트 맵 이미지,두 개의 행렬 에 대응 합 니 다.그리 기 과정 에서 사용 되 는 외부 호출 방법 을 정 의 했 습 니 다.좌우 로 미 끄 러 지 는 과정 에서 오프셋 값 을 통 해 투명 값 을 바 꾸 고 두 장의 그림 중첩 은 대응 하 는 과도 한 효과 입 니 다.
그 다음 에 미끄럼 과정 에서 view 를 계속 새로 고치 고 다시 그립 니 다.이 를 통 해 onDraw 를 다시 쓰 는 방법 이 있 습 니 다. 

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (this.mPaint == null) {
   return;
  }
  this.mPaint.setAlpha(255 - this.mSelectedAlpha);
  canvas.drawBitmap(this.mNormalIcon, null, this.mNormalRect, this.mPaint);
  this.mPaint.setAlpha(this.mSelectedAlpha);
  canvas.drawBitmap(this.mSelectedIcon, null, this.mSelectedRect, this.mPaint);
 }

동료 Paint 가 들 어 오 는 두 개의 bitmap 투명 도 를 바 꾸 어 점차 적 인 효 과 를 얻 는 것 을 볼 수 있 습 니 다.그 중에서 mSelected Alpha 는 외부 로 투명 값 을 전달 합 니 다. 
2.아래쪽 bar 용 기 를 사용자 정의 합 니 다.여 기 는 LinearLayout 재 작성 을 통 해 이 루어 집 니 다(container 라 고 함).  container 에서 우 리 는 이렇게 몇 가지 일 을 해 야 합 니 다.
1).외부 호출 인 터 페 이 스 를 정의 하고 아래쪽 에 자원 정 보 를 표시 합 니 다.
a.우선 매개 변 수 를 초기 화 합 니 다. 

public void initContainer (String[] titles, int[][] iconsRes, int[] colors, boolean showTransitionColor) {
  this.mTitles = titles;
  this.mIconRes = iconsRes;
  this.mTextNormalColor = getResources().getColor(colors[0]);
  this.mTextSelectedColor = getResources().getColor(colors[1]);
  this.mShowTransitionColor = showTransitionColor;
 }

tab 에 표 시 된 텍스트 배열,표 시 된 그림 자원 배열,기본 색상 과 초점 을 얻 었 을 때 색상 값 배열(배열 크기=2),전환 시 과도 효 과 를 표시 할 지 여부 가 들 어 왔 습 니 다.
b.레이아웃 파일 과 레이아웃 파일 에 대응 하 는 컨트롤 ID 를 설정 하고 그림 을 표시 할 때 그림 의 너비 와 높이 파 라미 터 를 설정 하여 세 가지 방식 을 제공 합 니 다.
 ① 그림 탭: 

/**
  *            id
  * @param layout layout     id
  * @param iconId ImageView    id id <=0     
  * @param textId TextView    id id <=0     
  * @param width icon   
  * @param height icon   
  */
 public void setContainerLayout (int layout, int iconId, int textId, int width, int height) {
  mLayoutId = layout;
  mTextViewId = textId;
  mIconVIewId = iconId;
  mIconWidth = width;
  mIconHeight = height;
 }

여기 layot 및 tab 의 레이아웃 파일 입 니 다.iconId 는 사용자 정의 ImageView 자원 Id 에 대응 합 니 다.textId 는 TextView 의 Id 에 대응 합 니 다.너비 와 높이 는 그림 의 너비 와 높이 를 말 합 니 다.
② 텍스트 탭 만 있 음:텍스트 탭 을 표시 할 때 iconId 를 입력 하면 됩 니 다.
③ 그림 tab:해당 하 는 것 은 그림 tab 에서 제공 하 는 방법 으로 텍스트 textId=0 을 입력 하면 됩 니 다.
c.ViewPager 주입:ViewPager 의 미끄럼 을 감청 하여 그 라 데 이 션 색 을 바 꿔 야 합 니 다.
2).tab 를 쉬 운 container 에 추가 합 니 다.
iconId 와 TextId 가 0 보다 큰 지,=0 은 표시 되 지 않 는 지 판단 해 야 합 니 다.또한 중앙 에서 아래쪽 container 길 이 를 나 누 기 위해 모든 tab 는 아래쪽 container 를 등분 합 니 다. 

/**
  * <p>  tab view     </p>
  */
 private void addTabViewToContainer() {
  final PagerAdapter adapter = mViewPager.getAdapter(); 
  mTabView = new View[adapter.getCount()]; //    adapter        tab  

  for (int index = 0, len = adapter.getCount(); index < len; index++) {

   final View tabView = LayoutInflater.from(getContext()).inflate(mLayoutId, this, false); //  tab  
   mTabView[index] = tabView;

   /*tabIconView   */
   TabIconView iconView = null;
   if (mIconVIewId > 0) { //          ID  0 ,      icon,      View
    iconView = (TabIconView) tabView.findViewById(mIconVIewId);
    iconView.init(mIconRes[index][0], mIconRes[index][1], mIconWidth, mIconHeight); //       ImageView init  
   }

   /*tabTextView   */
   TextView textView = null;
   if (mTextViewId > 0) {
    textView = (TextView) tabView.findViewById(mTextViewId);
    textView.setText(mTitles[index]);

   }

   /*    ,  container*/
   LayoutParams lp = (LayoutParams) tabView.getLayoutParams();
   lp.width = 0;
   lp.weight = 1;

   /*  tab    */
   addTabOnClickListener(tabView, index);

   /*      */
   if (index == mViewPager.getCurrentItem()) { //    tab,             
    if (iconView != null) {
     iconView.offsetChanged(0);
    }
    tabView.setSelected(true);
    if (textView != null) {
     textView.setTextColor(mTextSelectedColor);
    }
   }

   addView(tabView);
  }
 }

3).viewPager 의 미끄럼 이 벤트 를 감청 하고 오프셋 값 에 따라 container 를 업데이트 하여 다시 그리 기 작업 을 완료 합 니 다.
4).container 의 onDraw 에서 오프셋 에 따라 투명 값 을 계산 합 니 다.이 텍스트 오프셋 값 은 오픈 소스 코드 를 사용 합 니 다.

@Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  final int childCount = getChildCount();
  if (childCount > 0) {
   /*      ,      */
   if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1) && mShowTransitionColor) {

    /*    tab   tab view */
    View selectedTab = getChildAt(mSelectedPosition);
    View nextTab = getChildAt(mSelectedPosition + 1);

    /*  tab icon ,    view    */
    if (mIconVIewId > 0) {
     View selectedIconView = selectedTab.findViewById(mIconVIewId);
     View nextIconView = nextTab.findViewById(mIconVIewId);

     //draw icon alpha
     if (selectedIconView instanceof TabIconView && nextIconView instanceof TabIconView) {
      ((TabIconView) selectedIconView).offsetChanged(mSelectionOffset);
      ((TabIconView) nextIconView).offsetChanged(1 - mSelectionOffset);
     }
    }

     /*  tab text,    view    */
    if (mTextViewId > 0) {
     View selectedTextView = selectedTab.findViewById(mTextViewId);
     View nextTextView = nextTab.findViewById(mTextViewId);

     //draw text color
     Integer selectedColor = (Integer) evaluate(mSelectionOffset, mTextSelectedColor, mTextNormalColor);
     Integer nextColor = (Integer) evaluate(1 - mSelectionOffset, mTextSelectedColor, mTextNormalColor);

     if (selectedTextView instanceof TextView && nextTextView instanceof TextView) {
      ((TextView) selectedTextView).setTextColor(selectedColor);
      ((TextView) nextTextView).setTextColor(nextColor);
     }
    }

   }
  }
 }

3.Fragment Adapter 를 정의 합 니 다.이 건 생략 하고 간단 합 니 다. 
4.위 와 같은 준비 작업 을 하면 테스트 예 를 들 어 효 과 를 시험 해 볼 수 있 습 니 다.물론 여기 서 효 과 를 보기 위해 우 리 는 미리 몇 장의 그림 과 몇 개의 fragment 를 준비 해 야 합 니 다. 

private void initViews() {  //  apdater
  TabFragmentAdapter mAdapter = new TabFragmentAdapter(getSupportFragmentManager(), fragments);
  ViewPager mPager = (ViewPager) findViewById(R.id.tab_pager);
  mPager.setAdapter(mAdapter);
  //        viewPager   
  TabContainerView mTabLayout = (TabContainerView) findViewById(R.id.ll_tab_container);
  mTabLayout.setOnPageChangeListener(this);

  mTabLayout.initContainer(getResources().getStringArray(R.array.tab_main_title), ICONS_RES, TAB_COLORS, true);

  int width = getResources().getDimensionPixelSize(R.dimen.tab_icon_width);
  int height = getResources().getDimensionPixelSize(R.dimen.tab_icon_height);
  mTabLayout.setContainerLayout(R.layout.tab_container_view, R.id.iv_tab_icon, R.id.tv_tab_text, width, height);
//  mTabLayout.setSingleTextLayout(R.layout.tab_container_view, R.id.tv_tab_text);
//  mTabLayout.setSingleIconLayout(R.layout.tab_container_view, R.id.iv_tab_icon);

  mTabLayout.setViewPager(mPager);
  mPager.setCurrentItem(getIntent().getIntExtra("tab", 0));
 }

ManActivity 에 대응 하 는 xml 는 비교적 간단 합 니 다.소스 코드 를 참고 할 수 있 습 니 다.마지막 으로 실행 효 과 는 바로 위의 스티커 입 니 다.이 를 통 해 위 챗 의 미끄럼 전환 이 완 료 됩 니 다.소스 코드 는 다음 링크 에 방문 하 십시오. 
원본 다운로드:https://github.com/JarekWang/wechathome.git
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기