2011-06-27 58 views
1

(這是Android: How do you scale multiple views together?有些一個後續)比例的視圖及其分層的子視圖相對

我的任務是端口在Android的iPhone/iPad應用,它由在其上的動畫是分層的簡單圖像視圖的在絕對位置頂部。雖然這在iOS上聽起來相當簡單,但您只需要定位幾種可能的屏幕尺寸,但Android會變得相當混亂。

我目前的設置是這樣的:一個RelativeLayout,其中我將主要(背景)圖像放置在左側= 0,頂部= 0和多個ViewFlipper實例用作「動畫容器」,相對於左上角父佈局實例。

這種方法有兩個基本問題:

  1. 所定位的「動畫」是錯誤放置儘快佈局的實際尺寸並不主要背景圖像的大小相匹配。

  2. 定位的「動畫」的尺寸也很大,因爲由於它們通常在自己周圍有「足夠的空間」,所以Android不會將它們縮放到RelativeLayout中(它也不會將它們縮放到原始背景。

由於動畫本身必須是交互式的,它不是一個解決方案,其具有的尺寸與主(背景)圖像相同的透明層上放置和位置所有的動畫,因爲它們會重疊互相之間,只有最上面纔會互動。

我想到了differen牛逼的解決方案:

  1. 讓主圖像的比例因子,我可以檢索其measuredWidthmeasuredHeight並設置該到原始width和視圖height的關係。然後我會使用這個比例因子進行自定義定位並最終進行自定義縮放。但是,顯然measuredWidth/-Height屬性僅在onMeasure()調用期間設置,並且在構建組件樹後調用,因此我不知道該解決方案是否可行。

  2. 執行我自己的佈局管理器並相應地縮放/放置視圖。我看了一下RelativeLayout的實現,但不得不承認onMeasure()方法讓我有點害怕。

你會在我的情況下做什麼?我還沒有考慮到什麼嗎?

在此先感謝。

回答

1

好了,回答我的問題 - 這是我解決問題的方式:

  1. 我放置在背景圖像上的我ImageView頂部與ImageView.setScaleType(ScaleType.FIT_START)
  2. 我計算我的背景的比例因子圖像像這樣:
 
    WindowManager mgr = (WindowManager) context 
       .getSystemService(Context.WINDOW_SERVICE); 
    DisplayMetrics metrics = new DisplayMetrics(); 
    mgr.getDefaultDisplay().getMetrics(metrics); 
    Drawable image = context.getResources().getDrawable(R.drawables.someImage); 
    float scale = metrics.widthPixels/(float) image.getIntrinsicWidth(); 
  1. 最後,我用這個尺度在加載覆蓋到位置和比例適當的查看自定義的ImageView類:
 
    public class OverlayImage extends ImageView 
    { 
     private int imgWidth, imgHeight; 
     private final float scale; 

     public OverlayImage(Context context, int xPos, int yPos, float scale) 
     { 
      super(context); 
      this.scale = scale; 

      LayoutParams animParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 
        LayoutParams.WRAP_CONTENT); 
      animParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      animParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
      animParams.leftMargin = (int) (scale * xPos); 
      animParams.topMargin = (int) (scale * yPos); 
      setLayoutParams(animParams); 

      Drawable dr = context.getResources().getDrawable(R.id.someImage); 
      setBackgroundDrawable(dr); 
      imgWidth = dr.getIntrinsicWidth(); 
      imgHeight = dr.getIntrinsicHeight(); 
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
     { 
      setMeasuredDimension((int) (scale * imgWidth), 
        (int) (scale * imgHeight)); 
     } 
    } 
+1

有趣的東西。我認爲這是一種相關性,我認爲這是一個可縮放的RelativeLayout,我正在嘗試做一些短時間的事情。我的原始問題和我的最終解決方案記錄在這裏:http://stackoverflow.com/questions/6378904/extending-relativelayout-and-overriding-dispatchdraw-to-create-a-zomable-view – Trevor

+0

事實上,你的解決方案是更好的工程比我的。感謝指針! –

0

我最近需要做類似的東西,我也只好端口一個iPad應用程序到Android,屏幕上有許多圖片必須在特定的地點。

我解決了這個稍微不同,絕對佈局,並貫穿所有的意見,並設置每個的協調和大小。

//This gets the scale of the screen change: 
DisplayMetrics displaymetrics = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
Drawable image = getResources().getDrawable(R.drawable.background_image); 
float scaleW = displaymetrics.widthPixels/(float)image.getIntrinsicWidth(); 
float scaleH = displaymetrics.heightPixels/(float)image.getIntrinsicHeight(); 

//And this scales each view accordingly: 
for(int i = 0; i < mainLayout.getChildCount(); i++) 
{ 
    View v = mainLayout.getChildAt(i); 
    v.setLayoutParams(new AbsoluteLayout.LayoutParams(
      Math.round(scaleW * v.getMeasuredWidth()), 
      Math.round(scaleH * v.getMeasuredHeight()), 
      Math.round(scaleW * ((AbsoluteLayout.LayoutParams)v.getLayoutParams()).x), 
      Math.round(scaleH * ((AbsoluteLayout.LayoutParams)v.getLayoutParams()).y))); 
}