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;
}
});
Related
I have a RecyclerViewClickListener.RecyclerTouchListener and on that #onClick override method, I sat Intent to go another activity.
But the problem is on that RecyclerViewClickListener.RecyclerTouchListener there is one image view also and I implemented onClickListener of that InmageView so that it will open one dialog box.
Now, when I click on that ImageView, 2 things happened at same time.
1.Opened Dialog box
2.It is going to another activity also, because of Intent.
How can I fix?
Try this
holder.hamburgerMenu.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
if (menuInterface != null) {
menuInterface.onClickHamburger(position);
}
return true;
}
return false;
}
});
I am trying to make some field with text (no button) what I click on to open datepicker dialog.
I am totally begginer and I am trying it on easy example.
firstbirth.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Toast.makeText(getApplicationContext(), "ahooj", Toast.LENGTH_LONG).show();
return false;
}
});
firstbirth is spinner, I tried it with Edittext and the result was same.
Can anybody help me?
Thanks in advance!
Use an OnClickListener instead.
setOnClickListener(View.OnClickListener l)
OnTouchListeners will trigger on multiple touch events (like touch down, touch up etc.) whereas the OnClickListener will only get fired once (onClick :) )
If you, for some reason, want to use an OnTochListener you can make sure that its only called once.
Try:
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP { // another option would be ACTION_DOWN for example
Toast.makeText(getApplicationContext(), "ahooj", Toast.LENGTH_LONG).show();
return true;
}
return false;
}
Thanks it sounds logical but when I use OnClick event application felt down while initializing.
firstbirth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DialogFragment dd1 = new DatePickerFragment();
dd1.show(getFragmentManager(), "Select a date");
}
});
Problem is not with DialogFragment becasue it works when I use onTouch event.
Thanks :)
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.
}
});
I'm trying to override the soft input keyboard for a singular EditText field. I've mostly been following this excellent example -- setting the XML to inputType="text", and then, within the onCreate:
EditText amount = (EditText) findViewById(R.id.amount_edit_text);
final EditText amt = amount;
amount.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
showCustomKeyboard(v);
} else {
hideCustomKeyboard();
}
}
});
amount.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showCustomKeyboard(v);
}
});
amount.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType();
edittext.setInputType(InputType.TYPE_NULL);
edittext.onTouchEvent(event);
edittext.setInputType(inType);
return true;
}
});
This works for the most part -- clicking on the EditText brings up my custom keyboard, but there's always a jump. It's very quick, but it'll show my keyboard stacking on top of the standard keyboard, and then the standard keyboard will collapse and my keyboard will be left. And at times, it will arbitrarily not collapse and simply just stack...
Is there any way to override the standard keyboard with my own without this jump?
I ended up using a Runnable to close the standard keyboard before showing my custom keyboard. It's not quite perfect, but it doesn't stack the two keyboards like it used to. I'll keep looking for a better solution though.
within the else statement of my OnFocusChangeListener:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
showCustomKeyboard(v);
}
}, 250);
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(v.getWindowToken(), 0);
Try to hide the softKeyboard when you are showing yours, using the following code:
InputMethodManager mgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(amount.getWindowToken(), 0);
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().