So, basically I have a clickable ImageView with a listener:
imageView1.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
//do something while pressed
}
if(event.getAction() == MotionEvent.ACTION_UP){
//when finger is lifted
}
return true;
}
});
It works, but the problem is that there is an annoying delay between the moment when I press the ImageView and when the code is actually executed.
Is there any way to fix it? I've read about a prepressed state that may fix it, can anyone explain it to me?
Related
There is a gButton button and there is an onTouch listener:
gButton.setOnTouchListener (new View.OnTouchListener () {
public boolean onTouch (View v, MotionEvent event) {
if (event.getAction () == MotionEvent.ACTION_DOWN) {
...
} else if (event.getAction () == MotionEvent.ACTION_UP) {
...
}
return false;
}
});
Something is done with ACTION_DOWN and ACTION_UP (pressing the button / releasing), but the pressing event occurs only when the button is touched, and if the button was pressed and you take your finger away, nothing will happen (there is no finger tap)
I tried to add below, after ACTION_DOWN, other "else if" conditions like ACTION_OUTSIDE (I took everything from the page: https://developer.android.com/reference/android/view/MotionEvent.html), but nothing happened. And yes, I used If, not Switch
I need to make sure that when I touch the button (if the finger is in the button area at all, even if the first touch was somewhere in the empty area and the finger was moved to the button), some actions were performed (for example, a Toast method with the text "On "), when you release your finger from the button area or when you move your finger from the button area, other actions were performed (Toast with the value of Off)
I tried to do this with one of the answers to a similar question by correcting it in my code: Cancel button press if user moves finger off button, however, an error prntscr.com/oghnm2 is displayed, and I do not know where and how to get L, R, T, B, except getTop();
I hope this might help,here i had checked mouse pointer location with the btn coordinates, if its location within range printed logs otherwise printed out of area.
btn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getLeft()<=event.getX() && v.getRight()>=event.getX() && v.getTop()<=event.getY() && v.getBottom()>=event.getY()) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
Log.d("LOG", "pressed");
if (event.getAction() == MotionEvent.ACTION_UP)
Log.d("LOG", "released");
if (event.getAction() == MotionEvent.ACTION_MOVE)
Log.d("LOG", "moving");
}
else
{
Log.d("LOG", "out of area");
}
return false;
}
});
I have a TextView, with a onLongClickListener and OnClick event, on holding TextView, its color changes to red, and on releasing, its color is supposed to change to white.
Problem:
When I hold the TextView and move my finger outside of it while holding, and then leave my finger, its color does not change to white.
XML
<TextView
android:layout_width="match_parent"
android:text="hello"
android:textColor="#ffff"
android:id="#+id/timer"
android:layout_height="wrap_content"
/>
Java
final TextView t1 = (TextView) findViewById(R.id.timer);
t1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t1.setTextColor(Color.WHITE);
}
});
t1.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
t1.setTextColor(Color.RED);
return false;
}
});
View.OnClickListener - Interface definition for a callback to be invoked when a view is clicked.
View.OnLongClickListener - Interface definition for a callback to be invoked when a view has been clicked AND held.
So what you are saying is 100% true.It should be red because its being been clicked and held as the way you did.
But when i hold the text view and move my finger outside the text view
while holding , and then leave my finger , it not changes its color to
white
You have given color white to text view when it gets only clicked !! If you want to get that white like you said(when clicked and held), you need to set the white color in OnLongClickListener
To the point if you want to detect your views touch and release and change colors related to that then you need to use OnTouchListener instead of clickListeners
View.OnTouchListener - Interface definition for a callback to be invoked when a touch event is dispatched to this view. The callback will be invoked before the touch event is given to the view
t1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch ( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
t1.setTextColor(Color.RED); // pressed state
break;
case MotionEvent.ACTION_UP:
t1.setTextColor(Color.WHITE); // Released state
break;
}
return true;
}
});
Assign a onTouch listener and look for MotionEvent.ACTION_DOWN and MotionEvent.ACTION_MOVE:
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Construct a rect of the view's bounds
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
// User moved outside bounds
t1.setTextColor(Color.WHITE);
}
}
return false;
}
Use OnTouchListener that way you can register touch down and up events. MotionEvent case MotionEvent.ACTION_DOWN: will set the color to red when the user touches down on your TextView, and case MotionEvent.ACTION_UP: will set the color to white when the user lifts their finger off the TextView.
final TextView t1 = (TextView) findViewById(R.id.timer);
t1.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
t1.setTextColor(Color.RED);
break;
case MotionEvent.ACTION_UP:
t1.setTextColor(Color.WHITE);
break;
}
return true;
}
});
As I described in the Title, my problem is that there is a view that is not focusable. So now I've no idea how to get KeyEvents from the View...
Edit:
If possible, event can be listened from service
I have used this code in a fragment to close a full screen pager view and it works
View v = inflater.inflate(R.layout.fragment_addetails, container1,
false);
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& pager.getVisibility() == View.VISIBLE) {
pager.setVisibility(View.GONE);
return true;
}
return false;
}
});
or this
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
//do code
return true
}
return false;
}
maybe this will help
if not please describe the full scenario for what your are trying to achieve
Ok I found out, that I can use the MediaButton to get the KeyEvent I wanted. I just needed to declare a BroadcastReceiver and register it. Thats it!
I am having this problem when I try to change the source/resource of a image(a button) when is pressed and released.
Btn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
/*if(event.getAction() == MotionEvent.ACTION_DOWN) {
ImageBtn.setImageResource(R.drawable.btn1);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
ImageBtn.setImageResource(R.drawable.btn0);
}*/
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
ImageBtn.setBackgroundResource(R.drawable.btn1);
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
ImageBtn.setBackgroundResource(R.drawable.btn1);
return true; // if you want to handle the touch event
}
return false;
}
});
This is the code, I tried what is in the comment too, but no result. I do have to mention that the button changes its resource just when touching it, but after releasing it, it doesn't change.
The button listener is on a relative layout(also defined as a relative layout in the xml code), in java however is defined as a button.
The image of the button doesn't change from when you touch it to when you release it because you are setting the same background resource.
Both cases contain:
ImageBtn.setBackgroundResource(R.drawable.btn1);
Set one of them to a different image.
I've got the following code which fires every time my "redTime" EditText is touched.
redTime.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("click", "onMtouch");
redTime.setSelection(redTime.getText().length());
return false;
}
});
It is meant to keep the cursor on the right side of the EditText upon every touch. The problem is that the line containing the "setSelection" method doesn't work upon the FIRST touch of the control. That is, if another control has focus, and I touch the "redTime" control for the first time, the method is fired, but the cursor remains at the location I touched (not the right side).
How do I know the listener fires? The "Log.i" call works, but not the cursor change. I suspect the "setSelection" call is working, but some later event is negating it.
I tried a few things. I tried consuming the event by returning TRUE in the listener. Didn't work. I tried repeating the "setSelection" call in OnTouchListener, and OnFocusChanged as well. Still doesn't work.
I almost forgot. Here is the XML for the control in question.
<EditText
android:id="#+id/redEditText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:ellipsize="end"
android:gravity="right"
android:inputType="time"
android:text="#string/zeroTime"
android:textColor="#ff0000"
android:textSize="32sp" >
</EditText>
I ran into this issue recently and couldn't get anything to work, so ended up doing this:
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
postDelayed(new Runnable() {
#Override
public void run() {
setSelection(getText().length());
}
}, 50);
return false;
}
});
To avoid the error do something like this:
yourEditText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
yourEditText.setFocusable(true);
yourEditText.requestFocus();
yourEditText.setSelection(emailEditText.getText().length());
break;
case MotionEvent.ACTION_UP:
v.performClick();
break;
default:
break;
}
return true;
}
});
You could do
redTime.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("click", "onMtouch");
redTime.setFocusable(true);
redTime.requestFocus();
redTime.setSelection(redTime.getText().length());
return false;
}
});
Before you call setSelection, that way redTime will have the focus when you do the selection.
Just put the edittext as like below
<EditText
android:id="#+id/from"
android:focusable="false"
android:hint="#string/pickup_location"
android:imeOptions="actionNext"
android:inputType="textNoSuggestions"
android:padding="10dp"
android:textColor="#android:color/white" />
Set the ontouch listener in your activity
EditText et = (EditText)findViewById(R.id.et); et.setOnTouchListener(this)
#Override public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP)
switch (v.getId()) {
case R.id.from:
//do your action
break;
use this method:
redTime.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_UP){ //check the event
redTime.requestFocus(); //keep focus on the EditText(redTime)
redTime.selectAll(); //select all text
}
}
return true;
});