Click here to Skip to main content
15,867,308 members
Articles / Mobile Apps / Android

Half circle listview

Rate me:
Please Sign up or sign in to vote.
4.81/5 (44 votes)
4 Apr 2014CPOL2 min read 82.5K   2.7K   46   25
Listview item will be displayed and scrolled in a circle.

Introduction

It is easy and normal to make a list view scroll up and down vertically, like below:

Image 1

But how do we create a list view like that can be scrolled in a segment of a circle, like that:

Image 2

How to do?

Of course, we must customize the view to create a list like that. I decided to use SurfaceView to create this list view. After analysis, the problems will contain:

  • How to draw image in a circle?
  • How to scroll list view in a segment of a circle?

How to draw image in a circle?

Suppose that there is a circle that has the center point (centerX, centerY) and radius r. And point P has angle alpha. It will be specified by the formula below:

  • P(x) = centerX + cos(alpha) *r.
  • P(y) = centerY - sin(alpha) * r.

Based on it, we can easily draw an item in a circle.

How to scroll list view in a segment of a circle?

The problem is when the user is scrolling, how do we update the angle of each item? Exactly, we must specify the scroll angle at scrolling time, then add to the current angle of each item of the list view. To resolve this requirement, I decided to use GestureDetector to control this event. And in this class, I focused on the function below to specify the scroll angle.

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)

Based on e2, distanceX, and distanceY, the scroll angle will be specified as in the picture below:

Image 3

Based on this picture, we give the formula below

Image 4

=> scroll angle = β - α

Using the code

I will create a list of players as a sample, with player images prepared in a resource folder. You can refer to the source code I uploaded.

Java
int[] playerDrawableResourceIds = new int[] { R.drawable.ronaldo,
            R.drawable.zindance, R.drawable.congvinh, R.drawable.huynhduc,
            R.drawable.gerrard, R.drawable.nagatomo, R.drawable.messi,
            R.drawable.minhphuong, R.drawable.neymar, R.drawable.ronaldo_beo,
            R.drawable.ronaldinho, R.drawable.xavi };

How to draw an image in a circle?

At first, create the item class CircleDrawItem of the list view.

Java
public class CircleDrawItem {
    public Bitmap mIconBitmap;
    public double mAngle;
}
  • mIconBitmap: the bitmap of each item of the list view.
  • mAngle: the angle in radian of item. This angle will be updated when scrolling.

Because the circle will be displayed in the left of the screen, the center will have x coordinate as negative number. Besides that, the y coordinate will be in the center of the screen.

Java
mCenterX = (int) (-Global.dp * 200);
mCenterY = (int) (Global.dh / 2.0f);
mRadius = (int) (450 * Global.dp);
mStartAngleInRadian = Math.PI / 4; 

With the value of Global is calculated:

Java
Global.dw = getResources().getDisplayMetrics().widthPixels;
Global.dh = getResources().getDisplayMetrics().heightPixels;
Global.dp = Global.density / 1.5f; 

The circle will keep an array list of CircleDrawItems, with the first item having angle PI/4, and the distance between two items PI/10. The angle of the first item and the distance between two items can be changed based on your requirements.

Java
for (int i = 0; i < playerDrawableResourceIds.length; i++) {
    CircleDrawItem circleDrawItem = new CircleDrawItem();
    circleDrawItem.mIconBitmap = decodeSampledBitmapFromResource(
            getResources(), playerDrawableResourceIds[i], 50, 50);
    circleDrawItem.mAngle = mStartAngleInRadian - i * Math.PI / 10;
    datas.add(circleDrawItem);      
}

I create a thread to draw data items in circle.

C#
protected void draw() {
    Canvas canvas = getHolder().lockCanvas();
    if (canvas == null) {
        return;
    }
    canvas.save();
    canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setAntiAlias(true);

    for (int i = 0; i < datas.size(); i++) {
        canvas.save();
        CircleDrawItem item = datas.get(i);
        double x = mCenterX + Math.cos(item.mAngle) * mRadius;
        double y = mCenterY - Math.sin(item.mAngle) * mRadius;
        canvas.drawBitmap(item.mIconBitmap,
                (int) x - item.mIconBitmap.getWidth() / 2, (int) y
                        - item.mIconBitmap.getHeight() / 2, paint);
        canvas.restore();
    }
    canvas.restore();
    getHolder().unlockCanvasAndPost(canvas);
} 

How to scroll list view in segment of a circle?

Implement a OnGestureListener and override the onScroll() method.

Java
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {
    float tpx = e2.getX();
    float tpy = e2.getY();
    float disx = (int) distanceX;
    float disy = (int) distanceY;
    double scrollAngle = calculateScrollAngle(tpx, tpy, tpx + disx, tpy
            + disy);
    for (int i = 0; i < datas.size(); i++) {
        datas.get(i).mAngle += scrollAngle;
    }
    return true;
}  

And the way to calculate the scroll angle will be:

Java
private double calculateScrollAngle(float px1, float py1, float px2,
        float py2) {
    double radian1 = Math.atan2(py1, px1);
    double radian2 = Math.atan2(py2, px2);
    double diff = radian2 - radian1;
    return diff;
}

History

  • 2013-08-24: Add source code with scroll event.

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

 
Questionhow to change scrolling distane??? Pin
Member 128278762-Nov-16 0:12
Member 128278762-Nov-16 0:12 
Questionclick image to transfer to another activity Pin
Member 1232809716-Feb-16 20:20
Member 1232809716-Feb-16 20:20 
GeneralMy vote of 5 Pin
jayantbramhankar17-Jan-15 0:10
jayantbramhankar17-Jan-15 0:10 
QuestionHow make it to horizontal left to right. .. as it is showing in vertical top to bottom Pin
kiranuday432-Jul-14 18:59
kiranuday432-Jul-14 18:59 
QuestionImage click Pin
wish4only7-Apr-14 23:50
wish4only7-Apr-14 23:50 
AnswerRe: Image click Pin
huyletran9-Apr-14 21:02
huyletran9-Apr-14 21:02 
GeneralRe: Image click Pin
wish4only23-Sep-14 20:32
wish4only23-Sep-14 20:32 
Thanks dear
SuggestionA better way to format the math Pin
Graham Wilson4-Apr-14 6:46
Graham Wilson4-Apr-14 6:46 
Questionhow can i get position of each image on image click ? Pin
Member 1045472521-Dec-13 0:00
Member 1045472521-Dec-13 0:00 
AnswerRe: how can i get position of each image on image click ? Pin
huyletran3-Apr-14 17:52
huyletran3-Apr-14 17:52 
QuestionGood Share Pin
Member 102331991-Oct-13 6:27
Member 102331991-Oct-13 6:27 
GeneralMy vote of 5 Pin
Brian A Stephens27-Sep-13 3:31
professionalBrian A Stephens27-Sep-13 3:31 
GeneralMy vote of 5 Pin
Renju Vinod16-Sep-13 20:38
professionalRenju Vinod16-Sep-13 20:38 
GeneralMy vote of 5 Pin
Shakeel Iqbal9-Sep-13 23:15
Shakeel Iqbal9-Sep-13 23:15 
GeneralMy Vote 5 Pin
Dhruvin Sukhadiya7-Sep-13 7:32
Dhruvin Sukhadiya7-Sep-13 7:32 
GeneralMy vote of 5 Pin
ThatsAlok6-Sep-13 18:40
ThatsAlok6-Sep-13 18:40 
GeneralMy vote of 5 Pin
ridoy5-Sep-13 19:36
professionalridoy5-Sep-13 19:36 
GeneralMy vote of 5 Pin
Anurag Gandhi4-Sep-13 23:46
professionalAnurag Gandhi4-Sep-13 23:46 
QuestionRespect Pin
Андрей Конюшенко4-Sep-13 0:20
Андрей Конюшенко4-Sep-13 0:20 
GeneralMy vote of 5 Pin
Shakeel Iqbal30-Aug-13 6:32
Shakeel Iqbal30-Aug-13 6:32 
GeneralMy vote of 5 Pin
Volynsky Alex30-Aug-13 0:13
professionalVolynsky Alex30-Aug-13 0:13 
GeneralMy vote of 5 Pin
raj ch29-Aug-13 23:39
raj ch29-Aug-13 23:39 
GeneralMy vote of 5 Pin
hjgode29-Aug-13 19:36
hjgode29-Aug-13 19:36 
GeneralMy vote of 5 Pin
Santhoshpettacode26-Aug-13 4:42
professionalSanthoshpettacode26-Aug-13 4:42 
GeneralRe: My vote of 5 Pin
Zin To15-Jan-14 16:25
Zin To15-Jan-14 16:25 

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.