2011-09-16 83 views
0

我有一個簡單的Android佈局問題;如何將圖像疊加在彼此之上而與屏幕尺寸無關?

拍攝大小爲480x800的圖像 - 任何圖像都可以做,但更喜歡有細節的東西。 讓我們把這個電話叫做large.png

現在,隨機選取一部分圖像並剪切並粘貼到新圖像中,並將其命名爲small.png

然後拍攝兩張圖像,並將大圖像作爲整個屏幕的背景,並嘗試將小圖像放在屏幕上,以便它像拼圖一樣匹配另一張圖像,所以看起來您只有一張圖像圖片。

最簡單的解決辦法是有一個(或者一,如果你設置的背景是FrameLayout的),只是給小ImageView一些邊距值。例如:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:layout_width="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="fill_parent"> 

    <ImageView android:layout_width="fill_parent" 
     android:layout_height="fill_parent" android:background="@drawable/large" 
     android:layout_gravity="top|left" /> 

    <ImageView android:layout_width="wrap_content" 
     android:layout_gravity="top|left" android:layout_height="wrap_content" 
     android:background="@drawable/small" android:layout_marginLeft="100dp" 
     android:layout_marginTop="100dp" /> 

</FrameLayout> 

這應該至少可以用於測試當前設備的分辨率。 當您在具有不同屏幕分辨率的其他設備上使用此解決方案時,或甚至改變當前屏幕的方向時,就會出現問題。

另一個可能的解決方案是有多個LinearLayouts,這將給你權重的力量,而不是使用餘量,但這種解決方案是混亂的,使XML(和內存使用)更大,它並不總是工作它可以爲小圖像創建空格,可能是由於計算限制。

這個問題的最佳解決方案是什麼?我試圖避免使用openGL。

我能找到的唯一可能的解決方案是拍攝小圖像並將其設置爲另一個圖像的蒙版,因此它具有與其他圖像相同的尺寸,並且在其周圍有空白區域。然而,這並不總是可能的,因爲有時我會得到很多圖片來處理,而且沒有人遵循這些規則。


更具體:

我希望把圖像放在另一個圖像的頂部,使他們完全適合,無論顯示什麼畫面。因此,例如,如果您有臉部圖像,並且我有多個眼睛 - 大小相同的圖像,我可以在它們之間切換以改變臉部的眼睛。


也許我應該寫它的開頭:

我希望把圖像放在另一個圖像的頂部,使他們完全適合,無論顯示什麼畫面。例如,如果你有一張臉的圖像,並且我有多個眼睛 - 相同大小的圖像,我可以在它們之間切換以改變臉部的眼睛。


我希望這可以這麼簡單。我試圖用不同的方式來解決它,如果需要,它甚至可以在全球範圍內解決它:我試圖根據原始屏幕和當前屏幕的比例使所有的縮放比例,所以如果它在一個屏幕上正常工作,它應該全部在所有其他屏幕上放大。 通常它可以正常工作,但有時候空的空間來自無處,也許是因爲計算錯誤,或者可能是因爲屏幕之間的縱橫比不同。 (請注意,如果所有尺寸單位均爲px而非dp,則此代碼僅適用,因爲dp會根據不同密度更改px的數量):

public class GlobalPercentageLayoutTestActivity extends Activity 
    { 
    private static final int DEFALT_TARGET_WIDTH =480,DEFALT_TARGET_HEIGHT=800; 
    private int    targetWidth; 
    private int    targetHeight; 
    private static int  screenWidth,screenHeight; 

    public int convertToNewXCoordinate(int x) 
    { 
    int newX=x*screenWidth/this.targetWidth; 
    return newX; 
    } 

    public int convertToNewYCoordinate(int y) 
    { 
    int newY=y*screenHeight/this.targetHeight; 
    return newY; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    DisplayMetrics metrics=new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(metrics); 
    screenWidth=metrics.widthPixels; 
    screenHeight=metrics.heightPixels; 
    this.targetWidth=DEFALT_TARGET_WIDTH; 
    this.targetHeight=DEFALT_TARGET_HEIGHT; 
    View root=getLayoutInflater().inflate(R.layout.main,null); 
    prepare(root); 
    setContentView(root); 
    } 

    private void scaleSingleView(View v) 
    { 
    LayoutParams lp=v.getLayoutParams(); 
    if(lp!=null) 
     { 
     // set margins: 
     if(lp instanceof MarginLayoutParams) 
     { 
     MarginLayoutParams ml=(MarginLayoutParams)lp; 
     int t=ml.topMargin,b=ml.bottomMargin,l=ml.leftMargin,r=ml.rightMargin; 
     ml.setMargins(convertToNewXCoordinate(l),convertToNewYCoordinate(t),convertToNewXCoordinate(r),convertToNewYCoordinate(b)); 
     } 
     // set size: 
     int w=lp.width,h=lp.height; 
     if(w!=ViewGroup.LayoutParams.FILL_PARENT&&w!=ViewGroup.LayoutParams.WRAP_CONTENT&&w!=ViewGroup.LayoutParams.MATCH_PARENT) 
     lp.width=convertToNewXCoordinate(w); 
     if(h!=ViewGroup.LayoutParams.FILL_PARENT&&h!=ViewGroup.LayoutParams.WRAP_CONTENT&&h!=ViewGroup.LayoutParams.MATCH_PARENT) 
     lp.height=convertToNewYCoordinate(h); 
     // set padding: 
     int t=v.getPaddingTop(),b=v.getPaddingBottom(),l=v.getPaddingLeft(),r=v.getPaddingRight(); 
     t=convertToNewYCoordinate(t); 
     b=convertToNewYCoordinate(b); 
     l=convertToNewXCoordinate(l); 
     r=convertToNewXCoordinate(r); 
     v.setPadding(l,t,r,b); 
     } 
    } 

    private void prepare(View v) 
    { 
    scaleSingleView(v); 
    if(v instanceof ViewGroup) 
     { 
     ViewGroup parent=(ViewGroup)v; 
     int numberOfChildren=parent.getChildCount(); 
     for(int i=0;i<numberOfChildren;++i) 
     { 
     View view=parent.getChildAt(i); 
     prepare(view); 
     } 
     } 
    } 
    } 

你們,我不認爲你明白我說明問題,所以我會形容它在一個謎語的方式。

採取下2張圖片,並把它們放在一起使用2個imageViews就像一個謎,使他們適應每個other.notes:

1,最重要的事情:使圖像填充儘可能多的空間可能基於當前的屏幕分辨率,保持所有視圖(邊距,填充,大小)的縱橫比,而不僅僅是imageViews(因爲我可能想要放置其他視圖(甚至佈局)),並使您的解決方案適用於所有可能的分辨率

2.名爲「large.png」的圖片應該在背景中,而名爲「small.png」的圖片應該位於另一張圖片的內部,以便填充其圖案。

3.在孔內不應該有空的空間,以便小圖像應該適合大圖像的整個孔。這是很重要的,因爲我成功實現了縮放,但我無法找出爲什麼會有空的空間(也許是因爲Android上的抽樣問題?),甚至沒有通過線性佈局重量技巧。 這裏是什麼,我一直在使用我在這裏寫的代碼成功的例子: http://imageshack.us/photo/my-images/402/testvk.png/

4.bonus:使它即使在運行時的工作,所以,如果我有具體的利潤率在運行時把一個新的觀點,填充和大小,它會根據屏幕分辨率自動縮放這些屬性。如果太難了,告訴我在新建視圖放入佈局之前/之後應該如何處理。

5.opengl,surfaceView等是偉大的,但不是我在找什麼。我想要一個解決方案,將使用簡單的Android視圖解決任何分辨率。作爲一個例子(我希望這是一個很好的例子),使用你的android網絡瀏覽器瀏覽到一個網站,它的html中沒有任何特殊的移動標籤。您可以看到該網站在您嘗試的所有設備上顯示的都相同,因爲所有內容都根據可用空間展開。

這裏有所有的圖像: http://imageshack.us/g/703/largee.png/

我希望現在大家都明白什麼是我的問題。

+0

您能更具體地瞭解您遇到的問題嗎? – emmby

+0

我添加了一些更多信息,但主持人刪除了它,並在主帖中放了兩次。主持人,因爲我不知道如何下午,請合併更新(你也可以刪除在這裏談論它的部分)。 在任何情況下,我所說的問題是,android不允許自動擴展活動的所有內容,除非您執行一些骯髒的竅門。這實際上是一個缺失的功能,因此邊距和填充沒有多大用處。 也許在Android 4上的情況不會這樣,因爲谷歌正在計劃將平板電腦和其他設備的Android合併。 –

+0

在我的答案中查看我的編輯。也許它會幫助 –

回答

1

你將不得不做,在代碼:

確定顯示維度(或圖像的容器的尺寸)。

然後計算圖像顯示/容器大小的比率。這會爲您提供您需要重新調整疊加圖像大小的比率。

最後使用計算出的比率計算您需要再次放置疊加層的位置的重新定位座標。

你完成了:)

編輯

可以在設置中XML格式的ImageViews參數?

android:adjustViewBounds="true" 
0

我不知道我是否100%理解你正在試圖做的,但如果你想在屏幕上的圖像,太多的控制,那麼你應該考慮SurfaceView,請自帶的LunarLander例子與SDK。

1

它適合我。傳遞兩個位圖圖像以相互重疊。

public static Bitmap overlay(String patho,String patht) { 
    Bitmap bmp1= BitmapFactory.decodeFile(patho); 
    Bitmap bmp2= BitmapFactory.decodeFile(patht); 
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig()); 
    Canvas canvas = new Canvas(bmOverlay); 

    Matrix m=new Matrix(); 
    canvas.drawBitmap(bmp1, m, null); 

    canvas.drawBitmap(bmp2, m,null); 
    return bmOverlay; 
}