2013-04-09 105 views
10

我需要一些幫助來理解在Android中繪製到畫布上的項目時滾動的基礎。假設我想創建一個時間軸,其中0的時間是可視化的頂部,隨着時間的增加,時間軸繼續呈現在先前點的下方。如果我想在Android上渲染,我知道我可以簡單地通過覆蓋onDraw()在畫布上創建一堆項目。但是,讓我們假設可視化比屏幕允許的更大。在大型畫布上滾動

例如,在下面的第一張圖片中,大黑盒包含整個畫布,因爲我呈現它。我創建了一條垂直向上和向下運行的藍線以及幾個黃色,綠色和藍色矩形。紅色框表示正在渲染可視化的Android屏幕。當它最初打開時,所有項目都被繪製,但只有紅色框中包含的項目出現在屏幕上。

Before_Scroll

現在,如果用戶向下滾動,最初出現下面的紅框中的項目在視野中,而已經沒有了紅色框的範圍的項目不再visable,作爲代表第二張照片。

After_Scroll

我相信我需要使用scrollables但我很丟了怎麼辦等等。我已閱讀此頁http://developer.android.com/training/custom-views/custom-drawing.html解釋如何創建您自己的客戶圖像和此頁面http://developer.android.com/training/custom-views/making-interactive.html解釋如何使UI交互,但我認爲我錯過了一些東西。

示出該問題的示例代碼(這是基本的,假定有邏輯口述WHERE的框/線去等)如下:

package com.example.scrolltest; 

import com.example.scrolltest.Draw; 

import android.os.Bundle; 
import android.app.Activity; 
import android.graphics.Color; 

public class MainActivity extends Activity { 
    Draw draw; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    draw = new Draw(this); 
    draw.setBackgroundColor(Color.WHITE); 
    setContentView(draw); 
    } 
} 

package com.example.scrolltest; 


import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.view.View; 


public class Draw extends View { 
    Paint paint = new Paint(); 

    public Draw(Context context) { 
     super(context);    
    } 

    @Override 
    public void onDraw(Canvas canvas) { 

     paint.setColor(Color.GREEN); 
     canvas.drawRect(30, 30, 90, 200, paint); 
     paint.setColor(Color.BLUE); 

     canvas.drawLine(100, 20, 100, 1900, paint); 

     paint.setColor(Color.GREEN); 
     canvas.drawRect(200, 2000, 400, 3000, paint); 
     } 
} 

但我無法弄清楚的是,我如何使用滾動條向下滾動到屏幕外的矩形。我也不確定,如果我開始正確或應該使用drawables,而不是...

回答

20

簡單的方法(如果所需的高度不是很大)。

使用ScrollView並在其中添加您的繪製視圖。在onMeasure中計算該視圖所需的高度。

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

draw = new Draw(this); 
draw.setBackgroundColor(Color.WHITE); 
ScrollView scrollView = new ScrollView(this); 
scrollView.addView(draw); 
setContentView(scrollView); 
} 

public class Draw extends View { 
     Paint paint = new Paint(); 

     public Draw(Context context) { 
      super(context);    
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      // Compute the height required to render the view 
      // Assume Width will always be MATCH_PARENT. 
      int width = MeasureSpec.getSize(widthMeasureSpec); 
      int height = 3000 + 50; // Since 3000 is bottom of last Rect to be drawn added and 50 for padding. 
      setMeasuredDimension(width, height); 
     } 

     @Override 
     public void onDraw(Canvas canvas) { 

      paint.setColor(Color.GREEN); 
      canvas.drawRect(30, 30, 90, 200, paint); 
      paint.setColor(Color.BLUE); 

      canvas.drawLine(100, 20, 100, 1900, paint); 

      paint.setColor(Color.GREEN); 
      canvas.drawRect(200, 2000, 400, 3000, paint); 
      } 
    } 
+0

怎樣才能加平移功能畫布? – 2016-04-26 13:11:59

0

另一種方法是使用偏移量X/Y值。

您如何處理偏移值取決於您,儘管我更喜歡使用我稱之爲Camera的類。訪問應該是靜態的。

public void render(Canvas c){ 
    c.drawRect(100 - offsetX, 100 - offsetY, 120 - offsetX, 120 - offsetY, Paints.BLUE); 

} 

而要平移畫布:

float x, y; 
@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    if(ev.getAction() == MotionEvent.ACTION_DOWN){ 
     x = ev.getX(); 
     y = ev.getY(); 
    }else if (ev.getAction() == MotionEvent.ACTION_MOVE) { 
     float currX = ev.getX(); 
     float currY = ev.getY(); 

     float newOffsetX = (x - currX), 
       newOffsetY = (y - currY); 
     //The next two if-statements are to add sensitivity to the scrolling. 
     //You can drop these if you don't plan on having touch events 
     //with pressing. Pressing works without this as well, but the canvas may move slightly 
     //I use DP to handle different screen sizes but it can be replaced with pixels. c is a context-instance 
     if (newOffsetY < Maths.convertDpToPixel(2, c) && newOffsetY > -Maths.convertDpToPixel(2, c)) 
      newOffsetY = 0; 

     if (newOffsetX < Maths.convertDpToPixel(2, c) && newOffsetX > -Maths.convertDpToPixel(2, c)) 
      newOffsetX = 0; 
     offsetX += newOffsetX; 
     offsetY += newOffsetY; 
     x = ev.getX(); 
     y = ev.getY(); 
    } 

    return true; 

} 

和樣本相機類:

public class Camera{ 

    public static float offsetX, offsetY; 
    //The constructor. ix and iy is the initial offset. Useful if you are creating a game and need to change the initial offset to center around a starting position. 
    //Most of the time it will be enough to set the values to 0 
    public Camera(float ix, float iy){ 
     this.offsetX = ix; 
     this.offsetY = iy; 
    } 

}