I'm writing an app in Java and I want to place a button randomly in the screen.
I used the Display.getSize(), but it gives me the whole size of the screen including the bottom bar of the return, home and recent activities buttons. So my button which is randomly located in the screen, often is hidden under this bar. How can I take into cosideration this bar in my calculation?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hiding_buttons);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
SCREEN_WIDTH = size.x;
SCREEN_HEIGHT = size.y;
}
public void button_hideButtonClick(View view) {
// init button location to beginning position
view.offsetLeftAndRight(-horizonOffset);
view.offsetTopAndBottom(-verticalOffset);
Random r = new Random();
// generate random pos relative to the screen
horizonOffset = r.nextInt(SCREEN_WIDTH-view.getWidth());
verticalOffset = r.nextInt(SCREEN_HEIGHT-view.getHeight());
// relocate the button randomly
view.offsetLeftAndRight(horizonOffset);
view.offsetTopAndBottom(verticalOffset);
}
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
int dens=dm.densityDpi;
double wi=(double)width/(double)dens;
double hi=(double)height/(double)dens;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);
as explained here
Try this..and let me know if it doesnt work..Will tell you some other options too...
Related
I'm trying to create a number of edit texts programmatically without using XML, but I faced some problems while trying this out. Here is a piece of code:
private void createEditText(int l, int topMargin){
ViewGroup.MarginLayoutParams vlp = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(vlp.width, vlp.height);
layoutParams.setMargins((vlp.leftMargin + l) - vlp.width - vlp.height - 25, topMargin, vlp.rightMargin, vlp.bottomMargin);
final EditText newEditText = new EditText(this);
newEditText.setBackgroundResource(R.drawable.rounded_edittext);
newEditText.setLayoutParams(layoutParams);
linearLayout.addView(newEditText);
}
private void numberOfEditTexts(){
String[] words = Answers.answers[getCurrentLevel()].split(" ");
int l = 0, topMargin = 450;
for(int i = 0; i < words.length - 1; i++){
createEditText(l, topMargin);
l += editText.getLayoutParams().width + 5;
if(i == 0) topMargin -= 560;
}
}
The first function creates an edit text and I send 2 parameteres to it, of which the topMargin is the variable that defines the altitude coordinates of the edit text. So the problem is that this edit text will appear differently on different devices because of their screen sizes.
How can I fix it? How can I avoid setting the position manually?
Thanks in advance.
I think you need to get the screen width and length. Use the percentage of screen size as your margin size.
to get the screen size by pixels,
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Your margin can be some percentage of the height: like 5% or 10% of the screen height. Then it is adjustable.
I am trying to make the ImageView missile1 to spawn at a random y-coordinate on the right edge of the screen and then move it left across the screen until it is off the screen, and finally move it back to a random y-coordinate on the right edge of the screen to repeat the process in an infinite loop. The code I have spawns the image at a totally random x and y coordinate location whenever the activity is restarted, but it doesn't move. Can anybody see why it doesn't move and give a solution to my problem? Some example code will be appreciated.
The thread that generates x and y coordinate values:
public class Missiles extends Thread {
private int height, width, currentscore;
private ImageView missile1, missile2, missile3, missile4, missile5;
Handler updatemissile = new Handler();
int min = 100;
RelativeLayout layout;
int setx1, sety1, setx2, sety2, setx3, sety3, setx4, sety4, setx5, sety5;
private Random rand = new Random();
TextView x, y;
Missiles(int screenheight, int screenwidth, ImageView missile01, ImageView missile02, ImageView missile03,
ImageView missile04, ImageView missile05, RelativeLayout rl, TextView xtext, TextView ytext) {
missile1 = missile01;
missile2 = missile02;
missile3 = missile03;
missile4 = missile04;
missile5 = missile05;
height = screenheight;
width = screenwidth;
layout = rl;
x = xtext;
y = ytext;
}
public void updatevalue(int value) {
currentscore = value;
}
public void run() {
SetMissilePosition position = new SetMissilePosition(missile1, layout, x, y);
updatemissile.post(position);
//width is the width of the screen as height is the height of the screen
while (true) {
setx1 = width;
position.updateX(setx1);
int randomNum = rand.nextInt((height - min) + 1) + min;
sety1 = randomNum;
position.updateY(sety1);
while (setx1 > -50) {
setx1 = setx1 - 1;
position.updateX(setx1);
}
setx1 = width;
position.updateX(setx1);
}
}
}
The Runnable Class:
public class SetMissilePosition implements Runnable{
int x1,y1, updateindicator;
ImageView missile1;
RelativeLayout layout;
TextView x,y;
SetMissilePosition(ImageView missile01, RelativeLayout relativeLayout, TextView xtext, TextView ytext) {
missile1 = missile01;
layout = relativeLayout;
x = xtext;
y = ytext;
}
public void updateX( int setx1) {
x1 = setx1;
updateindicator = 1;
}
public void updateY(int sety1) {
y1 = sety1;
updateindicator = 1;
}
public void run() {
missile1.setImageResource(R.drawable.missileanim);
layout.addView(missile1);
if(updateindicator == 1) {
missile1.setX(x1);
missile1.setY(y1);
x.setText(Integer.toString(x1));
y.setText(Integer.toString(y1));
updateindicator = 0;
}
}
}
If I am being unclear in any way or you need more code such as my MainActivity, please ask. Thanks in advance!
It sounds like you're trying to update the UI thread from off of the UI thread.
If that's the route you want to go, I'd encourage you to take a look at the 'run on ui thread' operation. Essentially, when you want to update layout positions, you can just call getContext().runOnUiThread([runnable]) and that will update your position. See here for more information: https://developer.android.com/training/multiple-threads/communicate-ui.html Some things to bear in mind:
Android runs at 60fps, so you need to make sure you're updating every 16ms or so in order to match in sync with your framerate. Otherwise your speed will be off.
Instead of doing that, why not use a Translate animation: https://developer.android.com/reference/android/view/animation/TranslateAnimation.html
You can set starting and ending x and y coordinates, you can even use them as percentages of screenwidth and length, and set the animation to repeat infinitely. If repeating infinitely won't work because you want to pick new X (or Y) values each time, you can hook something up on the end of the animation to pick new values and restart.
I found the answer myself through lots of trial end error. What I did was Created an activity that extended surface view, added a bitmap to it, updated the images coordinates in a thread, and finally passed the coordinates into another thread which updated the screen 30 times a second.
This question already has answers here:
How can I dynamically set the position of view in Android?
(13 answers)
Closed 6 years ago.
I want myImageView to locate itself somewhere on a random position inside the screen, without pushing textviews away. I found this code in another thread, but I can't get it to work.
myImageView = (ImageView) findViewById(R.id.myImageView);
LinearLayout game = (LinearLayout)findViewById(R.id.game);
int width = game.getWidth();
int height = game.getHeight();
random = new Random();
int x = width;
int y = height;
int imageX = random.nextInt(x-50)+50;
int imageY = random.nextInt(y-100)+100;
myImageView.setX(imageX);
myImageView.setY(imageY);
You can give margin programmatically between certain range, may be you can use device width or height for range. Check this links for setting margin dynamically on run time and get screen dimension.
I Think first get programmatically device size then set image view width & height
WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
hear you get width & height now set image view size
android.view.ViewGroup.LayoutParams layoutParams =myImageView.getLayoutParams();
layoutParams.width = 30;
layoutParams.height = 30;
myImageView.setLayoutParams(layoutParams);
and if you still have a problem to change it's size try to put it inside of a LinearLayout and manipulate the imageView size using the layout params:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30);
myImageView.setLayoutParams(layoutParams);
I want to set margin of Imageview. What I wanted to achieve is to move one image up to some distance. The content of screen is RelativeLayout, in that there is ImageView at left and button at right aligned. Now I want to move image from left to right within the gap between Image and Button in 100 click of button. The code I am following is as below:
private static int count= 1 ;
public void onClick(View view) {
RelativeLayout lay = (RelativeLayout)findViewById(R.id.layout1);
ImageView i1= (ImageView)findViewById(R.id.img1);
ImageButton btn= (ImageButton)findViewById(R.id.iBtn);
int i1Width = i1.getWidth();
int btnWidth = btn.getWidth();
int totalMragine = lay.getWidth() - i1Width - btnWidth ; //the total margine image will move.
int stepSize = (lay.getWidth() - i1Width - btnWidth ) / 100;
int step = stepSize * count++;
Log.i("i1Width ", ""+i1Width );
Log.i("btnWidth ", ""+btnWidth );
Log.i("lay.getWidth()", ""+lay.getWidth());
Log.i("stepSize", ""+stepSize);
Log.i("count", ""+count);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(step, 0, 0, 0);
i1.setLayoutParams(lp);
LinearLayout.LayoutParams lp1 = (LinearLayout.LayoutParams) horse.getLayoutParams();
Log.i("currentMargine", ""+lp1.leftMargin);
if(lp1.leftMargin >= totalMragine ){
Log.i("Result", "maringe over");
}
}
What I wanted to know that the margin I am setting is in Integer but the value for the step is in float. So How to set margin float in LayoutParams? or is there any other way to do this?
you can do one thing calculate distance to move every time as when going to move
distance to move = the rest of length/rest of clicks
of in final step (100th step) it will reach to end with error < . 5px and . 5px is too small )
like in
1st click distance_to_move = 370/100; as round off come 4
2nd click distance_to_move = 366/99; as round off come 4
3rd click distance_to_move = 362/98; as round off come 4
so movemnt will be as in px 44444...3444...3444..3444...
I am trying to change my ImageView size, but I can't seem to change both - width and height. If I just change one of them, then all works correctly, but when I try to change both, only width is changed.
I have the size in dp: width 22 and height 38, and I convert them to px. Is there another way to do so? I have tried many other ways, but they don't seem to work either.
Could someone tell me, what I should do differently?
Here is my code:
public GridLayout gridLayout;
public GridLayout.Spec row = GridLayout.spec(0);
public GridLayout.Spec col = GridLayout.spec(3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridLayout = (GridLayout) findViewById(R.id.gameGrid);
createBlock();
}
public void createBlock() {
ImageView block = new ImageView(this);
block.setImageResource(R.drawable.red);
if (gridLayout != null) {
gridLayout.addView(block, new GridLayout.LayoutParams(row, col));
int width_in_dp = 22, height_in_dp = 38;
final float scale = getResources().getDisplayMetrics().density;
int width_in_px = (int) (width_in_dp * scale + 0.5f);
int height_in_px = (int) (height_in_dp * scale + 0.5f);
ViewGroup.LayoutParams layoutParams = block.getLayoutParams();
layoutParams.width = width_in_px;
layoutParams.height = height_in_px;
block.setLayoutParams(layoutParams);
}
}
Have you tried playing with the block's scaleType? The default is fitCenter but I usually choose centerCrop or fitXY. Here's a good webpage that describes the differences.
You can set the scaleType through ImageView's setScaleType method.