I am developing an animation app like Mine Sweeper. Upon tapping on the buttons, the buttons will be pressed and the user may tap on the other button. On the third tap on the chosen button, there will be an incoming image (which uses AlphaAnimation/ScaleAnimation) from that button.
Buttons
private int[] right_lung = { R.id.lungs_106, R.id.lungs_113,
R.id.lungs_114, R.id.lungs_115, R.id.lungs_116, R.id.lungs_121,
R.id.lungs_122, R.id.lungs_123, R.id.lungs_124, R.id.lungs_125,
R.id.lungs_129, R.id.lungs_130, R.id.lungs_131, R.id.lungs_132,
R.id.lungs_133, R.id.lungs_134, R.id.lungs_137, R.id.lungs_138,
R.id.lungs_139, R.id.lungs_140, R.id.lungs_141, R.id.lungs_142,
R.id.lungs_145, R.id.lungs_146, R.id.lungs_147, R.id.lungs_148,
R.id.lungs_149, R.id.lungs_150, R.id.lungs_151, R.id.lungs_152,
R.id.lungs_153, R.id.lungs_154, R.id.lungs_155, R.id.lungs_156,
R.id.lungs_157, R.id.lungs_158, R.id.lungs_159, R.id.lungs_160,
R.id.lungs_161, R.id.lungs_162, R.id.lungs_163, R.id.lungs_164,
R.id.lungs_165, R.id.lungs_166, R.id.lungs_167, R.id.lungs_168,
R.id.lungs_169, R.id.lungs_170, R.id.lungs_171, R.id.lungs_172,
R.id.lungs_173, R.id.lungs_174, R.id.lungs_175, R.id.lungs_176,
R.id.lungs_177, R.id.lungs_178, R.id.lungs_179, R.id.lungs_180,
R.id.lungs_181, R.id.lungs_182, R.id.lungs_183, R.id.lungs_184,
R.id.lungs_185, R.id.lungs_186, R.id.lungs_187, R.id.lungs_188,
R.id.lungs_189, R.id.lungs_190, R.id.lungs_191, R.id.lungs_192,
R.id.lungs_194, R.id.lungs_195, R.id.lungs_196, R.id.lungs_197,
R.id.lungs_198, R.id.lungs_199, R.id.lungs_200, R.id.lungs_205,
R.id.lungs_206, R.id.lungs_207 };
private Button[] button_right_lung = new Button[right_lung.length];
MainActivity
for (int i = 0; i < button_right_lung.length; i++) {
final int b = i;
button_right_lung[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (counter == 1) {
show_first_page();
int[] startPosition = new int[2];
button_right_lung[b].getLocationOnScreen(startPosition);
int[] endPosition = new int[2];
button_right_lung[b].getLocationOnScreen(endPosition);
Animation anim = new ScaleAnimation(startPosition[1], 2000, endPosition[1], 2000);
anim.setDuration(3000);
img_Message1.setVisibility(View.VISIBLE);
img_Message1.startAnimation(anim);
}
});
}
Now, my question is, how can I get the coordinates of the selected button and will animate the image after the button is pressed?
Now you know how many butouns you need to put. You also have id for all of them. You have placed same in an array.
Now I do believe that you can find array length.
Just put all buttouns in loop.
for ex:
for(int i = 0; i < right_lung.length; i++){
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Button btn = (Button)v;
int btn_value = btn.getid;
// Some thing like that..
}
});
}
you can use OnTouchListener on your button
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int X=(int) event.getX();
int Y=(int) event.getY();
}
}
Related
I am new in the Android. I can not touch the three buttons at one time This code I can click on the three buttons but not the One Touch. I have researched a lot but I did not find the solution I tried to use OnCilckListener() but OnTouchListener() could not find a way
I want to give me an example or a tip. And you can see in the picture. Please help me, thank you
public class MainActivity extends Activity{
Button a,b,c;
int a1 = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//a = (Button)findView...;
//b = ....;
//c = ....;
a.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
a1 = 1;
b.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
if(a1 == 1){
a1 = 2;
c.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
if(a1 == 2){
Toast.makeText(getBaseContext(), "Toast", Toast.LENGTH_SHORT).show();
a1 = 0;
}}});
}
}});
}
});
}
Put the 3 buttons in a single parent view. Have the parent view implement the swiping behavior. Then have the parent view override onInterceptTouchEvent to return true for all touches. That way the parent view will handle all touches for all of its children, and you just have a basic swipe detector.
Attach an onTouchListener to the layout containing the three buttons. Check each touch for an ACTION_DOWN (putting the finger down) that is inside the bounds of the first view. Then look for the next ACTION_UP (releasing the initial touch) to be inside the bounds of the third view. You can check whether a touch event is in the bounds of a view with the following code:
public static boolean hitTest(View v, int x, int y) {
final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f);
final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f);
final int left = v.getLeft() + tx;
final int right = v.getRight() + tx;
final int top = v.getTop() + ty;
final int bottom = v.getBottom() + ty;
return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
}
Here is the problem I am facing. On a empty relative layout, when touched textview is instantiated at the touched x y position. I got this far correct, but the problem is that when I touch on the empty space near already instantiated view, previous view and currently placed views are overlapped. I tried by the getting the child views of the layout and checking the current view and already placed view using rect data that if they intersect. How to solve this problem?
Here is the code:
public class MainActivity extends AppCompatActivity
{
private int id = 0;
private RelativeLayout root;
private RelativeLayout.LayoutParams params;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_designer);
root = (RelativeLayout) findViewById(R.id.rootlayout);
root.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
instantiateView(v, event);
break;
}
return true;
}
});
}
private void instantiateView(View v, MotionEvent event)
{
int x = (int) event.getX();
int y = (int) event.getY();
TextView bt = new TextView(DesignerActivity.this);
bt.setText("1");
bt.setId(++id);
bt.setBackgroundColor(Color.BLACK);
bt.setTextColor(Color.WHITE);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
showDialog();
}
});
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(x, y, 0, 0);
bt.setLayoutParams(params);
//((ViewGroup) v).addView(bt);
if(root.getChildCount() <= 0)
{
((ViewGroup) v).addView(bt);
}
else
{
for (int i = 0; i < root.getChildCount(); i++)
{
if (!checkCollision(bt, root.getChildAt(i)))
{
if(bt != root.getChildAt(i))
{
((ViewGroup) v).addView(bt);
}
}
}
}
}
private void showDialog()
{
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_layout);
Button editBtn = (Button) dialog.findViewById(R.id.button1);
Button deleteBtn = (Button) dialog.findViewById(R.id.button2);
editBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
dialog.dismiss();
}
});
deleteBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
dialog.dismiss();
}
});
dialog.show();
}
private boolean checkCollision(View v1, View v2)
{
Rect r1 = new Rect(v1.getLeft(), v1.getTop(), v1.getRight(), v1.getBottom());
Rect r2 = new Rect(v2.getLeft(), v2.getTop(), v2.getRight(), v2.getBottom());
return r1.intersect(r2);
}
}
You are using Relative Layout that's why your Textviews are overlapping.
If you don't want the overlapping and want to place it next or somewhere else to the overlapped view , it is your decision. Just check if they intersect and take appropriate decision based on your requirement.
Below line is the problem in your code.
Rect r1 = new Rect(v1.getLeft(), v1.getTop(), v1.getRight(), v1.getBottom());
You set the params' Margin does not mean that you will get desired left,top,right, bottom values.You will get these values right after the inflation of your view hierarchy.
You can use this function:
private boolean checkCollision(View v1, View v2)
{
int leftMargin = ((RelativeLayout.LayoutParams) v1.getLayoutParams()).leftMargin;
int topMargin = ((RelativeLayout.LayoutParams) v1.getLayoutParams()).topMargin;
Rect r1 = new Rect(root.getPaddingLeft() + leftMargin, root.getPaddingTop() + topMargin,
root.getPaddingLeft() + leftMargin + v2.getWidth(), root.getPaddingTop() + topMargin + v2.getHeight());
Rect r2 = new Rect(v2.getLeft(), v2.getTop(), v2.getRight(), v2.getBottom());
return r1.intersect(r2);
}
After that use
params.addRule(); according to your requirement where you want to place your overlapping view.
I created a simple app, just want when I click a button, the imageview will travel to another position.
Below is the code, but it seems that when I click the button, the imageview always begin with the original position, not the real position. Is there any problem with my code?
public class MainActivity extends Activity{
private ImageView iv;
private Button bt;
private AnimatorSet mAniSet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ddd);
iv = (ImageView) this.findViewById(R.id.imageView1);
bt = (Button) this.findViewById(R.id.button1);
mAniSet = new AnimatorSet();
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int pointOnScreen[] = new int[2];
iv.getLocationOnScreen(pointOnScreen);
ObjectAnimator AniTranslationX = ObjectAnimator.ofFloat(iv, View.TRANSLATION_X, pointOnScreen[0]+100);
mAniSet.playTogether(AniTranslationX);
mAniSet.setTarget(iv);
mAniSet.setDuration(200).start();
}
});
}
}
If you create a ObjectAnimator.ofFloat(Object, Property, values) and there is only one value, so the origin of the animation will be 0f.
You can find the source into the class android.animation.KeyFrameSet and the following method:
public static KeyframeSet ofFloat(float... values) {
boolean badValue = false;
int numKeyframes = values.length;
FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
if (Float.isNaN(values[0])) {
badValue = true;
}
} else {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
keyframes[i] =
(FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
if (Float.isNaN(values[i])) {
badValue = true;
}
}
}
if (badValue) {
Log.w("Animator", "Bad value (NaN) in float animator");
}
return new FloatKeyframeSet(keyframes);
}
You can see, with only one value, the start of the animation is 0f (keyframes[0]).
If you put 2 values, your animation will start from the first value and stop at the second:
ObjectAnimator AniTranslationX = ObjectAnimator.ofFloat(iv, View.TRANSLATION_X, pointOnScreen[0], pointOnScreen[0] + 100);
With 3 or more values, the animation will reach all these values over the time of the animation.
i want to touch button and drag into other button position you can get clear idea by this image.
Guiding Image
Please help me
I Also Found This very helpful.
Touch and drag image in android
but i want to drag to other button position not some were else on screen.i don't have any idea how i would detect button is entered in other button dimensions.
So far i am doing is just animation but i don't want just straight forward moving button by click.
i want user to move by himself button to other button position.
Code
public class AnimationActivity extends Activity implements OnClickListener {
public Button btn_a1, btn_a2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainsec);
btn_a1 = (Button) findViewById(R.id.btn_a1);
btn_a2 = (Button) findViewById(R.id.btn_a2);
btn_a1.setOnClickListener(this);
btn_a2.setOnClickListener(this);
}
#Override
public void onClick(final View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_a1: {
int direction = -1;
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
RelativeLayout.LayoutParams absParams = (RelativeLayout.LayoutParams) btn_a1
.getLayoutParams();
final float xDelta = (displaymetrics.widthPixels / 2)
- absParams.leftMargin - (btn_a1.getWidth() / 2);
final Animation animation = new TranslateAnimation(0, xDelta
* direction, 0, 0);
AnimationListener animationOutListener = new AnimationListener() {
public void onAnimationEnd(Animation animation) {
btn_a2.setBackgroundDrawable(R.id.blank);// Unselect
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
btn_a2.setBackgroundDrawable(R.id.red);// Select
}
};
animation.setAnimationListener(animationOutListener);
animation.setDuration(1000);
btn_a2.startAnimation(animation);
break;
}
case R.id.btn_a2: {
int direction = 1;
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
RelativeLayout.LayoutParams absParams = (RelativeLayout.LayoutParams) btn_a1
.getLayoutParams();
final float xDelta = (displaymetrics.widthPixels / 2)
- absParams.leftMargin - (btn_a1.getWidth() / 2);
final Animation animation = new TranslateAnimation(0, xDelta
* direction, 0, 0);
AnimationListener animationOutListener = new AnimationListener() {
public void onAnimationEnd(Animation animation) {
btn_a1.setBackgroundDrawable(R.id.blank);// Unselect
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
btn_a1.setBackgroundDrawable(R.id.red);// Select
}
};
animation.setDuration(1000);
btn_a1.startAnimation(animation);
break;
}
}
}
How about this:
You would have to evaluate the buttons parentViews onTouchEvents, and if you hit it, you can start the onClick method associated with the button, or when you lift your finger, what ever suits your app.
But while finger down/move you can just change the buttons coordinates and trigger a redraw ont he parent view.
You might have to create a new View that supports moving Buttons. I dont know if you can do that inside of a layout.
public class UnitConverterActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
LinearLayout mLinearLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLinearLayout = new LinearLayout(this);
ImageView i = new ImageView(this);
i.setImageResource(R.drawable.mainmenu);
//i.setAdjustViewBounds(false);
i.setScaleType(ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mLinearLayout.addView(i);
setContentView(mLinearLayout);
//setContentView(R.layout.main);
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
return false;
}
}
I have used the above method to load an image for the main menu I am trying to create. The image has four areas and each will be used to call a particular function of the app. Now I am trying to implement touch interface on those areas. I know how to define the range of pixels for that purpose but I am at loss on how to implement OnTouchListner on the image. Please help me in this regard.
If your image was split into four rectangular quarters (say)
then in onCreate have:
i.setOnTouchListener(this);
and for your listener, something like this (illustrates the principle only):
#Override
public boolean onTouch(View v, MotionEvent mev) {
int width = v.getWidth();
int height = v.getHeight();
float x = mev.getX();
float y = mev.getY();
String msg;
if (x < width / 2) {
if (y < height / 2)
msg = "Top left quarter";
else
msg = "Bottom left quarter";
} else {
if (y < height / 2)
msg = "Top right quarter";
else
msg = "Bottom right quarter";
}
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
return false;
}
Just put this code in onCreate().
i.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//your code
}
}