Android 는 그림 스크롤 과 페이지 서명 컨트롤 기능 의 실현 코드 를 실현 합 니 다.

먼저,오늘 아침 에 일 어 났 을 때 손 이 미 끄 러 지 며 내 휴대 전 화 를 내 던 졌 다.결국 2 년 반 동안 함께 있 었 던 모 토로 라 이정표 세대 가 이렇게 편히 잠 들 었 다.그래서 나 는 오늘 더욱 화가 나 서 내 가 죽은 사랑 의 기 회 를 기념 하기 로 결정 했다.
만약 당신 이 인터넷 쇼핑 의 달인 이 라면,당신 의 휴대 전화 에는 타 오 바 오 클 라 이언 트 가 빠 질 수 없 을 것 입 니 다.필 터 를 주목 하 는 사람들 은 타 오 바 오 가 사이트 든 모 바 일 클 라 이언 트 든 홈 페이지 에 사진 스크롤 플레이어 가 있 고 그 위 에 추천 하 는 상품 을 보 여 준다.타 오 바 오 로 거의 타이틀 을 붙 일 수 있 는 기능 인 데 멋 있어 보 여요.오늘 바로 이 루 겠 습 니 다.
실현 원 리 는 사실 이전의 그 문장 이다Android 모방 클 라 이언 트 슬라이딩 메뉴 의 사 이 드 슬라이딩 메뉴 효과역사상 가장 간단 한 측면 미끄럼 실현 이다.  ,그 원 리 를 바탕 으로 한 또 다른 변종 이 라 고 할 수 있다.이른바 일 통 백 통 이라는 것 이 한 가지 방법 을 진정 으로 파악 한 후에 이 방법 을 사용 하여 각종 통 하지 않 는 효 과 를 바 꿀 수 있다.
오늘 도 사용자 정의 컨트롤 을 실행 한 다음 임의의 Activity 레이아웃 파일 에서 참조 하면 그림 스크롤 러 의 효 과 를 실현 할 수 있 습 니 다.
Eclipse 에 안 드 로 이 드 프로젝트 를 새로 만 들 었 습 니 다.프로젝트 이름 은 SlidingView Switcher 입 니 다.
Sliding Switcher View 라 는 새로운 종 류 를 만 들 었 습 니 다.이 종 류 는 Relative Layout 에서 계승 되 었 고 OnTouch Listener 인 터 페 이 스 를 실현 하 였 습 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.

public class SlidingSwitcherView extends RelativeLayout implements OnTouchListener { 
 /** 
 *      ,           。 
 */ 
 public static final int SNAP_VELOCITY = 200; 
 /** 
 * SlidingSwitcherView   。 
 */ 
 private int switcherViewWidth; 
 /** 
 *           。 
 */ 
 private int currentItemIndex; 
 /** 
 *           。 
 */ 
 private int itemsCount; 
 /** 
 *           。 
 */ 
 private int[] borders; 
 /** 
 *            。              ,marginLeft      ,     。 
 * 
 */ 
 private int leftEdge = 0; 
 /** 
 *            。   0,marginLeft      ,     。 
 */ 
 private int rightEdge = 0; 
 /** 
 *            。 
 */ 
 private float xDown; 
 /** 
 *            。 
 */ 
 private float xMove; 
 /** 
 *            。 
 */ 
 private float xUp; 
 /** 
 *     。 
 */ 
 private LinearLayout itemsLayout; 
 /** 
 *     。 
 */ 
 private LinearLayout dotsLayout; 
 /** 
 *          。 
 */ 
 private View firstItem; 
 /** 
 *            ,    leftMargin  ,             。 
 */ 
 private MarginLayoutParams firstItemParams; 
 /** 
 *            。 
 */ 
 private VelocityTracker mVelocityTracker; 
 /** 
 *   SlidingSwitcherView     ,     XML           。 
 * 
 * @param context 
 * @param attrs 
 */ 
 public SlidingSwitcherView(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 } 
 /** 
 *         。 
 */ 
 public void scrollToNext() { 
 new ScrollTask().execute(-20); 
 } 
 /** 
 *         。 
 */ 
 public void scrollToPrevious() { 
 new ScrollTask().execute(20); 
 } 
 /** 
 *  onLayout                 。 
 */ 
 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
 super.onLayout(changed, l, t, r, b); 
 if (changed) { 
  initializeItems(); 
  initializeDots(); 
 } 
 } 
 /** 
 *        ,             ,            ,           。 
 */ 
 private void initializeItems() { 
 switcherViewWidth = getWidth(); 
 itemsLayout = (LinearLayout) getChildAt(0); 
 itemsCount = itemsLayout.getChildCount(); 
 borders = new int[itemsCount]; 
 for (int i = 0; i < itemsCount; i++) { 
  borders[i] = -i * switcherViewWidth; 
  View item = itemsLayout.getChildAt(i); 
  MarginLayoutParams params = (MarginLayoutParams) item.getLayoutParams(); 
  params.width = switcherViewWidth; 
  item.setLayoutParams(params); 
  item.setOnTouchListener(this); 
 } 
 leftEdge = borders[itemsCount - 1]; 
 firstItem = itemsLayout.getChildAt(0); 
 firstItemParams = (MarginLayoutParams) firstItem.getLayoutParams(); 
 } 
 /** 
 *        。 
 */ 
 private void initializeDots() { 
 dotsLayout = (LinearLayout) getChildAt(1); 
 refreshDotsLayout(); 
 } 
 @Override 
 public boolean onTouch(View v, MotionEvent event) { 
 createVelocityTracker(event); 
 switch (event.getAction()) { 
 case MotionEvent.ACTION_DOWN: 
  //      ,          
  xDown = event.getRawX(); 
  break; 
 case MotionEvent.ACTION_MOVE: 
  //      ,         ,        ,        leftMargin ,            
  xMove = event.getRawX(); 
  int distanceX = (int) (xMove - xDown) - (currentItemIndex * switcherViewWidth); 
  firstItemParams.leftMargin = distanceX; 
  if (beAbleToScroll()) { 
  firstItem.setLayoutParams(firstItemParams); 
  } 
  break; 
 case MotionEvent.ACTION_UP: 
  //      ,           ,            ,          
  xUp = event.getRawX(); 
  if (beAbleToScroll()) { 
  if (wantScrollToPrevious()) { 
   if (shouldScrollToPrevious()) { 
   currentItemIndex--; 
   scrollToPrevious(); 
   refreshDotsLayout(); 
   } else { 
   scrollToNext(); 
   } 
  } else if (wantScrollToNext()) { 
   if (shouldScrollToNext()) { 
   currentItemIndex++; 
   scrollToNext(); 
   refreshDotsLayout(); 
   } else { 
   scrollToPrevious(); 
   } 
  } 
  } 
  recycleVelocityTracker(); 
  break; 
 } 
 return false; 
 } 
 /** 
 *         ,                    。 
 * 
 * @return   leftMargin   leftEdge rightEdge    true,    false。 
 */ 
 private boolean beAbleToScroll() { 
 return firstItemParams.leftMargin < rightEdge && firstItemParams.leftMargin > leftEdge; 
 } 
 /** 
 *                        。            ,                    。 
 * 
 * @return                  true,    false。 
 */ 
 private boolean wantScrollToPrevious() { 
 return xUp - xDown > 0; 
 } 
 /** 
 *                        。            ,                    。 
 * 
 * @return                  true,    false。 
 */ 
 private boolean wantScrollToNext() { 
 return xUp - xDown < 0; 
 } 
 /** 
 *                 。             1/2,          SNAP_VELOCITY, 
 *                。 
 * 
 * @return                 true,    false。 
 */ 
 private boolean shouldScrollToNext() { 
 return xDown - xUp > switcherViewWidth / 2 || getScrollVelocity() > SNAP_VELOCITY; 
 } 
 /** 
 *                 。             1/2,          SNAP_VELOCITY, 
 *                。 
 * 
 * @return                 true,    false。 
 */ 
 private boolean shouldScrollToPrevious() { 
 return xUp - xDown > switcherViewWidth / 2 || getScrollVelocity() > SNAP_VELOCITY; 
 } 
 /** 
 *         ,  currentItemIndex             。 
 */ 
 private void refreshDotsLayout() { 
 dotsLayout.removeAllViews(); 
 for (int i = 0; i < itemsCount; i++) { 
  LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams(0, 
   LayoutParams.FILL_PARENT); 
  linearParams.weight = 1; 
  RelativeLayout relativeLayout = new RelativeLayout(getContext()); 
  ImageView image = new ImageView(getContext()); 
  if (i == currentItemIndex) { 
  image.setBackgroundResource(R.drawable.dot_selected); 
  } else { 
  image.setBackgroundResource(R.drawable.dot_unselected); 
  } 
  RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams( 
   LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
  relativeParams.addRule(RelativeLayout.CENTER_IN_PARENT); 
  relativeLayout.addView(image, relativeParams); 
  dotsLayout.addView(relativeLayout, linearParams); 
 } 
 } 
 /** 
 *   VelocityTracker  ,         VelocityTracker  。 
 * 
 * @param event 
 *                
 */ 
 private void createVelocityTracker(MotionEvent event) { 
 if (mVelocityTracker == null) { 
  mVelocityTracker = VelocityTracker.obtain(); 
 } 
 mVelocityTracker.addMovement(event); 
 } 
 /** 
 *             View      。 
 * 
 * @return     ,               。 
 */ 
 private int getScrollVelocity() { 
 mVelocityTracker.computeCurrentVelocity(1000); 
 int velocity = (int) mVelocityTracker.getXVelocity(); 
 return Math.abs(velocity); 
 } 
 /** 
 *   VelocityTracker  。 
 */ 
 private void recycleVelocityTracker() { 
 mVelocityTracker.recycle(); 
 mVelocityTracker = null; 
 } 
 /** 
 *        ,     border,border      {@link #borders} 。 
 * 
 * @param leftMargin 
 *             
 * @param speed 
 *       ,        ,        。 
 * @return       border   true,    false。 
 */ 
 private boolean isCrossBorder(int leftMargin, int speed) { 
 for (int border : borders) { 
  if (speed > 0) { 
  if (leftMargin >= border && leftMargin - speed < border) { 
   return true; 
  } 
  } else { 
  if (leftMargin <= border && leftMargin - speed > border) { 
   return true; 
  } 
  } 
 } 
 return false; 
 } 
 /** 
 *       leftMargin     border 。 
 * 
 * @param leftMargin 
 *             
 * @return     leftMargin     border 。 
 */ 
 private int findClosestBorder(int leftMargin) { 
 int absLeftMargin = Math.abs(leftMargin); 
 int closestBorder = borders[0]; 
 int closestMargin = Math.abs(Math.abs(closestBorder) - absLeftMargin); 
 for (int border : borders) { 
  int margin = Math.abs(Math.abs(border) - absLeftMargin); 
  if (margin < closestMargin) { 
  closestBorder = border; 
  closestMargin = margin; 
  } 
 } 
 return closestBorder; 
 } 
 class ScrollTask extends AsyncTask<Integer, Integer, Integer> { 
 @Override 
 protected Integer doInBackground(Integer... speed) { 
  int leftMargin = firstItemParams.leftMargin; 
  //             ,     border ,    。 
  while (true) { 
  leftMargin = leftMargin + speed[0]; 
  if (isCrossBorder(leftMargin, speed[0])) { 
   leftMargin = findClosestBorder(leftMargin); 
   break; 
  } 
  publishProgress(leftMargin); 
  //           ,         10  ,             。 
  sleep(10); 
  } 
  return leftMargin; 
 } 
 @Override 
 protected void onProgressUpdate(Integer... leftMargin) { 
  firstItemParams.leftMargin = leftMargin[0]; 
  firstItem.setLayoutParams(firstItemParams); 
 } 
 @Override 
 protected void onPostExecute(Integer leftMargin) { 
  firstItemParams.leftMargin = leftMargin; 
  firstItem.setLayoutParams(firstItemParams); 
 } 
 } 
 /** 
 *              。 
 * 
 * @param millis 
 *            ,       
 */ 
 private void sleep(long millis) { 
 try { 
  Thread.sleep(millis); 
 } catch (InterruptedException e) { 
  e.printStackTrace(); 
 } 
 } 
} 
세심 한 친 구 는 내 가 예전 의 코드 를 많이 재 활용 한 것 을 알 수 있다.여기 몇 가지 중요 한 점 이 있다.내 가 말 할 게.onLayout 방법 에 서 는 그림 을 포함 하 는 컨트롤 의 크기 를 다시 정의 한 다음 그림 을 포함 하 는 컨트롤 마다 touch 이벤트 모니터 를 등록 합 니 다.이렇게 하면 우리 가 모든 그림 컨트롤 을 미 끄 러 뜨 릴 때 onTouch 사건 을 촉발 한 다음 에 첫 번 째 그림 컨트롤 의 left Margin 을 바 꾸 어 애니메이션 효 과 를 실현 합 니 다.그 다음 에 onLayout 에 페이지 서명 View 를 동적 으로 추 가 했 습 니 다.몇 개의 그림 컨트롤 이 몇 개의 페이지 서명 을 추가 한 다음 에 current ItemIndex 에 따라 어떤 페이지 서명 을 강조 할 지 결정 합 니 다.다른 것 도 특별히 설명 할 것 이 없 으 니 코드 와 주석 을 보 러 가 는 것 을 더 깊이 이해 하 세 요.
그리고 레이아웃 파일 에서 사용자 정의 이 컨트롤 을 어떻게 사용 하 는 지,activity 를 만 들 거나 여 는 지 보 세 요.main.xml,다음 코드 를 추가 합 니 다:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:orientation="horizontal" 
 tools:context=".MainActivity" > 
 <com.example.viewswitcher.SlidingSwitcherView 
 android:id="@+id/slidingLayout" 
 android:layout_width="fill_parent" 
 android:layout_height="100dip" > 
 <LinearLayout 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:orientation="horizontal" > 
  <Button 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:background="@drawable/image1" /> 
  <Button 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:background="@drawable/image2" /> 
  <Button 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:background="@drawable/image3" /> 
  <Button 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:background="@drawable/image4" /> 
 </LinearLayout> 
 <LinearLayout 
  android:layout_width="60dip" 
  android:layout_height="20dip" 
  android:layout_alignParentBottom="true" 
  android:layout_alignParentRight="true" 
  android:layout_margin="15dip" 
  android:orientation="horizontal" > 
 </LinearLayout> 
 </com.example.viewswitcher.SlidingSwitcherView> 
</LinearLayout> 
 com.example.view switcher.sliding Switcher View 의 루트 디 렉 터 리 에 두 개의 LinearLayout 가 설치 되 어 있 는 것 을 볼 수 있 습 니 다.첫 번 째 LinearLayout 에 스크롤 디 스 플레이 가 필요 한 그림 을 넣 어야 합 니 다.여기에 우 리 는 네 개의 Button 을 추 가 했 고 모든 Button 은 배경 그림 을 설정 합 니 다.두 번 째 LinearLayout 에 서 는 아무것도 추가 할 필요 가 없습니다.크기 와 위 치 를 잘 조절 하면 탭 이 실 행 될 때 이 layot 에 자동 으로 추 가 됩 니 다.
그리고 MainActivity 를 메 인 인터페이스 로 만 들 거나 열 었 습 니 다.추가 코드 가 추가 되 지 않 았 습 니 다.

public class MainActivity extends Activity { 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_main); 
 } 
} 
마지막 으로 AndroidManifest.xml 코드 를 주 고 자동 으로 생 성 된 내용 입 니 다.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
 package="com.example.viewswitcher" 
 android:versionCode="1" 
 android:versionName="1.0" > 
 <uses-sdk 
 android:minSdkVersion="8" 
 android:targetSdkVersion="8" /> 
 <application 
 android:allowBackup="true" 
 android:icon="@drawable/ic_launcher" 
 android:label="@string/app_name" 
 android:theme="@android:style/Theme.NoTitleBar" > 
 <activity 
  android:name="com.example.viewswitcher.MainActivity" 
  android:label="@string/app_name" > 
  <intent-filter> 
  <action android:name="android.intent.action.MAIN" /> 
  <category android:name="android.intent.category.LAUNCHER" /> 
  </intent-filter> 
 </activity> 
 </application> 
</manifest> 
자,이제 운행 효 과 를 살 펴 봅 시다.핸드폰 이 고장 나 서 시 뮬 레이 터 에서 만 운행 할 수 있 습 니 다.
먼저 프로그램 이 열 렸 을 때 화면 은 다음 과 같 습 니 다.

그리고 손가락 이 그림 에서 미 끄 러 지면 우 리 는 그림 이 구 르 는 효 과 를 볼 수 있다.
 
끊임없이 페이지 를 넘 기 면 페이지 서명 도 함께 변 합 니 다.다음 그림 에서 우 리 는 하 이 라이트 가 표 시 된 점 이 변 하 는 것 을 볼 수 있 습 니 다.
 
네,타 오 바 오 클 라 이언 트 의 효 과 를 비교 해 보 세 요.저 는 우리 가 잘 모방 한 것 같 아 요.어,뭔 가 부족 한 것 같 아...원래 그림 은 자동 으로 재생 되 지 않 습 니 다...
괜 찮 습 니 다.저 는 뒤의 글 에서 자동 재생 기능 을 추 가 했 습 니 다.또한 자동 재생 기능 뿐만 아니 라 참고 하 시기 바 랍 니 다Android 는 사용자 정의 속성 을 사용 하여 그림 자동 재생 스크롤 기능 을 수행 합 니 다.
오늘 의 글 은 여기까지 입 니 다.문제 가 있 는 친 구 는 아래 에 메 시 지 를 남 겨 주세요.
원본 다운로드,여 기 를 클릭 하 세 요.
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기