Reputation: 5607
I have image and I want it to be full-screen in the layout. Then I want to place icon on a particular place of the image; the problem is that the icon doesn't lie on the same place when I run the application on multiple screen sizes.
The only thing that worked fine is that I used a fixed width and height for the image in the xml layout file. But this is not enough to me I want it to be with the full-screen size eventhough the image is stretched and also on all screen sizes and densities. Anybody has solved this issue?
Actually, I am using the following code:
public class MainActivity extends Activity {
double [] X= {60,100,140};
double [] Y= {65,105,145};
//Parameter for icons on Image
RelativeLayout.LayoutParams [] params;
//Parameter for the Whole Screen
FrameLayout.LayoutParams ScreenParams;
RelativeLayout rl;
ImageView [] iv;
Context _cox;
RelativeLayout.LayoutParams paramss;
ImageView vvv;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_cox = this;
//Screen Density
double Density = getResources().getDisplayMetrics().densityDpi;
Log.v("Density is = ", ""+Density);
//Screen Height*Width
double _ScreenHeight = getResources().getDisplayMetrics().heightPixels;
double _ScreenWidth = getResources().getDisplayMetrics().widthPixels ;
Log.v("Screen Width before = ", ""+_ScreenWidth);
Log.v("Screen Height before = ", ""+_ScreenHeight);
double ScreenHeight = _ScreenHeight * (Density/160);
double ScreenWidth = _ScreenWidth * (Density/160);
Log.v("Screen Width after = ", ""+ScreenWidth);
Log.v("Screen Height after = ", ""+ScreenHeight);
ScreenParams = new FrameLayout.LayoutParams((int)ScreenWidth,(int)ScreenHeight);
rl = (RelativeLayout) findViewById(R.id.rel1);
iv = new ImageView[X.length];
params = new RelativeLayout.LayoutParams[X.length];
Toast.makeText(_cox, "Density is = "+Density, Toast.LENGTH_SHORT).show();
for(int i = 0 ; i<X.length ; i++)
{
Log.v("X before = ", ""+X[i]);
Log.v("Y before = ", ""+Y[i]);
X[i] = X[i]*(Density/160);
Y[i] = Y[i]*(Density/160);
Log.v("X after = ", ""+X[i]);
Log.v("Y after = ", ""+Y[i]);
iv[i] = new ImageView(this);
iv[i].setBackgroundDrawable(getResources().getDrawable(R.drawable.star));
double xx = 21*(Density/160);
double yy = 21*(Density/160);
params[i] = new RelativeLayout.LayoutParams((int)xx,(int)yy);
params[i].leftMargin = (int) X[i];
params[i].topMargin = (int) Y[i];
iv[i].setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(_cox)
.setTitle("")
.setMessage("Image: ")
.setPositiveButton("sdfsdfddddd",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).setNegativeButton("", null).show();
}
});
iv[i].setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float X = event.getX();
float Y = event.getY();
Toast.makeText(getApplicationContext(), "X = "+X+"\n"+"Y = "+Y, Toast.LENGTH_SHORT).show();
return false;
}
});
int arr[] = new int[2];
arr[0]=(int) X[i];
arr[1]=(int) Y[i];
iv[i].getLocationOnScreen(arr);
Toast.makeText(_cox, "", Toast.LENGTH_SHORT).show();
//Add ImageView item to the layout
rl.addView(iv[i], params[i]);
}
rl.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float X = event.getX();
float Y = event.getY();
Toast.makeText(getApplicationContext(), "X = "+X+"\n"+"Y = "+Y, Toast.LENGTH_LONG).show();
return false;
}
});
}
}
And Android xml layout file is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rel1"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content" ___I used fixed length here 250dip___
android:layout_height="wrap_content" ___I used fixed length here 250dip___
android:scaleType="fitXY"
android:src="@drawable/world" />
</RelativeLayout>
Upvotes: 2
Views: 1033
Reputation: 4689
You code manages the screen density but not the screen size.
If you set your background to take the fullscreen, it will be scaled according to the screen size.
You need to compute this scale and apply it to your margins.
But first, I've change the layout to make the backgroung take the fulscreen and be align to the top left corner (scaleType : fitStart)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rel1"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitStart"
android:src="@drawable/ic_launcher" />
</RelativeLayout>
Then you need to compute the applied scale :
private double getScaleForImage( Drawable d) {
int imgHeight = d.getIntrinsicHeight();
int imgWidth = d.getIntrinsicWidth();
double _ScreenHeight = getResources().getDisplayMetrics().heightPixels;
double _ScreenWidth = getResources().getDisplayMetrics().widthPixels ;
double imgRatio = (1.0f * imgWidth) / imgHeight;
double screenRatio = (1.0f * _ScreenWidth) / _ScreenHeight;
double scale = 1.0f;
if(imgRatio < screenRatio)// the scale can be found according to height
{
scale = (1.0f * _ScreenHeight) / imgHeight;
}
else // the scale can be found according to width
{
scale = (1.0f * _ScreenWidth) / imgWidth;
}
return scale;
}
then in the onCreate method :
double scale = getScaleForImage(backgroundDrawable);
and apply it in your computation :
X[i] = X[i]*(Density/160)*scale;
Y[i] = Y[i]*(Density/160)*scale;
Note that my example is using the screen size so it assume that your application runs in fullscreen mode, insert the next code to make it happen :
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Tell me if that helps.
Upvotes: 1
Reputation: 148
Look at this link maybe it will help you
This is multiple sizes of your images:
ldpi: 120dpi
mdpi: 160dpi
hdpi: 240dpi
xhdpi: 320dpi
The conversion formula is as follows:
px = dp * (dpi / 160)
Where px is the final image size in pixels, dp is the desired size in density-independent units, and dpi is the target density.
Simplifying this formula, using the size in pixels of your mdpi images as the baseline:
ldpi = mdpi * 0.75
hdpi = mdpi * 1.5
xhdpi = mdpi * 2.0
Going back to your sample code, if you want a button that is 30dp by 30dp, you should be providing images for each density:
ldpi: 23px x 23px
mdpi: 30px x 30px
hdpi: 45px x 45px
xhdpi: 60px x 60px
Upvotes: 1