android 레이아웃의 좌우 드래그 및 애니메이션 효과를 실현하는 코드 범례

8500 단어
먼저 PanelSwitcher 클래스:
package com.android.viewswitcher;

import android.view.animation.TranslateAnimation;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector;
import android.widget.FrameLayout;
import android.content.Context;
import android.util.AttributeSet;


class PanelSwitcher extends FrameLayout {
    private static final int MAJOR_MOVE = 100;
    private static final int ANIM_DURATION = 400;

    private GestureDetector mGestureDetector;
    private int mCurrentView;
    private View mChildren[] = new View[0];

    private int mWidth;
    private TranslateAnimation inLeft;
    private TranslateAnimation outLeft;

    private TranslateAnimation inRight;
    private TranslateAnimation outRight;

    private static final int LEFT  = 2;
    private static final int RIGHT = 3;
    private int mPreviousMove = 0;

    public PanelSwitcher(Context context, AttributeSet attrs) {
        super(context, attrs);
        mCurrentView = 0;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    int dx = (int) (e2.getX() - e1.getX());

                    // don't accept the fling if it's too short
                    // as it may conflict with a button push
                    if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) {
                        if (velocityX > 0) {
                            moveRight();
                        } else {
                            moveLeft();
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
            });
    }

    void setCurrentIndex(int current) {
        mCurrentView = current;
        updateCurrentView();
    }

    private void updateCurrentView() {
        for (int i = mChildren.length-1; i >= 0 ; --i) {
            mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE);
        }
    }

    @Override 
    public void onSizeChanged(int w, int h, int oldW, int oldH) {
        mWidth = w;
        inLeft   = new TranslateAnimation(mWidth, 0, 0, 0);
        outLeft  = new TranslateAnimation(0, -mWidth, 0, 0);        
        inRight  = new TranslateAnimation(-mWidth, 0, 0, 0);
        outRight = new TranslateAnimation(0, mWidth, 0, 0);

        inLeft.setDuration(ANIM_DURATION);
        outLeft.setDuration(ANIM_DURATION);
        inRight.setDuration(ANIM_DURATION);
        outRight.setDuration(ANIM_DURATION);
    }

    protected void onFinishInflate() {
        int count = getChildCount();
        mChildren = new View[count];
        for (int i = 0; i < count; ++i) {
            mChildren[i] = getChildAt(i);
        }
        updateCurrentView();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    void moveLeft() {
        //  <--
        if (mCurrentView < mChildren.length-1  && mPreviousMove != LEFT) {
            mChildren[mCurrentView+1].setVisibility(View.VISIBLE);
            mChildren[mCurrentView+1].startAnimation(inLeft);
            mChildren[mCurrentView].startAnimation(outLeft);
            mChildren[mCurrentView].setVisibility(View.GONE);

            mCurrentView ++;
            mPreviousMove ++;
        }
    }

    void moveRight() {
        //  -->
        if (mCurrentView > 0 && mPreviousMove != RIGHT) {
            mChildren[mCurrentView-1].setVisibility(View.VISIBLE);
            mChildren[mCurrentView-1].startAnimation(inRight);
            mChildren[mCurrentView].startAnimation(outRight);
            mChildren[mCurrentView].setVisibility(View.GONE);

            mCurrentView --;
            mPreviousMove --;
        }
    }

    int getCurrentIndex() {
        return mCurrentView;
    }
}

이 클래스는 뷰를 좌우로 전환할 수 있는 컨트롤을 사용자 정의하고 FrameLayout에서 계승하여 메인 레이아웃에서 레이아웃의 개수를 얻은 다음에 좌우로 드래그하는 동작을 하고 전환된 애니메이션을 간단한 애니메이션으로 완성하며 첫 번째 페이지의 판단을 한다.
여기에 세 개의view 레이아웃을 추가했습니다. 각각 다음과 같습니다.
layout1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/simplePad"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical"
         android:layout_gravity="center">
         <TextView android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:textSize="25sp"
                   android:text="This is the first view!"/>
</LinearLayout>

 layout2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/advancedPad"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical"
         android:layout_gravity="center">
         <TextView android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:textSize="25sp"
                   android:text="This is the second view!"/>
</LinearLayout>
layout3.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/thirdPad"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical"
         android:layout_gravity="center">
         <TextView android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:textSize="25sp"
                   android:text="This is the third view!"/>
</LinearLayout>

 main.xml 주 레이아웃:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <com.android.viewswitcher.PanelSwitcher
         android:id="@+id/panelswitch"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
         <include android:id="@+id/simplePad" layout="@layout/layout1" />
         <include android:id="@+id/advancedPad" layout="@layout/layout2" />
         <include android:id="@+id/thirdPad" layout="@layout/layout3" />
    </com.android.viewswitcher.PanelSwitcher>
</LinearLayout>

주 프로그램 코드:
package com.android.viewswitcher;
 
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.LinearLayout;
 
public class ViewSwitcher extends Activity {
    private LinearLayout mFirstLayout;
    private LinearLayout mSecondLayout;
    private LinearLayout mThirdLayout;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mFirstLayout = (LinearLayout)findViewById(R.id.simplePad);
        mSecondLayout = (LinearLayout)findViewById(R.id.advancedPad);
        mThirdLayout = (LinearLayout)findViewById(R.id.thirdPad);
        mFirstLayout.setBackgroundColor(Color.RED);
        mSecondLayout.setBackgroundColor(Color.BLUE);
        mThirdLayout.setBackgroundColor(Color.GREEN);
    }
}

좋은 웹페이지 즐겨찾기