This is so strange, but if you put an onClickListener on a TextView (or non-editable EditText) which has android:textIsSelectable="true" - it needs not one tap, but two.
I checked it on 3 phones and all of them perform onClick only after second tap.
Of course, if you make focusable="false" or android:textIsSelectable="false" it works from the 1st tap, but text selection doesn't work.
Please, help me with that issue
Set in XML to your TextView:
android:textIsSelectable="true"
After that set onTouchListener to your TextView and in them do this:
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus();
It's set focus for every tap on TextView.
After all set onClickListener to your TextView.
I have the same problem with a ViewHolder in my RecyclerView.Adapter. So, I cut it for you if you need:
class RollHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnTouchListener {
private TextView textView;
RollHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text_view);
textView.setOnClickListener(this);
textView.setOnTouchListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.text_view:
// Do here that you need
break;
}
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (view.getId()){
case R.id.text_view:
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus();
break;
};
return false;
}
}
I had the same problem and it's hard to ask and search for a resolution.
Here are two things that I noticed in addition to the double tap behavior:
if you really double tap (quickly) on a TextView with textIsSelectable, it selects the word you tapped, even when the focus is on something else, which means the view somehow registered the first touch as well.
if you long tap while the focus is somewhere else, it works and starts the selection action mode as if it was focused already
Here's how I managed to make it work. It's not beautiful, but everything works fine so far: in the XML you only need to add textIsSelectable, no other focusable / focusableInTouchMode / clickable / enabled attributes needed; then you need two listeners, one is the existing onClick which works, but needs a double take and the other is an onFocusChange where you handle the exceptional first tap:
hint = (TextView)view.findViewById(R.id.hint);
hint.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
handleHintClick();
}
});
hint.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) { handleHintClick(); }
}
});
Here is an alternative solution in a related question which I don't like and didn't even try: wrap the TextView in a FrameLayout and add the listener to that.
Here is another related question which has more solutions.
Use onTouchListener to detect clicks and redirect them to the container view:
textView.setOnTouchListener { _, event ->
if (event.action == 1 && !textView.hasSelection()) {
containerView.callOnClick()
}
false
}
This will keep the ability to select and unselect text without calling onClick event.
android:longClickable="false"
android:clickable="false"
Disable the button with setEnabled(false) until it is safe for the user to click it again.
May this helpful to you
Try this.
use in XML file
android:onclick"your Name"//for example I used "onImageListClick"
public void onImageListClick(View view)
{
//do your task.
//Intent intent = new Intent(this, ImageListActivity.class);
//intent.putExtra(Extra.IMAGES, IMAGES);
//startActivity(intent);
}
or
txtboxname.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
////do you task.
}
});
Related
I have a few imageview which have onclicklistener. If I press one (not release), I can press click others or I can click them same time. I do not want it. Everytime when I press one of them others should be disable to click.
imageview1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getMethod();
}
});
I guess, I tried setClickable(false); but it did not work properly, if I clicked one button after that it worked.
Try using onTouchListener instead of onClickListener and calling setEnabled(false); on the other views there. Here's a fairly basic example:
OnTouchListener onTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
imageView1.setEnabled(false);
imageView2.setEnabled(false);
}
return true;
}
};
And then apply it to the image views with:
imageView1.setOnTouchListener(onTouchListener);
That should work. One thing is, though, that while you'll only be able to push one button no matter what, you also won't be able to push anything after you let go - but, you can fix that by adding some logic to see if the view actually got clicked or if the user touched it, changed their mind and slid away. The (event.getAction() == MotionEvent.ACTION_DOWN) check will be true even if the user is just scrolling.
//button on which press u want to disable others
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
button2.setEnabled(false); //button which u want to disable
button3.setEnabled(false); //button which u want to disable
}
});
//update fixed a spelling error
try to disable the button and
button.setEnable(false);
enable the button
button1.setEnable(true);
I have 2 buttons and I need to read onClick event from second button when first is pressed down now and v.v. Like in keyboards. How to do that?
Edit
No, no! I don't need to check was first button clicked or not. I need to listen another onClick events when first or second button is in ACTION_DOWN state couse if I press first button, I can't press second, but I have multitouch.
May be You could try the following code :
Declare a boolean variable in class.
private boolean button1IsPressed = false;
Write following code for button 1 :
button1.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
button1IsPressed=true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
button1IsPressed=false;
}
}
};
For Button 2 You can do the following:
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(button1IsPressed){
//Write your to do code here
}
}
});
You could try with onTouchListeners. In the first button modify a boolean on the down and up event, in the second button, only perform an action when the boolean is true.
If the buttons are toggle buttons, what I think is the case then:
public void onToggleClicked(View view) {
// Is the toggle on?
boolean on = ((ToggleButton) view).isChecked();
if (on) {
// Do something
} else {
// Disable vibrate
}
}
The main thing here is the isChecked() function, which may be used when checking which one is checked, so to execute something then. You can set in the XML of the two buttons the following:
android:onClick="onToggleClicked" then with isChecked determine which one is checked like this:
boolean on1 = ((ToggleButton) view1).isChecked();
boolean on2 = ((ToggleButton) view2).isChecked();
if (on1)
//do something with button2
if (on2)
//do something with button1
Cheers
There's a sample code in android-16/ApiDemos project called "Views -> Splitting Touches across Views" (SplitTouchView.java). In that sample enclosing LinearLayout has an attribute android:splitMotionEvents="true" which allows to scroll two list views simultaneously.
According to Android 3.0 API Overview this attribute appeared in this api version:
Previously, only a single view could accept touch events at one time. Android 3.0 adds support for splitting touch events across views and even windows, so different views can accept simultaneous touch events.
Found two solutions - please see selected answer
When the user clicks in a certain region of an EditText, I want to popup a dialog. I used onClick to capture the click. This partially works: the first time the user taps the EditText, the soft keyboard pops up and the dialog doesn't. Subsequent taps bring up the keyboard and then the dialog (and the keyboard disappears).
I suspect this has something to do with the EditText gaining focus.
Here's a code snip:
public class PrefixEditText extends EditText implements TextWatcher, OnClickListener
{
public PrefixEditText (Context context)
{
super (context);
setOnClickListener (this);
}
#Override
public void onClick(View v)
{
int selStart = getSelectionStart();
if (selStart < some_particular_pos)
bring_up_dialog();
}
}
IMPORTANT: I don't want to completely disable the normal EditText behavior. I want the user to be able to make region selections (for copy & paste). I probably still want it to gain focus (so I don't break the model when people with physical keyboards use the app). And it's ok for the click to set the cursor position. Thus, solutions that override onTouch and block all onTouch actions from the EditText will not work for me.
UPDATE I've discovered a bit more. If the EditText is gaining focus, onFocusChange gets called and onClick does not. If it already has focus, onClick gets called and onFocusChange does not.
Secondly, it's possible to hide the keyboard by calling
setInputType (InputType.TYPE_NULL);
Doing so in onFocusChange works - the keyboard never shows up. Doing so in onClick (assuming the keyboard was hidden before the click) apparently is too late - the keyboard shows up and then disappears.
The next idea to try would be to hide the keyboard during onTouch. However, I'm afraid to mess with that code - seems that whatever I figure out would be very fragile with respect to future versions of EditText.
Any thoughs on this?
May be this can work
EditText e = new EditText(context);
e.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
if(hasFocus)
{
//dialogue popup
}
}
});
or u can use e.hasFocus(); and then use e.setFocusable(false); to make it unfocus
/////////////// my code
e.setInputType(InputType.TYPE_NULL);
e.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder sa = new Builder(ctx);
sa.create().setOnDismissListener(new OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
// TODO Auto-generated method stub
e.setInputType(InputType.TYPE_CLASS_TEXT);
}
});
sa.show();
}
});
try change capture click by onClick to onTouch
this.editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//dialogue popup
}
return false;
}
});
try this if it can help u.first time the edittext will behave as a normal editttext and on condition u can show the dialog as needed
EditText editText;
mTim_edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
//statement
if(condition){
AlertDialog diaBox = Utils.showErrorDialogBox( "Term in Months Cannot be 0", context);
diaBox.show();
}
}
}
});
After lots of experiments, here are two working solutions! I tested them on my two devices - Nexus 7 running 4.2.1, Kyocera C5170 runing 4.0.4. My preference is Solution 2.
SOLUTION 1
For the first, the trick was to determine the cursor position in onTouch instead of onClick, before EditText has a chance to do it's work - particularly before it pops up the keyboard.
One additional comment: be sure to set android:windowSoftInputMode="stateHidden" in your manifest for the popup, or you'll get the keyboard along with the popup.
Here's the whole code:
public class ClickText extends EditText implements OnTouchListener
{
public ClickText (Context context, AttributeSet attrs)
{
super (context, attrs);
setOnTouchListener (this);
}
#Override
public boolean onTouch (View v, MotionEvent event)
{
if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
{
int line = getLayout().getLineForVertical ((int)event.getY());
int onTouchCursorPos = getLayout().getOffsetForHorizontal (line, event.getX());
if (onTouchCursorPos < 10) // or whatever condition
showPopup (this); // or whatever you want to do
}
return false;
}
private void showPopup (final EditText text)
{
Intent intent = new Intent (getContext(), Popup.class);
((Activity)getContext()).startActivity (intent);
}
}
SOLUTION 2
This one is actually simpler and, I think, is better - fewer side effects.
Here, the trick is to let EditText do all its click processing and then override it asynchronously. The gist is: wait for the touch to "let go" - MotionEvent.ACTION_UP - and then instead of doing your action right then, post a Runnable to the event queue and do your action there.
The whole code:
public class ClickText extends EditText implements OnTouchListener
{
public ClickText (Context context, AttributeSet attrs)
{
super (context, attrs);
setOnTouchListener (this);
}
#Override
public boolean onTouch (View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_UP:
{
post (new Runnable ()
{
// Do this asynch so that EditText can finish setting the selectino.
#Override
public void run()
{
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
// If selStart is different than selEnd, user has highlighed an area of
// text; I chose to ignore the click when this happens.
if (selStart == selEnd)
if (selStart >= 0 && selStart < 10) // or whatever range you want
showPopup (this);
}
});
break;
}
}
return false;
}
private void showPopup (final EditText text)
{
Intent intent = new Intent (getContext(), Popup.class);
((Activity)getContext()).startActivity (intent);
}
}
use this below code snippet
this.editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//dialogue popup
}
return false;
}
});
In my application when I click an EditText, I have to perform some logic. I have the code. But it is not going into the click method.
My code:
EditText des=(EditText)findViewById(R.id.desinc);
des.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
java.lang.System.out.println("Inside click");
EditText income=(EditText)findViewById(R.id.editText1);
// TODO Auto-generated method stub
String inc=income.getText().toString();
int indexOFdec = inc.indexOf(".");
java.lang.System.out.println("index="+indexOFdec);
if(indexOFdec==0)
{
java.lang.System.out.println("inside index");
income.setText(inc+".00");
}
}
});
What am I doing wrong? Help me.
Try overriding onTouch by setting up an onTouchListener in the same way as an onClickListener. Use this code as a reference.
EditText dateEdit = (EditText) findViewById(R.id.date);
date.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
//anything you want to do if user touches/ taps on the edittext box
}
return false;
}
});
UPDATE(why this behavior):
The first click event focuses the control, while the second click event actually fires the OnClickListener. If you disable touch-mode focus with the android:focusableInTouchMode View attribute, the OnClickListener should fire as expected.
You can also try this: set android:focusableInTouchMode="false" for your EditText box in the xml. See if it works with the existing code.
You should use OnFocusChangeListener()
Try clicking EditText twice because at first instance EditText gets focus and after that EditText's click event executes. So, if you want your code to execute on first click write your code for focus change of EditText using OnFocusChangeListener().
I'm trying to display a RatingBar View that is only capable of showing a one star rating, or no stars. This seems so trivial...
My ratingbar is defined like so:
My view implements OnRatingBarChangeListener and OnTouchListener
My OnRatingBarChange handler has no code.
My OnTouch handler looks like so:
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(this.mRating.getRating() == 0)
{
this.mRating.setRating(1);
}
else
{
this.mRating.setRating(0);
}
return true;
}
return false;
}
No matter what, the onTouch event does not succeed at setting the rating back to zero. This seems way too trivial. What am I doing wrong?
Thanks!
Consider using ToggleButton and btn_star stock drawable instead. Here's example:
<ToggleButton
android:button="#android:drawable/btn_star"
android:background="#android:color/transparent"
android:textOn=""
android:textOff=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The RatingBar is extended from the SeekBar and the listener actually expects a slide action. Thus the RB can't be set to 0 (or not for this purpose) when there is only one star. The proper widget to use for this type of functionality (no surprise here) is the ToggleButton.
I had the same problem, trying to use a single star RatingBar as a favourite button. But the ToggleButton is exactly what you need for this type of thing.
This is what I implemented for the ToggleButton. (The _favourited bool was specifically used for something in my code, I can't remember now)
favourite_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!_favourited) {
// Do stuff
_favourited = true;
} else {
// Do stuff
_favourited = false;
}
}});