Android 는 그림 스크롤 과 페이지 서명 컨트롤 기능 의 실현 코드 를 실현 합 니 다.
만약 당신 이 인터넷 쇼핑 의 달인 이 라면,당신 의 휴대 전화 에는 타 오 바 오 클 라 이언 트 가 빠 질 수 없 을 것 입 니 다.필 터 를 주목 하 는 사람들 은 타 오 바 오 가 사이트 든 모 바 일 클 라 이언 트 든 홈 페이지 에 사진 스크롤 플레이어 가 있 고 그 위 에 추천 하 는 상품 을 보 여 준다.타 오 바 오 로 거의 타이틀 을 붙 일 수 있 는 기능 인 데 멋 있어 보 여요.오늘 바로 이 루 겠 습 니 다.
실현 원 리 는 사실 이전의 그 문장 이다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 는 사용자 정의 속성 을 사용 하여 그림 자동 재생 스크롤 기능 을 수행 합 니 다.
오늘 의 글 은 여기까지 입 니 다.문제 가 있 는 친 구 는 아래 에 메 시 지 를 남 겨 주세요.
원본 다운로드,여 기 를 클릭 하 세 요.
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.