Click here to Skip to main content
15,881,281 members
Articles / Mobile Apps

ListView auto scroll horizontally

Rate me:
Please Sign up or sign in to vote.
4.75/5 (6 votes)
5 Sep 2013CPOL4 min read 48.5K   3K   10   6
Develop a list view which auto scrolled horizontally.

Introduction

With my experience, customize a View is really a difficult taskSmile | <img src=. Fortunately, Android supports SurfaceView, which is useful in view customize.

In this article, I guided the way to custom a Half Circle list view. Today, I will also use SurfaceView o custom a auto horizontal scroll view.

Image 2

Background

You should spend time to read SurfaceView document in Android developer website before reading this article.

Using the code

Animation.java

To auto slide list view from right to left, the idea is we will update the coordinate of each item in list view and draw it continuously in a background thread.

How to update the coordinate of each item continuously?

Suppose that, from time t1 to time t2, we must translate item from coordinate x1, to x2. The problem is, at time t, x = ? The formula will be easy:

x = x1 + t * (x2-x1) / (t2-t1)

Base on idea above, I made a simple Animation class which is used to calculate the current value, with below properties:

  • mStartValue: The beginning value when animation starting.
  • mEndValue: The final value when animation ending.
  • mDuration: The duration to change value from mStartValue to mEndValue.
  • mStartTime: The time animation starting. At the time animation is started, it is got by System.currentTimeMillis().
  • mEndTime: The time animation ending. mEndTime = mStartTime + mDuration.

The method to get the current value at specified time will be:

Java
public float getCurrentValue(long currentTime) {
   float currentValue = mStartValue + (currentTime)
                * (mEndValue - mStartValue) / mDuration;
   if (currentTime > mEndTime) {
           currentValue = mEndValue;
   }
   return currentValue;
} 

Extends above class, I made TranslateXAnimation.java

Java
public class TranslateX extends Animation {
    public TranslateX() {
        super(Type.Translate);
    }
}

Offcourse, we can make more Animation such as: FadeAnimation, ScaleAnimation... with the same idea. In this article, I use TranslateXAnimation only.

ImageItem.java

This object is an item of ListView.

Java
private class ImageItem {
     public float x;
     public float y;
     public Bitmap bitmap; 
     public TranslateXAnimation translateX; 
}    
  • x and y: is the coordinate of image item. The coordinate will be updated at real time. Base on x, y, item will be drawn in a thread by using Canvas canvas.drawBitmap(bitmap, x, y, paint);
  • translateX: when start to auto scrolling, item will be executed this animation. It will updated the x at runtime:

Java
x = translateX.getCurrentValue(System.currentTimeMillis() - translateX.mStartTime);

And item will be drawn by Canvas.

Java
canvas.drawBitmap(bitmap, x, y, paint);    

AutoHorizontalScrollView.java

This class is extends from SurfaceView which keeps an array list of ImageItem.

How to auto scroll for each 2 seconds?

I keep a variable startDisplayTime in this list view with idea:

  • From the first time AutoHorizontalScrollView is being displayed, startDisplayTime = System.currentTimeMillis().
  • When runtime, if <span style="font-size: 14px;"> </span>^__em style="font-size: 14px;">startDisplayTime >= 2 seconds,
    • Start auto scroll.
    • Update startDisplayTime = System.currentTimeMillis()

How to looping?

Looping means that, when the last item is being began to display from the right, the next right item will be the first item:)

If we have ITEM_WIDTH is the width of each list item, we will update its x coordinate:

Java
if (item.x <= -ITEM_WIDTH) {
  item.x = VIEW_WIDTH - 2 * ITEM_WIDTH;
}  

How to draw list item?

It is a easy work, because we only draw all item of list in background thread continuously.
Java
Canvas canvas = getHolder().lockCanvas();
if (canvas == null) {
   return; 
}
canvas.save();
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
for (int i = 0; i < items.size(); i++) {
  ImageItem item = items.get(i);
  item.draw(canvas);
}
canvas.restore();
getHolder().unlockCanvasAndPost(canvas); 

ImageItem.draw()

Java
public void draw(Canvas canvas) {
            canvas.save();
            if (translateX != null && !translateX.isEnded()) {
                x = translateX.getCurrentValue(System.currentTimeMillis()
                        - translateX.mStartTime);
            } else {
                // translateX = null;
            }
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setFilterBitmap(true);
            paint.setAntiAlias(true);
            canvas.drawBitmap(bitmap, x, y, paint);
            canvas.restore();
        }  

I put here the class diagram for easy understanding.

Image 3

Advance animation

20130906.

I have finished the article to guide the way to execute animation in SurfaceView. Base on the animation in this article, I will apply it to improve function of this list view? What do you think if I added more requirement as below:

  • All item will be has alpha is 100 at default.
  • The last right item will be scale from 1 to 1.5 and its alpha will be changed from 100 to 255 when slide from the right to the left.
  • The center item will be scale down 1.5 to 1 and its alpha will be changed from 255 to 100 when slide from the right to the left.
Base on Animation class, it is easy to make the ScaleXAnimation, ScaleYAnimation, AlphaAnimation.

The ImageItem will be added more properties:

  • scaleX: keep the scale ratio
  • scaleY: keep the scale ratio
  • alpha: Keep alpha value for fade in/out animation.
  • animations: The array list of animation which is executed.

With AutoHorizontalScrollView.java, I added:

  • firstItemPos: The position in list items of the first item in the left. Default is 0 from starting.
  • secondItemPos: The position in list items of the first item in the center. Default is 1 from starting.
  • thirdItemPos: The position in list items of the first item in the center. Default is 2 from starting.

Animation

When slide, if the position is thirdItemPos , beside the TranslateXAnimation, add to it:

ScaleXAnimation

Java
ScaleXAnimation scaleX = new ScaleXAnimation();
scaleX.mStartTime = System.currentTimeMillis();
scaleX.mDuration = 500;
scaleX.mEndTime = System.currentTimeMillis() + 500;
scaleX.mStartValue = 1f;
scaleX.mEndValue = 1.5f;
item.animations.add(scaleX);

ScaleYAnimation

Java
ScaleYAnimation scaleY = new ScaleYAnimation();
scaleY.mStartTime = System.currentTimeMillis();
scaleY.mDuration = 500;
scaleY.mEndTime = System.currentTimeMillis() + 500;
scaleY.mStartValue = 1f;
scaleY.mEndValue = 1.5f;
item.animations.add(scaleY);

And AlphaAnimation

Java
AlphaAnimation alpha = new AlphaAnimation();
alpha.mStartTime = System.currentTimeMillis();
alpha.mDuration = 500;
alpha.mEndTime = System.currentTimeMillis() + 500;
alpha.mStartValue = 150;
alpha.mEndValue = 255;
item.animations.add(alpha);  

And if it is the center position secondItemPos, add to it

ScaleXAnimation

Java
ScaleXAnimation scaleX = new ScaleXAnimation();
scaleX.mStartTime = System.currentTimeMillis();
scaleX.mDuration = 500;
scaleX.mEndTime = System.currentTimeMillis() + 500;
scaleX.mStartValue = 1.5f;
scaleX.mEndValue = 1f;
item.animations.add(scaleX);

ScaleYAnimation

Java
ScaleYAnimation scaleY = new ScaleYAnimation();
scaleY.mStartTime = System.currentTimeMillis();
scaleY.mDuration = 500;
scaleY.mEndTime = System.currentTimeMillis() + 500;
scaleY.mStartValue = 1.5f;
scaleY.mEndValue = 1f;
item.animations.add(scaleY);

And AlphaAnimation

Java
AlphaAnimation alpha = new AlphaAnimation();
alpha.mStartTime = System.currentTimeMillis();
alpha.mDuration = 500;
alpha.mEndTime = System.currentTimeMillis() + 500;
alpha.mStartValue = 255;
alpha.mEndValue = 100; 

And 3 three position will be updated as below:

Java
thirdItemPos++;
if (thirdItemPos == items.size()) {
   thirdItemPos = 0;
}
secondItemPos++;
if (secondItemPos == items.size()) {
    secondItemPos = 0;
}
firstItemPos++;
if (firstItemPos == items.size()) {
   firstItemPos = 0; 
}    

Draw

To draw ItemImage, do as below:

Java
for (int i = 0; i < animations.size(); i++) {
                Animation animation = animations.get(i);
                if (animation.isStarted()) {
                    if (!animation.isEnded()) {
                        if (animation.mType == Type.TranslateX) {
                            x = animation
                                    .getCurrentValue(System.currentTimeMillis()
                                            - animation.mStartTime);
                        } else if (animation.mType == Type.ScaleX) {
                            scaleX = animation
                                    .getCurrentValue(System.currentTimeMillis()
                                            - animation.mStartTime);
                        } else if (animation.mType == Type.ScaleY) {
                            scaleY = animation
                                    .getCurrentValue(System.currentTimeMillis()
                                            - animation.mStartTime);
                        } else if (animation.mType == Type.Alpha) {
                            alpha = (int) animation
                                    .getCurrentValue(System.currentTimeMillis()
                                            - animation.mStartTime);
                        }
                    } else {
                        animations.remove(i);
                    }
                }
            }
            paint.setAlpha(alpha);
            canvas.scale(scaleX, scaleX, x, y);
            canvas.drawBitmap(bitmap, x, y, paint); 

You can download AdvandeHorizontalAutoScrollListView.zip to view the result. 

HISTORY

20130905: First created. 

20130906: After finishing the article about SurfaceView animation add alpha, scaleX, scaleY animation to it. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Vietnam Vietnam
I'm Java developer.
I started Java web coding from 2007 to 2010. After that, I began to develop Android from 2010 to now.
In my thinking, sharing and connecting is the best way to develop.
I would like to study more via yours comments and would like to have relationship with more developers in the world.

Comments and Discussions

 
QuestionVertical Pin
Santosh Kumar9-May-16 22:04
Santosh Kumar9-May-16 22:04 
QuestionHorizontal Scrollable listview Pin
Member 119559823-Sep-15 0:51
Member 119559823-Sep-15 0:51 
QuestionChanges require for images(Item) having different Width and Height Pin
Member 1038539021-Jan-15 2:14
Member 1038539021-Jan-15 2:14 
GeneralThanks you Pin
futurejo7-Jan-15 20:19
futurejo7-Jan-15 20:19 
GeneralHi huyletran Pin
Member 1053007716-Jan-14 23:26
Member 1053007716-Jan-14 23:26 
GeneralMy vote of 5 Pin
Volynsky Alex5-Sep-13 0:28
professionalVolynsky Alex5-Sep-13 0:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.