Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this questionI have a simple Android layout question;
Take an image that is of size 480x800 - any image will do, but prefer something that has details.
Let's call this call this image large.png
.
Now, take a random part of the image and cut and paste it to a new image and call it small.png
.
Then take both images and put the large image as the background of the whole screen, and try to put the small image on the screen so that it matches the other one like a puzzle, so it appears that you only have one image.
The easy solution would be to have a FrameLayout
with 2 ImageViews
(or one, if you set the background to be of the FrameLayout
), and just give the small ImageView
some margin values. For example:
<?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>
This should work at least for the resolution of your current device that you test on. The problem arises when you use this solution on other devices with different screen resolutions, or even change the orientation of the current one.
Another possible solution is to have multiple LinearLayouts
that will give you the the power of weight instead of using margins, but this solution is messy ,makes the XML (and memory usage) larger, and it doesn't always work as it can create blank spaces for the small image, probably because of calculation limitations.
What is the best solution for this problem? I'm trying to avoid using openGL.
The only possible solution that I could find is to take the small image and set it to be like a mask of the other one , so it has the same size as of the other image and has blank space everywhere around it. This isn't always possible, though, since sometimes I get a lot of images to handle, and none follows these rules.
To be more specific:
I wish to put an image on top of another image, so that they will fit perfectly, no matter what screen they are shown on.
So, for example, if you have an image of a face, and I have multiple eyes-images of the same size, I can switch between them to change the eyes of the face.
maybe i should have written it on the beginning:
i wish to put an image on top of another image, so that they will fit perfectly, no matter what screen they are shown on . so, for example, if you have an image of a face, and i have multiple eyes-images of the same size , i can switch between them for changing the eye of the face .
i wish this was even as simple as this. i tried to solve it in a different way,which will solve it even globally if needed : i tried to make everything scale depending on the ratio of the original screen and the current screen , so if it works fine on one screen, it should all scale up on all other screens. usually it works fine, but sometimes empty spaces come from nowhere , maybe because of calculations errors , or maybe because of the different aspect ratio between the screens. here, check out this code, and please tell me what is wrong (btw, this code only works if all of your dimensions units are in px and not dp , since dp changes the amount of px per different density) .:
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*sc开发者_StackOverflow社区reenWidth/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);
}
}
}
}
you guys, i don't think you understand the problem i'm describing , so i will describe it in a way of a riddle.
take the next 2 images , and put them together using 2 imageViews like a puzzle, so that they will fit each other.notes:
1.the most important thing: make the images fill as much space as possible based on current screen resolution , keep the aspect ratio of all views (margins,padding,size) and not just imageViews (since i might want to put other views as well (even layouts) , and make your solution work on all possible resolutions.
2.the image named "large.png" should be in the background, while the image named "small.png" should be inside the other one so it fills its hole.
3.there should be no empty space created inside the hole , so that the small image should fit the entire hole of the large image. this is important since i succeeded achieving the scaling , but i couldn't find out why there is the empty space (maybe because of a sampling problem on android? ) , not even via weights&linearLayout tricks . here's an example of what i've succeeded using the code i've written here: http://imageshack.us/photo/my-images/402/testvk.png/
4.bonus: make it work even during runtime, so that if i put a new view during runtime with specific margin,padding and size, it will scale those properties automatically according to the screen resolution. if it's too hard, tell me what i should do with the newly created view before/after putting it into the layout.
5.opengl,surfaceView etc are great but are not what I'm looking for. i want a solution that will work on any resolution using the simple android views. as an example (and i hope it's a good example) , use your android web browser to surf to a website that doesn't have any special mobile tags in its html . you can see that the website is shown about the same on all of the devices that you try, since everything is stretched according to the space available.
here are all of the images: http://imageshack.us/g/703/largee.png/
i hope that now everyone will understand what is my question.
You will have to do it in code:
Determine the display dimensions (or the dimensions of the container of the image).
Then calculate the ratio of the image-display/container size. This will give you the ratio by which you need to re-size your overlay image.
Last calculate the re-sized coordinates of the position in which you need to place the overlay again using the calculated ratio.
You are done :)
EDIT
can you set a parameter in your ImageViews in xml?
android:adjustViewBounds="true"
It works for me. Pass two bitmap images to overlay each other.
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;
}
I'm not sure if I 100% understand what you're trying to do, but if you want that much control over images on a screen then you should consider SurfaceView, check out the LunarLander example that comes with the SDK.
精彩评论