Android - Make Sure ImageView Stays on Screen - java

I have a Android project where I have an ImageView that moves to the left every time a button is pressed using
tButton.setOnTouchListener(new RepeatListener(10, 10, new View.OnClickListener()
{
#Override
public void onClick(View view)
{
player1.setX(player1.getX() - 1);
}
}));
I don't want this ImageView to leave the screen, and so I've tried adding another ImageView to the edge, and tried using
tButton.setOnTouchListener(new RepeatListener(10, 10, new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Rect p1 = new Rect();
player1.getHitRect(p1);
Rect sL = new Rect();
lSide.getHitRect(sL);
if(Rect.intersects(p1, sL))
{
player1.setX(player1.getX() + 100);
}
else
{
player1.setX(player1.getX() - 1);
}
}
}));
The problem is that after the two objects interest, the onClick method never seemed to get called again. Is there something that I'm forgetting to do, or is there an easier way to solve this problem?
Thanks

There's an easier way to solve the problem. Use imageView.getLocationOnScreen() to get the x and y position of the view on screen. Then you can check and see if moving it again would cause you to have a negative X (move off the screen to the left) or if X+imageView.getWidth()>screen_width (move off to the right).

Related

android imageview onclick behaviour

Can you create different actions for clicking on the same ImageView but different parts? Say I have an ImageView and I want for it to act differently if I click on the top of the ImageView and differently if I click on the middle part of the ImageView . Can I achieve this in android
The best way is to add an OnTouchListener to the view and handle click event by yourself related to the touch coordinate.
But if you need an easy way which I don't suggest because it can lead to performance issue you can add transparent views on top of your ImageView and add different OnClickListener for them.
if you have fixed sections in your imageview you can use a frame layout and add 3(for example) transparent views on your imageview and then set click listeners on those views.
but if you have dynamic sections you can handle it by combining onTouchListener and onClickListener, for example :
// just store the touch X,Y coordinates
View.OnTouchListener touchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// save the X,Y coordinates
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
lastTouchDownXY[0] = event.getX();
lastTouchDownXY[1] = event.getY();
}
// let the touch event pass on to whoever needs it
return false;
}
};
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// retrieve the stored coordinates
float x = lastTouchDownXY[0];
float y = lastTouchDownXY[1];
// use the coordinates for whatever or check the clickable areas
Log.i("TAG", "onLongClick: x = " + x + ", y = " + y);
}
};
I think the best way for this is that you declare a frameLayout as parent view then you can declare views on your imageView then clicking each view will perform what you want.

How to set ImageView permanently at a position after TranslateAnimation

I referenced the other questions but couldn't find a solution, also I am fairly new to programming.
So I implemented a TranslateAnimation on my ImageView but once the animation ends it returns to its original position. I used Override onAnimationEnd but that doesn't seem to work. Can someone figure out what should I be doing?
public class PackAnimation extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pack_animation);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
String s = getIntent().getStringExtra("CHOICE");
final ImageView pandya = (ImageView) findViewById(R.id.pandya);
final int amountToMoveRight = 600;
final int amountToMoveDown = 0;
TranslateAnimation anim = new TranslateAnimation(0, amountToMoveRight, 0, amountToMoveDown);
anim.setDuration(100);
anim.setAnimationListener(new TranslateAnimation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation)
{
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)pandya.getLayoutParams();
params.topMargin += amountToMoveDown;
params.leftMargin += amountToMoveRight;
pandya.setLayoutParams(params);
}
});
pandya.startAnimation(anim);
}
}
You can use anim.setFillAfter(true) to the TranslateAnimation and get the button stay at the new position, but the button clicks will not work at the new position.
So use ViewPropertyAnimator or ObjectAnimator. These are property animation and will change the position of the View, whereas the TranslateAnimation is View animation and will not change the actual property of the View.
For example, using ViewPropertyAnimator:
pandya.animate()
.translationX(amountToMoveRight)
.translationY(amountToMoveDown);
Refer the blog for more info:
Finally, the previous animations changed the visual appearance of the
target objects... but they didn't actually change the objects
themselves. You may have run into this problem. Let's say you want to
move a Button from one side of the screen to the other. You can use a
TranslateAnimation to do so, and the button will happily glide along
to the other side of the screen. And when the animation is done, it
will gladly snap back into its original location. So you find the
setFillAfter(true) method on Animation and try it again. This time the
button stays in place at the location to which it was animated. And
you can verify that by clicking on it - Hey! How come the button isn't
clicking? The problem is that the animation changes where the button
is drawn, but not where the button physically exists within the
container. If you want to click on the button, you'll have to click
the location that it used to live in. Or, as a more effective solution
(and one just a tad more useful to your users), you'll have to write
your code to actually change the location of the button in the layout
when the animation finishes.
Use anim.setFillAfter(true); and it will remain on the final position after the end of animation.

Loop through each child element and compare its text in java

I am trying to build an android app that gets some questions from a database and its possible answers (the answers are created dynamically as UI buttons). What I have managed so far is that once the user clicks on an answer, if the answer is right the button's colour becomes green, and if the answer is wrong the colour becomes red. What I want to achieve is in case the answer was wrong, change the button's colour to red and find the button with the correct answer and change it's colour to green. I am currently trying to do this by looping through every child element of the clicked button's parent, and comparing its text with the right answer given from the database. This is what my code looks like:
final TableRow textRow = new TableRow(this);
textRow.addView(questionText, rowParamsQuestions);
layout.addView(textRow, layoutParams);
for(final String option : currentQuestion.getOptions())
{
final Button button = new Button(this);
button.setText(option);
button.setTextSize(16);
button.setBackgroundResource(R.drawable.rounded_shape);
button.setTextColor(Color.WHITE);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button clicked = (Button) v;
if (!answeredQuestions.containsKey(currentQuestion)) {
answeredQuestions.put(currentQuestion, clicked.getText().toString());
if (clicked.getText().equals(currentQuestion.getAnswer())) {
clicked.setBackgroundResource(R.drawable.right_answer);
} else {
clicked.setBackgroundResource(R.drawable.wrong_answer);
for (int i = 0; i < textRow.getChildCount(); i++) {
View child = textRow.getChildAt(i);
if (child instanceof Button) {
if (((Button) child).getText().equals(currentQuestion.getAnswer())) {
child.setBackgroundResource(R.drawable.right_answer);
}
}
}
}
Thank you very much!

Android GridLayout get row/column

I have a 3x3 GridLayout with buttons. These buttons have a onTileClicked() listener. Now I want to get the position of the clicked button in the grid. Here is my code:
public void onTileClicked(View view) {
Button button = (Button) view;
GridLayout.LayoutParams params = (LayoutParams) button.getLayoutParams();
}
But how can i get the row and column of the clicked button? There is params.columnSpec but I don't know what to do with this...
There is no direct way to get the position of the cell. However, you can calculate the position of the clicked button assuming you know the number of columns and rows in the onItemClick listener:
public void onItemClick(AdapterView parent,
View v, int position, long id)
{
int row_no=position/3;
int col_no=position%3;
.
.
}
Thanks for your answer AmmarCSE, but I solved the broblem by just doing something like this:
public void onTileClicked(View view) {
Button button = (Button) view;
if(button.getId()==R.id.btn00)onTileClicked(0, 0, button);
else if(button.getId()==R.id.btn01)onTileClicked(0, 1, button);
else if(button.getId()==R.id.btn02)onTileClicked(0, 2, button);
else if(button.getId()==R.id.btn10)onTileClicked(1, 0, button);
else if(button.getId()==R.id.btn11)onTileClicked(1, 1, button);
else if(button.getId()==R.id.btn12)onTileClicked(1, 2, button);
else if(button.getId()==R.id.btn20)onTileClicked(2, 0, button);
else if(button.getId()==R.id.btn21)onTileClicked(2, 1, button);
else if(button.getId()==R.id.btn22)onTileClicked(2, 2, button);
}
This may be old, but i also looked for a solution and still did not find it.
I needed to make multiple lines of button depending on users choice for a game. Using ID's was not possible because the number of buttons could vary from 2x2 to 9x9.
My button did not need to have a caption, so here is what i did:
layout = (GridLayout) findViewById(R.id.layoutPrincipal);
context = this;
for(int i=0;i<rowCount;i++){
for(int j=0;j<columnCount;j++){
Button mButon= new Button(this);
mButon.setText(""+i+""+j);
mButon.setTextColor(Color.TRANSPARENT);
mButon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button button = (Button) v;
//button.getText() allows me to retrieve the coordinates.
button.getText()
}
});
layout.addView(mButon);
}
}
Of course this won't work if you need a text on your button. Maybe you could use a tag?
I am facing the same problem and currently the only solution that makes me comfortable is to modify the class and add whatever information you need.
My example is
class ImageView extends android.widget.ImageView {
public ImageView(Context context) {
super(context);
}
//the position of the plane head.
int xPos,yPos;
public void setPosInGrid(int x,int y) {
xPos=x;yPos=y;
}
public int[] getPosInGrid() {
int[] pos=new int[2];
pos[0]=xPos;
pos[1]=yPos;
return pos;
}
}
And now we can use this additional functionality. We can also rewrite the setLayoutParams and integrate the setPosInGrid() into it.
No modification of other codes is required except when you want an ordinary ImageView just use the full identifier "androi.widget.ImageView".

How to stop the animation when required and start it immediately in android

I am new to android and I need help.
I want my image which is falling from the top of screen to get invisible when I click a button on the keyboard which has the same tag as the image. Although I have implemented the above points a problem arises when I want to show the next animation again immediately after the previous image gets invisible. This is my code for animation.
public void startAnimation(final ImageView aniView)
{
animator= ValueAnimator.ofFloat(0 ,.85f);
animator.setDuration(Constants.ANIM_DURATION);
animator.setInterpolator(null);
//generation of random values
Random rand = new Random();
index = rand.nextInt((int) metrics.widthPixels);
//for debugging
i = Integer.toString(index);
Log.e(" index is :", i);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation)
{
float value = ((Float) (animation.getAnimatedValue())).floatValue();
aniView.setTranslationX(index);
aniView.setTranslationY((height+ (50*mScale))*value);
//aniView.setTranslationY(height);
}
});
animator.start();
}
//keyboard methods goes here
#Override
public void onClick(View v)
{
gettext(v);
}
private void gettext(View v)
{
try
{
String b = "";
b = (String) v.getTag();
String img_val = map.get(b);
int imgid = (Integer) imageView.getTag();
Log.e("img values=:", img_val+" "+imgid);
if(img_val.equals(ALPHABETS[imgid]))
{
imageView.setVisibility(View.INVISIBLE);
animator.start();
//trying to start the animation again
}
I am using the animation.addupdateListener to call the animation again and again but it only calls when the .ofFloat finishes on the value. When I click on the appropriate button the animation gets invisible but the next animation starts again after the same time. I want to start it immediately.
Basically calling start() again won't work. you need to "reset" the animation somehow, did you try calling end() before ?
animator.end();
animator.start();

Categories

Resources