Drag a view onLongClick and start activity onClick - java

I'm banging my head with this problem which probably is simple but since I'm new to this topic I somehow haven't been able to figure it out yet.
I've successfully implemented dragging a view with onTouch method. I've also successfully implemented onLongClick and onClick methods. But both of these functionalities were implemented separately.
The problem, like the title says is when I want to join these functionalities. I want the onTouch method to be called when a user long clicks a view and I want a new activity to start when a user clicks a view.
Here is the pseudo code:
public class Website extends AppCompatActivity implements View.OnTouchListener{
TextView longpress;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_website);
longpress = (TextView) findViewById(R.id.longpress);
longpress.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view){
//I don't really know how to do this part
onTouch(View view, Motion Event event);
return true;
}
});
longpress.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//Code for new activity comes here (I know how to do this part)
}
});
}
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction(){
case MotionEvent.ACTION_DOWN:
//Save initial coordinates of view <-- view.getX(), view.getY()
break;
case MotionEvent.ACTION_MOVE:
//Calculate dX and dY and setX and Y of the view (move view)
break;
case MotionEvent.ACTION_UP:
//If view is certain distance away from initial points do something
break;
}
}
}
Like I said, onTouch works on itself if I don't try to call it from onLongClick method. If I try to call onTouch(View view, MotionEvent event) from onLongClick method the problem occurs because onLongClick only receives one out of two arguments onTouch method should receive (onLongClick only receives view argument but it should also receive event argument).
Maybe I'm trying to do this in a totally wrong way but I have been looking at some documentation e.g. https://developer.android.com/training/gestures/ but still won't get an idea what to do.
(I would like to have a similar functionality to notifications on android phones)

So I've come to a solution which might or might not be a good one but for now it serves my functionality. If someone has a better solution and thinks mine is bad in some way please say so.
Here is the code:
boolean flag;
public boolean onTouch(View view, MotionEvent event){
int action = event.getAction() & MotionEvent.ACTION_MASK;
if(action == MotionEvent.ACTION_DOWN){
//do something on a down press
flag = true;
return true;
}
if(action == MotionEvent.ACTION_UP && flag == true){
//do something if we move finger away from screen we
//didn't move the view first
return true;
}
if(action == MotionEvent.ACTION_UP && flag == false){
//do something if we move finger away from screen and we moved
//the view before we moved the finger away from screen
}
if(action == MotionEvent.ACTION_MOVE){
//do something when moving the view
flag = false;
}

Related

Detecting the location where a button was clicked

I was wondering if there is a way to know exactly where a button was tapped, and take different actions based on where the user tapped it. Something like:
fooBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
switch(onClickLocation){
case LEFT:
foo();
break;
case RIGHT:
bar();
break;
case MIDDLE:
baz();
break;
}
}
});
Not using an OnClickListener. OnTouchListener gives you a MotionEvent that you can use to determine where the actual touch event occurred.
For example, here I register both an OnClickListener and an OnTouchListener on the same View (called row):
row.setOnClickListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
row.setOnTouchListener(new View.OnTouchListener() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public boolean onTouch(View v, MotionEvent event) {
v
.findViewById(R.id.row_content)
.getBackground()
.setHotspot(event.getX(), event.getY());
return(false);
}
});
}
In this case, I don't need to know where the widget was touched for processing the click, but I do need to know where the widget was touched for adjusting the RippleDrawable background, so the ripple appears to emanate from where the user touched. Returning false from onTouch() means I am not consuming the touch event, and so eventually my onClick() method will also be called.
In your case, either:
do the actual work in onTouch(), or
cache the last-seen touch point in onTouch() but do not do the work until onClick()
My gut tells me that the latter should give you better results (e.g., you won't misinterpret a long-click), but I have not tried doing what you are seeking.

How to check if the screen hasn't been clicked in Android?

I know that if you want to check if someone clicked on something, you would do
if(event.getAction() == MotionEvent.ACTION_DOWN)
But I want to check if the screen hasn't been clicked at all.
What is the code I would produce in order to do this?
Also, as a side note, would it be a good idea to have all the classes in an Android app extend the View classes?
Create a boolean variable called istouched and use onTouchLisener on your top most View actually its a Window that's where your Views are, quick sample
getWindow().getDecorView().setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
// i have been touched
istouched = true;
Toast.makeText(getBaseContext(), "you touched me?!! - i will tell my mom", Toast.LENGTH_SHORT).show();
return true;
}
if(event.getAction() == MotionEvent.ACTION_DOWN){
// you can implement this
Toast.makeText(getBaseContext(), "shhh; i am touching", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
so the logic here is if istouched is false your device is not telling her mom, which means it has not being touched..
hope it helps
One way is to add android:onClick="method" to the root layout in your layout xml.
in the method you can change a boolean variable to true (screenClicked = true).

Alternative to make an action when pressing/realising a button, android

I want to make an application with 9 buttons for android 4.0, I need each of the buttons to call a method when pressed and another method when released.
I'm kind of surprised there's not a really straight-forward method to accomplish what I just described but thanks to some questions and answers I read on stackoverflow I managed to accomplish what I need by adding a listener in each of the buttons, as shown for one of the buttons in the next code.
buttonUp.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
buttonUpPressed();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
buttonUpReleased();
}
return true;
}
});
I want to know if there's an alternative to accomplish this behavior without having to add a listener for every button. I see that as a waste of resources and a lot of coding. I can't imagine if I eventually have to add more buttons.
So any help would be appreciated.
implements your class with OnTouchListener
Button a,b;
Button[] bArray = {a,b};
for (int i = 0; i < bArray.length; i++) {
bArray[i].setOnTouchListener(this)
}
after that add unimplemented method
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_DOWN){
switch (v.getId()) {
case R.id.button1:
break;
default:
break;
}
}
else if(event.getAction() == MotionEvent.ACTION_UP){
switch (v.getId()) {
case R.id.button1:
break;
default:
break;
}
}
return false;
}
i hope you'll like my logic :)
You can add all the buttons to an array or ArrayList and then define a listener field in your class.
OnTouchListener oclButtons = new OnTouchListener(...);
Then you can add the same listener to all the Buttons in the ArrayList.
for (Button b : listOfButtons) {
b.setOnTouchListener(oclButtons);
}
An alternative to setting IDs for each Button is to get/set tags (since each view needs a unique ID). Your listener can determine which button was touched by using v.getTag().

Which items are sensitive to MotionEvent.ACTION_MOVE?

I am setting OnTouchListener to a Button, I can check if motion type is MotionEvent.ACTION_MOVE. On the other hand if it is TextView, I cannot get any moment of MotionEvent.ACTION_MOVE
For example take a look at the code below:
public boolean onTouch(View view, MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
Log.e(TAG,"1");
}
if (me.getAction() == MotionEvent.ACTION_UP) {
Log.e(TAG,"2");
} else if (me.getAction() == MotionEvent.ACTION_MOVE) {
Log.e(TAG,"3");
}
return false;
}
if I bind this listener to a Button, I can see "3" in my logs, on the other hand, if I bind this to an ImageView or etc. I cannot see any "3". but "1" and "2" are acting normal for both situation.
So the question is (if I am not mistaken) which items are MotionEvent.ACTION_MOVE sensitive?
Try implementing OnClickListener also..like this..and put onClick empty.. I think it then detects ACTION_MOVE, along with ACTION_UP and ACTION_DOWN..
class MyActivity implements View.OnTouchListerner, View.OnClickListener{
.....
public void onClick(View v) {}
.....
}
Textview doen't hava any MotionEvent ActionMove, http://developer.android.com/reference/android/widget/TextView.html..
Thanks...

i want call MotionEvent.ACTION_DOWN in one activity and MotionEvent.ACTION_UP in another activity

ImageView ii = (ImageView)v.findViewById(R.id.picture);
ii.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent e) {
ImageView i2 = (ImageView)findViewById(R.id.btn_imagetest);
if(e.getAction() == MotionEvent.ACTION_DOWN){
//call activity one
}
if (e.getAction() == MotionEvent.ACTION_UP)
{
//call activity 2
}
return true;
}
});
when i touch on image 'ii' i should go to imgview(i2)(can be activity too) and when i leave the imgview should go away(back to same activitiy) ..(Note:imgview is covers full screen in phone)
i have no idea..how to proceed.
If I understand correctly, you're asking for information on how to start another Activity from the current Activity. For information on that, take a look at Android - finishing activity from another activity
Also, take a look at the Notepad Tutorial, for a complete example.

Categories