Making button move on Touch at exact position where we touch - java

I have created an application in which there is a button which moves on touching it .
Now for onTouch I have implemented A different class.There are 2 classes one is main CircleMActivity.java and another for onTouch.
Now the app is running fine but there is one problem. When I am clicking on the button and moving it It is moving but there is a gap between the button and the screen touch.
What I want is to move it exactly where I touch it NOT at some distance later OR you can think that I want to move it at exact the cursor position.
How should I achieve it ?
Code:
CircleMActivity.java:
public class CircleMActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circle_m);
Button b=(Button)findViewById(R.id.btn1);
MultiTouch mtb=new MultiTouch(this);
b.setOnTouchListener(mtb);
}
}
MultiTouch.java:
public class MultiTouch implements OnTouchListener{
float mPrevX,mPrevY;
CircleMActivity cm;
public MultiTouch(CircleMActivity circleMActivity) {
// TODO Auto-generated constructor stub
cm=circleMActivity;
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
float currentX,currentY;
int action=arg1.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
mPrevX = arg1.getX();
mPrevY = arg1.getY();
break;
case MotionEvent.ACTION_MOVE:
currentX = arg1.getRawX();
currentY = arg1.getRawY();
MarginLayoutParams marginParams = new MarginLayoutParams( arg0.getLayoutParams());
marginParams.setMargins((int)( currentX - mPrevX), (int)( currentY - mPrevY),0, 0);
LayoutParams layoutParams = new LinearLayout.LayoutParams(marginParams);
arg0.setLayoutParams(layoutParams);
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
activity_circle.xml:
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#000000"
android:weightSum="100">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="4.95"
android:background="#fff"
android:orientation="vertical" >
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="X coord"
android:textColor="#ff00ee"
android:inputType="number" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Y coord"
android:textColor="#ff00ee"
android:inputType="number" />
<EditText
android:id="#+id/editText3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Radius"
android:textColor="#ff00ee"
android:inputType="number" />
<EditText
android:id="#+id/editText4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:textColor="#ff00ee"
android:hint="Colour"
android:inputType="number" />
</LinearLayout>
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="4.95"
android:background="#drawable/custom" />
"
</LinearLayout>
So how should I achieve it ?

It is a simple coordinates maths . In your
case MotionEvent.ACTION_DOWN:
mPrevX = arg1.getX();
mPrevY = arg1.getY();
break;
Make
mPrevY = arg1.getY()+250;
Well It will go out of the child linear layout but it is looking good !

Related

Android implement a progressBar with two clip textview on it

I am going to implement a progress bar with two clip textview on it.
Something like:
I use some trick (using paddingEnd/paddingStart, back/front textview to achieve the clip effect for textview) to implement it:
// part of activity
TextView leftFrontText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.test_page_layout, containerLayout);
View progressBar = view.findViewById(R.id.progress_bar);
leftFrontText = view.findViewById(R.id.left_front_textview);
int progress = 59;
ValueAnimator va = ValueAnimator.ofFloat(0f, progress);
int mDuration = 1000;
va.setDuration(mDuration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float)animation.getAnimatedValue();
setViewWidth(progressBar, (int)value);
setLeftFrontTextViewPadding((int)value);
}
});
// va.addListener(new Animator.AnimatorListener() {
// #Override
// public void onAnimationStart(Animator animation) {
//
// }
//
// #Override
// public void onAnimationEnd(Animator animation) {
// setLeftFrontTextViewPadding(progress);
// }
//
// #Override
// public void onAnimationCancel(Animator animation) {
//
// }
//
// #Override
// public void onAnimationRepeat(Animator animation) {
//
// }
// });
va.start();
}
private void setViewWidth(View view, int dp) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = ThemeUtil.dpToPx(this, dp);
view.setLayoutParams(layoutParams);
}
private void setLeftFrontTextViewPadding(int progressBarDp) {
int marginStart = ThemeUtil.dpToPx(TestPageActivity.this, 12);
leftFrontText.post(new Runnable() {
#Override
public void run() {
int textViewLength = leftFrontText.getWidth();
int progressbarDistance = ThemeUtil.dpToPx(TestPageActivity.this, progressBarDp);
if (textViewLength >= 0) {
int padding = marginStart + textViewLength - progressbarDistance;
leftFrontText.setPadding(0, 0, padding > 0 ? -padding : 0, 0);
}
}
});
}
And the layout is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#drawable/rounded_corner_bg_for_cashlfow_homepage_category_cell"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
>
<TextView
android:id="#+id/left_bottom_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="Entertatinment"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#color/grey1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<View
android:id="#+id/progress_bar"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#drawable/rounded_corner_front_progreebar_homepage_category_cell"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="#+id/left_front_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|start"
android:text="Entertatinment"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<TextView
android:id="#+id/right_bottom_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:textColor="#color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
/>
<TextView
android:id="#+id/right_front_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:textColor="#color/black1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
android:paddingStart="0dp"
/>
</android.support.constraint.ConstraintLayout>
When I run this code, it almost achieved the effect I want. But it has one issue. Textview keeps flashing while doing animation, and when animation finished, the color of textview sometime turn all white.
I think there may be something wrong in leftFrontText.post() of setLeftFrontTextViewPadding, like how I get width of textview. But I can't be quite sure. Can anyone show me the right way to do this? Or any other better way to implement this kind of progress bar.
Why not try this approach and leverage the power of ConstraintLayout as your progressBar:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentview"
android:layout_width="360dp"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#ddddff"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<TextView
android:id="#+id/left_bottom_textview"
android:layout_width="180dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Entertainment"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#404040"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/right_front_amount_textview"
android:layout_width="180dp"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:maxLines="1"
android:textColor="#color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="#+id/progress_bar"
android:layout_width="50dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#004090">
<TextView
android:id="#+id/left_front_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Entertainment"
android:singleLine="true"
android:textColor="#fff"
android:ellipsize="none"
android:layout_paddingStart="12dp"
android:layout_paddingLeft="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/right_bottom_amount_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:layout_alignRight="#id/left_front_textview"
android:textColor="#ffffff"
android:layout_paddingEnd="12dp"
android:layout_paddingRight="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/left_front_textview"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
So basically we would have:
The Parent layout (parentview): having a fixed layout_width 360dp and contains the initial Grey TextViews
The Progress layout (progress_bar): also having a fixed size 360dp and contains the front White TextViews
Hence we overlay the Progress layout (progress_bar) ontop of its parent layout and increase or decrease the layout_width to simulate a progress without flickering:
The image below shows the progress layout having a static layout_width of 74dp; Also note that progress layout_width based on the example provided above can range from 1dp to max:360dp or otherwise 1% to 100% of parentview width.

Drag & Drop image in Screen size of device using android

I am working on a project to move floating button in whole screen. I have written a simple code for drag & drop image of float button. but it didn't move in specific screen of device. It's hide in header and also cut from all corners. I attached some screenshots. How can I add some padding from all sides.
Here is my code for drag & drop event:
mFloatingActionButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
Intent mIntent = new Intent(mActivity, Cart.class);
startActivity(mIntent);
} else {
int X = (int) event.getRawX();
int Y = (int) event.getRawY();
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
if (X > windowwidth) {
X = windowwidth;
}
if (Y > windowheight) {
Y = windowheight;
}
lParams.leftMargin = X - _xDelta;
lParams.topMargin = Y - _yDelta;
lParams.rightMargin = 100;
lParams.bottomMargin = 100;
view.setLayoutParams(lParams);
break;
}
mRrootLayout.invalidate();
return true;
}
return true;
}
});
xml file:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white_color">
<in.srain.cube.views.GridViewWithHeaderAndFooter
android:id="#+id/gridProductList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="none"
android:focusable="false"
android:listSelector="#android:color/transparent"
android:numColumns="2"
android:overScrollMode="never"
android:paddingBottom="4dp"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
android:stretchMode="columnWidth" />
<RelativeLayout
android:id="#+id/rl_parent_floating"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible">
<RelativeLayout xmlns:fab="http://schemas.android.com/apk/res-auto"
android:id="#+id/rl_floating_button"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="3dp"
android:src="#drawable/ic_floating_cart"
fab:fab_colorNormal="#color/header_color_red"
fab:fab_colorPressed="#color/colorPrimaryDark"
fab:fab_colorRipple="#color/gold_color" />
<TextView
android:id="#+id/txtCartCount"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignRight="#+id/fab"
android:layout_alignTop="#+id/fab"
android:background="#drawable/cart_gold_circle"
android:gravity="center"
android:singleLine="true"
android:text="2"
android:textColor="#android:color/white"
android:textSize="8sp" />
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
finally After lots of research i found the solution with this awesome repo. use this library :)
Floating button in github

Use onTouchEvent and onclick event together

I'm having trouble with enabling buttons while the onTouchEvent is active. In my app the user is supposed to press anywhere on the screen to see a text and while pressing the screen press a button. The problem is that while the onTouchEvent is active the buttons doesnt work. is there anyway to enable buttons while the onTouchEvent is active?
My code for the button and onToch looks like this.
public void correctWord(){
correct_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
theWord.setText(((global_rules) getApplication()).NewWord(getApplicationContext()));
}
});
}
public boolean onTouchEvent(MotionEvent event){
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(enableTouch) {
holdToView.setVisibility(View.INVISIBLE);
theWord.setVisibility(View.VISIBLE);
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if(enableTouch) {
holdToView.setVisibility(View.VISIBLE);
theWord.setVisibility(View.INVISIBLE);
}
break;
}
return false;
}
edit, added the .xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg_1">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rätt"
android:id="#+id/correct_btn"
style="#style/btn_style2"
android:layout_alignTop="#+id/skip"
android:layout_alignLeft="#+id/holdToView"
android:layout_alignStart="#+id/holdToView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:id="#+id/theWord"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="invisible"
android:textStyle="bold"
android:textSize="40dp"
android:textColor="#ffffff" />
</RelativeLayout>

Android layout Not working

Hii i made a simple layout in which i use 3 image views and i make the center one movable.
Her is my layout class main.xml:-
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view class="com.example.screenlock.MainActivity$IV"
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|fill_horizontal"
android:background="#60000000"
android:orientation="horizontal"
android:padding="7dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:scaleType="fitXY"
android:layout_alignParentLeft="true"
android:src="#drawable/browser1" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/circle" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|fill_vertical"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/lock" />
</LinearLayout>
</FrameLayout>
and My MainActivity.java class is as follows:-
public class MainActivity extends Activity {
private ImageView imageView1, imageView2;
public static class IV extends ImageView {
private MainActivity mActivity;
public IV(Context context) {
super(context);
}
public IV(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setActivity(MainActivity act) {
mActivity = act;
}
public void onSystemUiVisibilityChanged(int visibility) {
mActivity.getState().onSystemUiVisibilityChanged(visibility);
}
}
private interface State {
void apply();
State next();
void onSystemUiVisibilityChanged(int visibility);
}
State getState() {
return mState;
}
static int TOAST_LENGTH = 500;
IV mImage;
TextView mText1, mText2;
State mState;
public MainActivity() {
// TODO Auto-generated constructor stub
}
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyLockService.class));
System.out.println(R.id.image);
imageView2 = (ImageView)findViewById(R.id.imageView2);
imageView2.setOnTouchListener(new OnTouchListener()
{
float lastX;
PointF DownPT = new PointF(); // Record Mouse Position When Pressed Down
PointF StartPT = new PointF(); // Record Start Position of 'img'
#SuppressLint("NewApi")
#Override
public boolean onTouch(View v, MotionEvent event)
{
int eid = event.getAction();
switch (eid)
{
case MotionEvent.ACTION_MOVE :
PointF mv = new PointF( event.getX() - DownPT.x, event.getY() - DownPT.y);
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD){
v.scrollBy((int) (event.getX()-lastX), 0);
lastX = event.getX();
if(lastX >= 170){
MarginLayoutParams lp = (MarginLayoutParams) imageView2.getLayoutParams();
lp.setMargins(178, 0, 0, 0);
imageView2.setLayoutParams(lp);
}
if(lastX <= 25){
MarginLayoutParams lp = (MarginLayoutParams) imageView2.getLayoutParams();
lp.setMargins(0, -16, 0, 0);
imageView2.setLayoutParams(lp);
}
System.out.println("XXXXXXX "+lastX);
}
else{
imageView2.setX((int)(StartPT.x+mv.x));
imageView2.setY((int)(StartPT.y+mv.y));
StartPT = new PointF( imageView2.getX(), imageView2.getY() );
//System.out.println("X: "+imageView2.getX()+"Y: "+imageView2.getY());
if(imageView2.getX() < -70)
{
imageView2.setX(-103);
imageView2.setY(6);
//System.out.println("--------------------------------------");
}
else if(imageView2.getX() > 260)
{
imageView2.setX(270);
imageView2.setY(8);
finish();
}
}
break;
case MotionEvent.ACTION_DOWN :
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD){
lastX = event.getX();
}
else{
DownPT.x = event.getX();
DownPT.y = event.getY();
StartPT = new PointF( imageView2.getX(), imageView2.getY() );
}
break;
case MotionEvent.ACTION_UP :
v.scrollTo(0, 0);
break;
default :
break;
}
return true;
}
});
}
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// Use onWindowFocusChanged to get the placement of
// the image because we have to wait until the image
// has actually been placed on the screen before we
// get the coordinates. That makes it impossible to
// do in onCreate, that would just give us (0, 0).
imageView1 = (ImageView) findViewById(R.id.imageView1);
int[] a = new int[2];
imageView1.getLocationInWindow(a);
int x = a[0];
int y = a[1];
System.out.println("X "+x+" Y "+y);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I am executing this code on pre-honeycomb emulator. But when i move the center image it gets hides behind the left and right images respectively.
I want center image to shown on the rest of two images and also want to show that two images also.
Basically, the center image is a circle and rest two images are browser and lock images and i want that circle to overlaps that images.
I am working on a lock screen.
Please help in my layout problem and how i can solve this problem?????
You can try changing your layout as follows...
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.screenlock.MainActivity$IV"
android:scaleType="center" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|fill_horizontal" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#60000000"
android:orientation="horizontal"
android:padding="7dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" />
<View
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|fill_vertical"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" />
</LinearLayout>
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_launcher" />
</FrameLayout>
</FrameLayout>

Get button coordinates and detect if finger is over them - Android

I have 4 buttons in my android app activity. This is what it looks like:
As you can see, the textViews at the bottom of the screen display the x and y coordinates. The coordinates are in reference to a relative layout. (See below given code)
Now, what I want to do is get the x and y coordinates of the 4 buttons at runtime and then figure out if my finger is touching the buttons while moving or not. In simple words, I want to press the buttons by swiping my finger over them instead of lifting and touching. How can I achieve it? I want to implement it in my piano application.
I was able to get the coordinates on screen and they change as I move my finger.
So, my question is How can I get the coordinates of the buttons and detect if my finger is swiping above them?:
XML
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:id="#+id/relativelayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Y Cord : "
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:id="#+id/textView"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="X Cord : "
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:id="#+id/textView2"
android:layout_above="#+id/textView"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="#+id/textView3"
android:textColor="#000000"
android:layout_below="#+id/textView2"
android:layout_toRightOf="#+id/textView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="#+id/textView4"
android:textColor="#000000"
android:layout_marginBottom="10dp"
android:layout_above="#+id/textView"
android:layout_toRightOf="#+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:textColor="#000000"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:textColor="#000000"
android:id="#+id/button2"
android:layout_below="#+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:textColor="#000000"
android:id="#+id/button3"
android:layout_below="#+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button4"
android:textColor="#000000"
android:layout_below="#+id/button3"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
Java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView xcordview = (TextView) findViewById(R.id.textView4);
final TextView ycordview = (TextView) findViewById(R.id.textView3);
RelativeLayout touchview = (RelativeLayout) findViewById(R.id.relativelayout);
touchview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
xcordview.setText(String.valueOf(event.getX()));
ycordview.setText(String.valueOf(event.getY()));
return true;
}
});
}
}
Thank you all very very much!
Update:
public class MainActivity extends Activity {
RelativeLayout touchview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView xcordview = (TextView) findViewById(R.id.textView4);
final TextView ycordview = (TextView) findViewById(R.id.textView3);
touchview = (RelativeLayout) findViewById(R.id.relativelayout);
touchview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
xcordview.setText(String.valueOf(event.getX()));
ycordview.setText(String.valueOf(event.getY()));
for(int i = 0; i < touchview.getChildCount(); i++){
if(checkInterSection(touchview.getChildAt(i), event.getRawX(), event.getRawY())){
Button button = (Button) findViewById(R.id.button);
button.setBackgroundColor(Color.BLUE);
break;
}
}
return true;
}
});
}
private boolean checkInterSection(View view, float rawX, float rawY) {
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
int width = view.getWidth();
int height = view.getHeight();
//Check the intersection of point with rectangle achieved
return (!(rawX < x || rawY > x + width || rawY < y || rawY > y + height));
}
}
package com.example.touch;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
Button b1, b2, b3, b4;
int b1x1, b1x2, b1y1, b1y2;
private TextView xcordview;
private TextView ycordview;
private TextView buttonIndicator;
private RelativeLayout touchview;
private static int defaultStates[];
private Button mLastButton;
private final static int[] STATE_PRESSED = {
android.R.attr.state_pressed,
android.R.attr.state_focused
| android.R.attr.state_enabled };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
xcordview = (TextView) findViewById(R.id.textView4);
ycordview = (TextView) findViewById(R.id.textView3);
buttonIndicator = (TextView) findViewById(R.id.button_indicator);
touchview = (RelativeLayout) findViewById(R.id.relativelayout);
b1 = (Button) findViewById(R.id.button1);
b2 = (Button) findViewById(R.id.button2);
b3 = (Button) findViewById(R.id.button3);
b4 = (Button) findViewById(R.id.button4);
defaultStates = b1.getBackground().getState();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
touchview.setOnTouchListener(new View.OnTouchListener() {
private boolean isInside = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
xcordview.setText(String.valueOf(x));
ycordview.setText(String.valueOf(y));
for (int i = 0; i < touchview.getChildCount(); i++) {
View current = touchview.getChildAt(i);
if (current instanceof Button) {
Button b = (Button) current;
if (!isPointWithin(x, y, b.getLeft(), b.getRight(), b.getTop(),
b.getBottom())) {
b.getBackground().setState(defaultStates);
}
if (isPointWithin(x, y, b.getLeft(), b.getRight(), b.getTop(),
b.getBottom())) {
b.getBackground().setState(STATE_PRESSED);
if (b != mLastButton) {
mLastButton = b;
buttonIndicator.setText(mLastButton.getText());
}
}
}
}
return true;
}
});
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
}
static boolean isPointWithin(int x, int y, int x1, int x2, int y1, int y2) {
return (x <= x2 && x >= x1 && y <= y2 && y >= y1);
}
}
layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff" >
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:text="Y Cord : "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView"
android:layout_alignParentLeft="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:text="X Cord : "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView2"
android:layout_toRightOf="#+id/textView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#+id/textView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="B1"
android:textColor="#000000" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/button1"
android:text="B2"
android:textColor="#000000" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/button2"
android:text="B3"
android:textColor="#000000" />
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/button3"
android:text="B4"
android:textColor="#000000" />
<TextView
android:id="#+id/button_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/textView4"
android:layout_marginRight="33dp"
android:text="No one"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button_indicator"
android:layout_alignBottom="#+id/button_indicator"
android:layout_marginRight="29dp"
android:layout_toLeftOf="#+id/button_indicator"
android:text="Entered: "
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
private boolean checkInterSection(View view, int rawX, int raxY) {
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
int width = view.getWidth();
int height = view.getHeight();
//Check the intersection of point with rectangle achieved
return (!(rawX < x || rawY > x + width || rawY < y || rawY > y + height));
}
for(int i = 0; i < touchview.getChildCount(); i++){
if(checkInterSection(touchview.getChildAt(i), event.getRawX(), event.getRawY())){
if(checkInterSection(touchview.getChildAt(i), event.getRawX(), event.getRawY())){
((Button)touchview.getChildAt(i)).setBackgroundColor(Color.BLUE);// Type casting may not be required
}else{
((Button)touchview.getChildAt(i)).setBackgroundColor(Color.WHITE);
}
break;
}
}
getX() getY() for a OnTouchListener give coordinates relative the the cooresponding view.
If you prefer screen coordinates instead you can use one of the following
overwrite onTouchEvent for the activity and remove OnTouchListener-s for buttons,
in which case MotionEvent will report screen coordinates instead of Button coordinates
#Override
public boolean onTouchEvent (MotionEvent event) {
xcordview.setText(String.valueOf(event.getX()));
ycordview.setText(String.valueOf(event.getY()));
return true;
}
use getTop() getLeft() in OnTouchListener for a button:
touchview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
xcordview.setText(String.valueOf(event.getX()+v.getLeft()));
ycordview.setText(String.valueOf(event.getY()+v.getTop()));
return true;
}
});
You may consider using GestureDetector to detect swipes, however it isn't really necessary.
karioki 's solution works well. In order to make it work even when we start the move from inside one of the buttons, just add
android:clickable="false"
for every button in xml.

Categories