2011-09-16 45 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; 
}