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...
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.
I'm trying to display the text on custom ImageView using canvas.
This is my TextPaint:
mPaint = new TextPaint();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFFFF);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTypeface(tf);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextSize(mSize);
User enters his text in EditText which is converted into String(sText) and then into SpannableString(ssText). That SpannableString is being displayed on the canvas.
This is my onDraw:
int x = this.getWidth() / 2, y = 10;
Editable.Factory fac = Editable.Factory.getInstance();
Editable edit = fac.newEditable(ssText);
DynamicLayout layout = new DynamicLayout(edit, mPaint, (x * 2), Alignment.ALIGN_NORMAL, 1, 0, false);
canvas.translate(x, y);
layout.draw(canvas);
canvas.restore();
Now, I'm taking some strings(mText) as input (one string in one line) from user in EditText of which I have to change color in the already displayed SpannableString(ssText) on the canvas.
for (String line : mText.split("\n")) { // one string one line
if (sText.matches(".*\\b" + line + "\\b.*")) {
int len = line.length();
// get the starting index of String line in sText
for (int i = -1; (i = sText.indexOf(mText, i + 1)) != -1;) {
// change the color of required text in ssText
ssText.setSpan(new ForegroundColorSpan(Color.rgb(r_deep, g_deep, b_deep)), i, (i + len), 0);
}
}
}
After changing the color of ssText as above I again call onDraw on the click of ChangeColor button to diaplay it back on the canvas. But, here what I see is that the position of the ssText on canvas is irregular.
I see this before the click of ChangeColor button:
And this is after click of ChangeColor button:
If the problem is in translate of canvas the I'm also using canvas.restore();
I don't understand what the problem is. Please help!
on xml layout, I have a FrameLayout with no child. Then I add a list buttons programatically into this framelayout by this code below:
private void addNumbers(){ // Numbers is set with random position
for (int i = 1; i < 20; i++) {
Button btn = new Button(this);
btn.setText("" + i);
btn.setId(i);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(50, 50);
int leftMargin = new Random().nextInt(widthScreen - btnSize );
int topMargin = new Random().nextInt(heightScreen - btnSize);
lp.leftMargin = leftMargin;
lp.topMargin = topMargin;
btn.setLayoutParams(lp);
framelayout1.addView(btn);
//framelayout2.addView(btn);
}
}
And some buttons overlap together, I do not want to happen this. How to avoid this problem ? Thanks in advance.
P/s: Sorry I can not upload image from my company, all upload > 4K is reject, please tell me if the question is not clear.
I'm dynamically creating buttons and I want to place them randomly on the screen.
In order to do that, I'm substracting the width of the button from the screen's width.
The thing is, the function button.getWidth() always return 0.
I saw in other posts that people recommended using
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
placeButtonsOnScreen();
}
But even when I'm using it, it doesn't work.
private void placeButtonsOnScreen() {
Random r = new Random();
LinearLayout layout = (LinearLayout) findViewById(R.id.ordered_buttons_layout);
for (int i = 0; i < NUMBER_OF_BUTTONS; i++) {
Button hiddenButton = buttonsArr[i];
// Get random horizontal margin for the button
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
horizontalMargin = r
.nextInt(SCREEN_WIDTH - hiddenButton.getWidth());
layoutParams.setMargins(horizontalMargin, 50, 0, 0);
// Add the button to the screen
layout.addView(hiddenButton, layoutParams);
Log.d("button width",String.valueOf(hiddenButton.getWidth()));
}
}
Any ideas how can I position the buttons on the screen minus their width? Cos right now they get cut off from intersection with the right side of the screen.
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
placeButtonsOnScreen();
}
});
You should use RelativeLayouts and make buttons position according to each other (Aligning of course the one closest to the right side of the screen as alignedToParentRight = true)