ViewFlipper,TextSwitcher

效果图:

封装:

public class GViewFlipper extends ViewFlipper {
    private Context mContext;
    //画显示器的画笔
    private Paint paint = new Paint();
    //指示器选中背景
    private int mSelectedColor = Color.BLACK;
    //指示器未选中背景
    private int mUnSelectedColor = Color.GRAY;
    //指示器显示的位置
    private GLayout mGLayout = GLayout.RIGHT_BOTTOM;
    //指示器的大小
    private int mIndicatorSize =
            getSize(10);
    //指示器间隔距离
    private int mLayoutInterval = getSize(5);
    //自动翻页
    private boolean mIsAutoFlipper;
    //默认翻页间隔3秒
    private int mFlipperInterval = 3000;
    //手势监听 请在界面显示后调用
    private OnMGestureListener mOnMGestureListener;
    private GestureDetector mGestureDetector;

    public void setmOnMGestureListener(OnMGestureListener mOnMGestureListener) {
        this.mOnMGestureListener = mOnMGestureListener;
    }

    //设置指示器显示位置
    public enum GLayout {
        CENTER_BOTTOM, RIGHT_BOTTOM
    }

    public GViewFlipper(Context context) {
        super(context);
        mContext = context;
        init(null);
    }

    public GViewFlipper(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init(attrs);
    }

    //初始化View
    private void init(AttributeSet attrs) {
        final TypedArray typeArray = mContext.obtainStyledAttributes(attrs, R.styleable.GViewFlipper);
        //初始化指示器位置
        if (typeArray.hasValue(R.styleable.GViewFlipper_mGLayout)) {
            int value = typeArray.getInt(R.styleable.GViewFlipper_mGLayout, 0);
            switch (value) {
                case 0:
                    mGLayout = GLayout.CENTER_BOTTOM;
                    break;
                case 1:
                    mGLayout = GLayout.RIGHT_BOTTOM;
                    break;
            }
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mIndicatorSize)) {
            mIndicatorSize = (int) typeArray.getDimension(R.styleable.GViewFlipper_mIndicatorSize, mIndicatorSize);
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mLayoutInterval)) {
            mLayoutInterval = (int) typeArray.getDimension(R.styleable.GViewFlipper_mLayoutInterval, mLayoutInterval);
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mSelectedColor)) {
            mSelectedColor = typeArray.getColor(R.styleable.GViewFlipper_mSelectedColor, mSelectedColor);
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mUnSelectedColor)) {
            mUnSelectedColor = typeArray.getColor(R.styleable.GViewFlipper_mUnSelectedColor, mUnSelectedColor);
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mIsAutoFlipper)) {
            mIsAutoFlipper = typeArray.getBoolean(R.styleable.GViewFlipper_mIsAutoFlipper, mIsAutoFlipper);
        }
        if (typeArray.hasValue(R.styleable.GViewFlipper_mFlipperInterval)) {
            mFlipperInterval = typeArray.getInteger(R.styleable.GViewFlipper_mFlipperInterval, mFlipperInterval);
        }
        typeArray.recycle();
        //设置自动开始动画
        setAutoStart(mIsAutoFlipper);
        //设置动画触发间隔的时间
        setFlipInterval(mFlipperInterval);
        //设置手势
        mGestureDetector = new GestureDetector(mContext,
                new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                        if (e1.getX() < e2.getX()) {
                            mOnMGestureListener.onSwipeLeft();
                        }

                        if (e1.getX() > e2.getX()) {
                            mOnMGestureListener.onSwipeRight();
                        }
//                        if (e1.getY() < e2.getY()) {
//                            Timber.d("Up to Down swipe performed");
//                        }
//
//                        if (e1.getY() > e2.getY()) {
//                            Timber.d("Down to Up swipe performed");
//                        }
                        return super.onFling(e1, e2, velocityX, velocityY);
                    }
                });
    }

    //设置手势动作
    public boolean setGestureEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        int width = getWidth();

        float radius = 10;
        float cx = 0;
        if (mGLayout == GLayout.CENTER_BOTTOM) {
            cx = width / 2 - ((radius + mLayoutInterval) * 2 * getChildCount() / 2);
        }
        if (mGLayout == GLayout.RIGHT_BOTTOM) {
            cx = width - (radius + mLayoutInterval) * 2 * getChildCount() - getSize(20);
        }
        //20 距离底部20dp
        float cy = getHeight() - getSize(20);
        canvas.save();

        for (int i = 0; i < getChildCount(); i++) {
            if (i == getDisplayedChild()) {
                paint.setColor(mSelectedColor);
                canvas.drawCircle(cx, cy, radius, paint);

            } else {
                paint.setColor(mUnSelectedColor);
                canvas.drawCircle(cx, cy, radius, paint);
            }
            cx += 2 * (radius + mLayoutInterval);
        }
        canvas.restore();
    }

    private int getSize(int size) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size
                , getResources().getDisplayMetrics());
    }

    //手势监听
    public interface OnMGestureListener {
        //向左滑动
        public void onSwipeLeft();

        //向右滑动
        public void onSwipeRight();
    }
}
xml:
<com.lskj.rrhr.shortkeytest.modules.viewFilpper.GViewFlipper
    android:id="@+id/vf_test"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:mFlipperInterval="3000"
    app:mIndicatorSize="5dp"
    app:mIsAutoFlipper="true"
    app:mSelectedColor="@android:color/holo_red_dark"
    app:mUnSelectedColor="@android:color/darker_gray" />

activity:onCreate()

mViewFlipper.addView(getImageView(R.drawable.ic_test_0));
        mViewFlipper.addView(getImageView(R.drawable.ic_test_1));
        mViewFlipper.addView(getImageView(R.drawable.ic_test_2));
        mViewFlipper.addView(getImageView(R.drawable.ic_test_3));
        mViewFlipper.addView(getImageView(R.drawable.ic_test_4));
@Override
    protected void onResume() {
        super.onResume();
        mViewFlipper.setmOnMGestureListener(new GViewFlipper.OnMGestureListener() {
            @Override
            public void onSwipeLeft() {
                mViewFlipper.showPrevious();
            }

            @Override
            public void onSwipeRight() {
                mViewFlipper.showNext();
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mViewFlipper.setGestureEvent(event);
    }

res-》values-》attrs

<declare-styleable name="GViewFlipper">
    <attr name="mSelectedColor" format="color|reference" />
    <attr name="mUnSelectedColor" format="color|reference" />
    <attr name="mGLayout" format="enum">
        <enum name="CENTER_BOTTOM" value="0" />
        <enum name="RIGHT_BOTTOM" value="1" />
    </attr>
    <attr name="mIndicatorSize" format="dimension" />
    <attr name="mLayoutInterval" format="dimension" />
    <attr name="mIsAutoFlipper" format="boolean" />
    <attr name="mFlipperInterval" format="integer" />
</declare-styleable>

参考:

http://codetheory.in/android-viewflipper-and-viewswitcher/

https://asishinwp.wordpress.com/2013/03/11/android-viewflipper-with-page-indicator/

While developing an Android application, most of us will encounter the need to integrate a section in our app where the user can switch between Views. So it should show one view which can be an ImageViewor a collection inside LinearLayoutRelativeLayout, etc. at a time that can be swiped/flinged to move to the next or previous item. Think of a slideshow of images or a step-based process like e-commerce checkouts. Basically whenever you want to swipe through a set of related sections but show only one at a time then you can leverageViewFlipper or ViewSwitcher class widgets that Android provides us. The detection of gestures can be achieved with major use of theMotionEvent class but we’ll make use of GestureDetector for this article.

ViewFlipper

So when we want to flip between two or more views, the ViewFlipperclass is what we’d most probably look at. We’ll try to create anImageView slideshow using it so let’s first define our layout resource at res/layout/activity_gesture.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:id="@+id/relativeLayout">

    <ViewFlipper
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/viewFlipper"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

    </ViewFlipper>

</RelativeLayout>

Now obviously there are two ways to add our child views into theViewFlipper:

  • Add them in this layout resource itself.
  • Add them programatically.

We’ll go with the second approach in our example. Before that you might want to get 5-6 odd image resources and put them inres/drawable/ directory. Personally, I downloaded six 400×600 images from LoremPixel and shoved them into the drawable directory. For naming them I used first.pngsecond.pngthird.pngand so on.

So the immediate next thing to do is, add the image views to theViewFlipper programatically like this from the onCreate() method of our Activity:

private ViewFlipper mViewFlipper;
private GestureDetector mGestureDetector;

int[] resources = {
        R.drawable.first,
        R.drawable.second,
        R.drawable.third,
        R.drawable.fourth,
        R.drawable.fifth,
        R.drawable.sixth
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gesture);

    // Get the ViewFlipper
    mViewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);

    // Add all the images to the ViewFlipper
    for (int i = 0; i < resources.length; i++) {
        ImageView imageView = new ImageView(this);
        imageView.setImageResource(resources[i]);
        mViewFlipper.addView(imageView);
    }
}

Now if you test your app activity in the emulator or a real handset then you’ll just see the first view. If you try to slide your fingers/mouse/pointer over the touch screen then nothing will happen. Hence, next we will integrate gesture detection using theGestureDetector class. For that we’ll first implement our custom gesture detector class as an inner class of our activity.

class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        // Swipe left (next)
        if (e1.getX() > e2.getX()) {
            mViewFlipper.showNext();
        }

        // Swipe right (previous)
        if (e1.getX() < e2.getX()) {
            mViewFlipper.showPrevious();
        }

        return super.onFling(e1, e2, velocityX, velocityY);
    }
}

Super easy to understand code. If the initial touch X coordinate is more than the final touch X position then it was a left swipe which means the intent was to see the next picture. If it’s just the opposite then showPrevious() needs to be called on the view flipper object.

The final step is to instantiate our custom gesture detector class and then re-route all the touch events to it from our Activity’sonTouchEvent() method. The instantiation code needs to go into ouronCreate() method:

CustomGestureDetector customGestureDetector = new CustomGestureDetector();
mGestureDetector = new GestureDetector(this, customGestureDetector);

The onTouchEvent() implementation will be like this:

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

    return super.onTouchEvent(event);
}

If you test the code on your device, you’ll notice the flipping between Views work great! Congrats on building your first slideshow withViewFlipper! But the problem is there’s no animation for the flipping motion which makes the experience really bland. So let’s add a really basic fade in and fade out animation by using a couple of android’s built-in animation resources. All we have to do is add this piece of code in the onCreate() method:

// Set in/out flipping animations
mViewFlipper.setInAnimation(this, android.R.anim.fade_in);
mViewFlipper.setOutAnimation(this, android.R.anim.fade_out);

Wow! Now there’s some interesting transition happening when the images are swiped. So here’s how our entire activity class will be like:

public class GestureActivity extends Activity {

    private ViewFlipper mViewFlipper;
    private GestureDetector mGestureDetector;

    int[] resources = {
            R.drawable.first,
            R.drawable.second,
            R.drawable.third,
            R.drawable.fourth,
            R.drawable.fifth,
            R.drawable.sixth
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gesture);

        // Get the ViewFlipper
        mViewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);

        // Add all the images to the ViewFlipper
        for (int i = 0; i < resources.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(resources[i]);
            mViewFlipper.addView(imageView);
        }

        // Set in/out flipping animations
        mViewFlipper.setInAnimation(this, android.R.anim.fade_in);
        mViewFlipper.setOutAnimation(this, android.R.anim.fade_out);

        CustomGestureDetector customGestureDetector = new CustomGestureDetector();
        mGestureDetector = new GestureDetector(this, customGestureDetector);
    }

    class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

            // Swipe left (next)
            if (e1.getX() > e2.getX()) {
                mViewFlipper.showNext();
            }

            // Swipe right (previous)
            if (e1.getX() < e2.getX()) {
                mViewFlipper.showPrevious();
            }

            return super.onFling(e1, e2, velocityX, velocityY);
        }
    }

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

        return super.onTouchEvent(event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gesture, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Automatically Start Flipping

If you want to auto-start flipping then the `ViewFlipper` API gives us the ability to do so. In the onCreate() method just put this:

mViewFlipper.setAutoStart(true);
mViewFlipper.setFlipInterval(2000); // flip every 2 seconds (2000ms)

Setting setAutoStart() to true will automatically call startFlipping()when the view flipper is attached to the window. setFlipInterval()defines the interval between each flips in milliseconds.

You might want to add a play icon/button that should trigger the slideshow. In that case you just set a click listener on that View that’ll trigger startFlipping() while the stop button will call stopFlipping().

Custom Sliding Flipping Animations

Instead of the built-in android animations we can also write our own animation XML resources and apply that to the transition. Let’s see how to write a simple one where the images will slide in and out of the screen on swipe. We’ll create four animation resources for:

  • Next image to come into screen (left_in.xml) and current image to move out from the left (left_out.xml) on swiping to left.
  • Previous image to come into screen (right_in.xml) and current image to move out from the right (right_out.xml) on swiping to the right.

Code for res/anim/left_in.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toXDelta="0" />

    <alpha
        android:duration="500"
        android:fromAlpha="0.1"
        android:toAlpha="1.0" />

</set>

Code for res/anim/left_out.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="-100%p" />

    <alpha
        android:duration="500"
        android:fromAlpha="1.0"
        android:toAlpha="0.1" />
</set>

Code for res/anim/right_in.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="500"
        android:fromXDelta="-100%p"
        android:toXDelta="0" />

    <alpha
        android:duration="500"
        android:fromAlpha="0.1"
        android:toAlpha="1.0" />

</set>

Code for res/anim/right_out.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="100%p" />

    <alpha
        android:duration="500"
        android:fromAlpha="1.0"
        android:toAlpha="0.1" />

</set>

Now in the Activity class’s onCreate() method remove thesetInAnimation() and setOutAnimation() method calls on the view flipper object. We’ll need them in the if blocks of our custom gesture detector class’s onFling() method. Here’s how our new custom gesture detector will look like after setting the new animation resources:

class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        // Swipe left (next)
        if (e1.getX() > e2.getX()) {
            mViewFlipper.setInAnimation(GestureActivity.this, R.anim.left_in);
            mViewFlipper.setOutAnimation(GestureActivity.this, R.anim.left_out);

            mViewFlipper.showNext();
        }

        // Swipe right (previous)
        if (e1.getX() < e2.getX()) {
            mViewFlipper.setInAnimation(GestureActivity.this, R.anim.right_in);
            mViewFlipper.setOutAnimation(GestureActivity.this, R.anim.right_out);

            mViewFlipper.showPrevious();
        }

        return super.onFling(e1, e2, velocityX, velocityY);
    }
}

Test it out in your device or emulator. You’ll enjoy some nice sliding effects while flipping over images in the slideshow.

Instead of using gestures to switch between views, you can also have buttons with click listeners that’d fire the mViewFlipper.showNext()and mViewFlipper.showPrevious() actions.

ViewSwitcher

By now if you’ve properly understood ViewFlipper then ViewSwitcherwill be a piece of cake for you. Just like ViewFlipperViewSwitcher is also a ViewAnimator (they are sub classes of ViewAnimator) that can hold only two child views (only significant difference with view flipper feature-wise) and show one at a time. We can add child views to it just like we did with our ViewFlipper or use its factory to create the views.

If we add Views like we did in the previous case:

// Get the ViewFlipper
mViewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);

// Add all the images to the ViewFlipper
for (int i = 0; i < resources.length; i++) {
    ImageView imageView = new ImageView(this);
    imageView.setImageResource(resources[i]);
    mViewSwitcher.addView(imageView);
}

This will work fine as long as resources has only 2 items, else it’ll throw an exception with the message

java.lang.IllegalStateException: Can‘t add more than 2 views to a ViewSwitcher.

Instead of calling addView() twice we can also call setFactory() on the ViewSwitcher object to set the factory that’d create the two views between which the user will switch (although I’d just prefer callingaddView() two times).

mViewSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
    @Override
    public View makeView() {
        ImageView imageView = new ImageView(GestureActivity.this);
        imageView.setImageResource(resources[0]);

        // Log.d(TAG, "setFactory#makeView");

        return imageView;
    }
});

The makeView() method will get called twice to generate two views. In this case it’s using the same resource as the image so we’ll have to set some condition (maybe based on mViewSwitcher.getChildCount()) to make sure that the second time some other resource is selected for the second view.

Here’s how your Activity making use of ViewSwitcher would look like (pretty much similar to the previous example using ViewFlipper):

public class GestureActivity extends Activity {

    // private ViewFlipper mViewFlipper;
    private ViewSwitcher mViewSwitcher;
    private GestureDetector mGestureDetector;

    int[] resources = {
            R.drawable.first,
            R.drawable.second/*,
            R.drawable.third,
            R.drawable.fourth,
            R.drawable.fifth,
            R.drawable.sixth*/
    };

    private String TAG = GestureActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gesture);

        // Get the ViewFlipper
        mViewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);

        /*mViewSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
            @Override
            public View makeView() {
                ImageView imageView = new ImageView(GestureActivity.this);
                imageView.setImageResource(resources[0]);

                Log.d(TAG, "setFactory#makeView");

                return imageView;
            }
        });*/

        // Add all the images to the ViewFlipper
        for (int i = 0; i < resources.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(resources[i]);
            mViewSwitcher.addView(imageView);
        }

        // Set in/out flipping animations
        //mViewFlipper.setInAnimation(this, android.R.anim.fade_in);
        //mViewFlipper.setOutAnimation(this, android.R.anim.fadeout);

        CustomGestureDetector customGestureDetector = new CustomGestureDetector();
        mGestureDetector = new GestureDetector(this, customGestureDetector);
    }

    class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

            // Swipe left (next)
            if (e1.getX() > e2.getX()) {
                mViewSwitcher.setInAnimation(GestureActivity.this, R.anim.left_in);
                mViewSwitcher.setOutAnimation(GestureActivity.this, R.anim.left_out);

                mViewSwitcher.showNext();
            }

            // Swipe right (previous)
            if (e1.getX() < e2.getX()) {
                mViewSwitcher.setInAnimation(GestureActivity.this, R.anim.right_in);
                mViewSwitcher.setOutAnimation(GestureActivity.this, R.anim.right_out);

                mViewSwitcher.showPrevious();
            }

            /*mViewSwitcher.getInAnimation().setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    Log.d(TAG, "Animation End");
                    Log.d(TAG, "Child Count: " + mViewSwitcher.getChildCount());
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });*/

            return super.onFling(e1, e2, velocityX, velocityY);
        }
    }

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

        return super.onTouchEvent(event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gesture, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Off the bat, one use of ViewSwitcher that I can think of is cases when you’ll need to have login and registration forms or maybe after the login submit button is clicked, the second view can show a loader or some confirmation message.

Differences Between ViewFlipper and ViewSwitcher

I came across these two classes when I really needed to transform one view to another for a specific requirement in my app which is similar to an image slideshow. Now based on the knowledge we’ve since we covered both of them in fair amount of details, the only difference between these two classes is that, ViewSwitcher supports only two views while ViewFlipper can have multiple. Also ViewSwitcher can source its views from a factory which has to be set via setFactory().

In most cases we’ll probably just want to use ViewFlipper over the other one.

Conclusion

These widgets are pretty nifty when a specific requirement entails moving between/among various Views. Although for my requirement I ended up using ViewPager because I really wanted its style of sliding transition where once the current image is pulled to the left the next one is also drawn along with it. Until a certain threshold if you release the image (or the View) then it’ll get back to its original state and the next View will move off the screen from the right edge.

If you’ve any questions regarding these view animators then feel free to discuss in the comments section.

添加圆型指示器:

Android ViewFlipper with page indicator.

Posted on March 11, 2013 by asish

Make a subclass of ViewFlipper and override “dispatchDraw(Canvas canvas)” method. Draw circle (rect, bitmap anything you like) in the bottom/upper of the viewFlipper.

public class AViewFlipper extends ViewFlipper
{

Paint paint = new Paint();

public AViewFlipper(Context context, AttributeSet attrs)
{
super(context, attrs);
}

@Override
protected void dispatchDraw(Canvas canvas)
{
super.dispatchDraw(canvas);
int width = getWidth();

float margin = 2;
float radius = 5;
float cx = width / 2 – ((radius + margin) * 2 * getChildCount() / 2);
float cy = getHeight() – 15;

canvas.save();

for (int i = 0; i < getChildCount(); i++)
{
if (i == getDisplayedChild())
{
paint.setColor(Color.BLUE);
canvas.drawCircle(cx, cy, radius, paint);

} else
{
paint.setColor(Color.GRAY);
canvas.drawCircle(cx, cy, radius, paint);
}
cx += 2 * (radius + margin);
}
canvas.restore();
}

}

That’s it, plot this view in xml.

<packageName.AViewFlipper

android:layout_width=”fill_parent”

android:layout_height=”@dimen/menubody_height”>

<include layout=”@layout/layout1″ />

<include layout=”@layout/layout2″ />

<include layout=”@layout/layout3″ />

</packageName.AViewFlipper>

添加手势 实现左右滑动 :

final GestureDetector mGestureDetector = new GestureDetector(mContext,                new GestureDetector.SimpleOnGestureListener() {                    @Override                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {                        if (e1.getX() < e2.getX()) {                            mOnMGestureListener.onSwipeLeft();                        }

                        if (e1.getX() > e2.getX()) {                            mOnMGestureListener.onSwipeRight();                        }//                        if (e1.getY() < e2.getY()) {//                            Timber.d("Up to Down swipe performed");//                        }////                        if (e1.getY() > e2.getY()) {//                            Timber.d("Down to Up swipe performed");//                        }                        return super.onFling(e1, e2, velocityX, velocityY);                    }                });        mGestureDetector.onTouchEvent(event);
时间: 2024-11-25 15:42:25

ViewFlipper,TextSwitcher的相关文章

二、Android应用的界面编程(七)ViewAnimator及其子类[ ViewSwitcher、ImageSwitcher、TextSwitcher、ViewFlipper ]

ViewAnimator是一个基类,它继承了FrameLayout.因此它表现出FrameLayout的特征,可以将多个View组“叠”在一起. ViewAnimator可以在View切换时表现出动画效果. ViewAnimator及其子类也是一组非常重要的UI组件,这种组件的主要功能是增加动画效果.从而使界面更加“炫”. [ViewAnimator及其子类的继承关系] 图2.56 [ViewAnimator支持的常见XML属性]android:animateFirstView 设置ViewAn

android ViewFlipper的使用

屏幕切换指的是在同一个 Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面. 通过查看 OPhone API文档可以发现,有个android.widget.ViewAnimator类继承至FrameLayout,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.该类有如下几个和动画相关的函数: l setInAnimation:设置 View进入屏幕时候使用的动画,该函数有两个

ViewFlipper与Gesture的使用&lt;一&gt;

转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/51924215 一,ViewFlipper的基本知识: (1)用途:常用于多个组件之间的切换,如动画播放,手势滑动切换,等等 (2)基本知识:继承自ViewAnimator,可调用addView(View v)添加多个组件 (3)基本方法: flipper.startFlipping()  ---- 开始自动播放动画 flipper.setInAnimation(上下文对象,动画布

ViewFlipper 在同一背景下 页面左右滑动

<ViewFlipper android:id="@+id/ViewFlipper1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:inAnimation="@anim/push_left_in" android:outAnimation="@anim/push_left_out" >

android的ImageSwitcher和TextSwitcher

ImageSwitcher: activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_heig

Android真正简单的教程-第十二枪(ViewFlipper实现滑动效果)

直接看代码 1.MainActivity.java: package org.yayun.demo; import android.app.Activity; import android.os.Bundle; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ViewGroup.LayoutParams; import android.view.animation.

使用SafeViewFlipper避免ViewFlipper交替时Crash

使用SafeViewFlipper避免ViewFlipper交替时Crash 柳志超博客 » Program » Andriod » 使用SafeViewFlipper避免ViewFlipper交替时Crash posted in Andriod on 2014/02/19 by liuzc ViewFilpper 是Android官方提供的一个View容器类,继承于ViewAnimator类,用于实现页面切换.当我们界面重叠较多的时候,ViewFilpper 容易崩溃,直接导致程序Crash.

Android 通过ViewFlipper实现广告轮播功能并可以通过手势滑动进行广告切换

为了实现广告轮播功能,在网上找了很多方法,有的效果很好,但是代码太麻烦,并且大多是用的viewpager,总之不是很满意. 于是看了一下sdk有个控件是ViewFlipper,使用比较方便,于是尝试了一下,最终实现了所需效果.在这里与大家分享. 首先看一下效果(主要是布局方面的效果,毕竟手势识别和滑动不太好显示,懒得弄成gif了): 1.布局文件.xml <LinearLayout android:layout_width="fill_parent" android:layout

[Android] TextSwitcher -- 做什么的

TextSwitcher的Java Doc是这样描述自己的: Specialized ViewSwitcher that contains only children of type TextView. A TextSwitcher is useful to animate a label on screen. Whenever setText(CharSequence) is called, TextSwitcher animates the current text out and anim