Android使用ListView實現圓弧列表例子

來源:互聯網
上載者:User
簡介
製作一個垂直列表非常常見也很簡單,如下所示:
但是我們如何建立一個可以圓弧型的列表呢?就像下面的效果:
如何??
當然,我們必須定製一個視圖來建立一個那樣的列表。我決定使用SurfaceView 來建立這個列表視圖。經過分析之後,該問題包含如下內容:
  • 如何在圓弧內繪製圖片?
  • 如何讓列表按照圓弧的軌跡滑動?
如何在圓弧內繪製圖片?
假設有一個帶中心點的圓弧(centerX, centerY)和半徑r。一個點P有相對於中心點的角度。那麼下面的公式就可以描述出該問題:
  • P(x) =  centerX + cos( alpha) *r.
  • P(y) = centerY - sin(alpha) * r.
基於此,我們可以很方便的在圓弧上繪製一個清單項目.
如何在圓弧上滑動列表視圖?
當使用者滑動列表時,會出現該問題。我們如何更新每個清單項目的角度?確切的說,我們必須詳細記錄滑動的角度。之後添加到當前列表視圖中每一項的角度中。為瞭解決這個要求。我決定使用GestureDetector 來控制這個事件。同時,在這個類中,我主要考慮的是如何詳細記錄滑動的角度(函數名如下).
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
基於e2, distanceX, 和 distanceY,滑動的角度將被詳細記錄到下面的圖片中:
基於此圖片,我們給出了下面的公式
=> scroll angle = β - α
代碼

我講建立一個展示的列表作為範例。列表中的圖片來自於資源檔夾。你可以參考我上傳的原始碼.

 代碼如下 複製代碼

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 };


如何在圓弧中繪製圖片?

首先,建立一個清單項目的類CircleDrawItem.

 代碼如下 複製代碼
 
public class CircleDrawItem {
    public Bitmap mIconBitmap;
    public double mAngle;
}

    mIconBitmap: 清單項目的位元影像.

    mAngle: 每個清單項目的弧度。這個弧度在旋轉清單項目的時候會被更新.

因為該圓弧將被在螢幕左側展示。所以圓心將會把X座標設定為負數。同時,Y座標將被設定為螢幕中心的Y座標值.
 

 代碼如下 複製代碼
mCenterX = (int) (-Global.dp * 200);
mCenterY = (int) (Global.dh / 2.0f);
mRadius = (int) (450 * Global.dp);
mStartAngleInRadian = Math.PI / 4;


用Global 的值進行計算:

 代碼如下 複製代碼
 
Global.dw = getResources().getDisplayMetrics().widthPixels;
Global.dh = getResources().getDisplayMetrics().heightPixels;
Global.dp = Global.density / 1.5f;


這個圓弧保有CircleDrawItem的數組列表。第一項的弧度為PI/4。每個清單項目的間隔是PI/10.第一項的弧度和兩項間的弧度可以根據你的需求進行修改。

 

 代碼如下 複製代碼
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);     
}

我建立了一個線程,以便將每個資料項目繪製到圓弧中。

 代碼如下 複製代碼
 
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);
}

如何讓列表在圓弧中滑動?

引用OnGestureListener 並重載onScroll()函數。

 代碼如下 複製代碼

 
@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;
}

計算滑動角度的方法如下:

 代碼如下 複製代碼

 
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;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.