I believe I may have found a bug in the Android UI, but I'd like to make sure I'm not doing something flat out wrong. Here is a simplified version of the code I'm running that's causing the problem. This listener is set on a specific NumberPicker in my UI, and it properly disables / enables things, but if the user has changed the value of one of the other NumberPickers that it disables, it behaves a little bit oddly.
It still properly disables the input, but it fails to grey the value out, making it look like it's still enabled. Is this intended? Am I doing something wrong?
NumberPicker.OnValueChangeListener diceChangeListener = new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
View parent = (View) picker.getParent();
if (newVal == 0) {
((NumberPicker) parent.findViewById(R.id.diceCountPicker1)).setEnabled(false);
} else if (oldVal == 0) {
((NumberPicker) parent.findViewById(R.id.diceCountPicker1)).setEnabled(true);
}
}
};
Let me know if there's a better way to do this, or if this is a legitimate bug. If it is a bug, is there a way to work around it?
Edit: Here's the definition of diceCountPicker1 in the XML:
<NumberPicker
android:id="#+id/diceCountPicker1"
android:layout_width="48dp"
android:layout_height="128dp"
android:descendantFocusability="blocksDescendants"
/>
Edit 2:
I have tested this in emulators, and confirmed that the problem doesn't exist before Jellybean (4.1). It works properly in ICS. That's... annoying. But I may be able to live with it for now. I'll leave this open for potential ways to work around the bug, but it looks to me like a real bug, and I doubt it can be fixed.
Try in this way.
NumberPicker npicker = (NumberPicker) findViewById(R.id.diceCountPicker1);
npicker.setMaxValue(100);
npicker.setMinValue(0);
npicker.setOnValueChangedListener(new OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal,
int newVal) {
// Conditions for Enable/Disable picker
if (newVal == 0) {
picker.setEnabled(false);
} else if (oldVal == 0) {
picker.setEnabled(true);
}
}
});
It works well for me and it is behaving properly with Enable/Disable as per added conditions.
Thanks.
Well, with no additional feedback coming in on this, I'm going to go ahead and close it out. Here's what I know:
This appears to be a bug introduced in Jellybean. I have tested in emulators, and the UI works as expected in ICS and earlier. For the time being, I'm just going to deal with this, and attempt to submit an official bug report.
Setting android:enabled="false" in NumberPicker and DatePicker xml layouts doesn't gray-out the controls for me on Android 4.0.4 device. However doing so programmetically via setEnabled(false) works as expected.
Related
I am using EditText's to accept an OTP, where user has focus on next EditText once he enters a digit to a field and so. It works fine on all devices. But on devices running android OS P i.e. API 28, requestFocus() does not work, and user is not able to enter digits to consecutive EditTexts as focus doesn't move automatically.
Here is the code - by default all EditText's are disable to prevent from opening system keyboard. I am using my own CustomKeybaord to accept numbers. However it works except Android P.
mEtCode1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
Log.d("BEFORE_", charSequence.toString());
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
hideError(charSequence.toString());
if (!charSequence.toString().isEmpty()) {
mEtCode2.requestFocus();
mEtCode1.setBackground(getResources().getDrawable(R.drawable.verify_code_edit_text_background));
mEtCode2.setBackground(getResources().getDrawable(R.drawable.verify_code_edit_text_background));
mEtCode1.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Please help me with this
Thank you, in advance
I had the same issue with my OTP screen on devices with Android P sdk. The problem was that i set the height and width of the editText to 0dp, which is focus disabling in android P,
as described in Android Developer page in the Android P change log:
android-9.0-changes-28#ui-changes
Views with 0 area (either a width or a height is 0) are no longer focusable.
This is issue with Android P. And what worked for me is the following code block, So sharing here:
enterOtpTextFrame.postDelayed(Runnable {
enterOtpTextFrame.requestFocus()
}, 100
)
we require to call requestFocus with postDelayed with some small time amount. In my case it is 100 millisecond.
Here is the official documentation for requestFocus method. It states there that it only works if the desired view for which you want to have focus is enabled, has size, is visible, is focusable and is FocusableInTouchMode.
I had exact same issue. I was using databinding to set the enable state of my EditText. I realised that requestFocus was not working because databinding, due to some unknown reasons, was not enabling my textview in time.
Here is my code:
/*
setMyEditTextEnabled is my method to which my view is binded i.e.
android:enabled="#{vm.myEditTextEnabled, default=false}"
This worked for all version except Android P because it has
some timing issues with API 28 (not sure what)
*/
//binding.getVm().setMyEditTextEnabled(true);
/*
So to make it work, I am enabling my EditText directly and
it works for all versions.
*/
binding.myEditText.setEnabled(true);
binding.myEditText.requestFocus();
Also, as mentioned in following post: EditText requestFocus not working
Do set focusable and focusableInTouchMode to true as well.
In short, my point is to make sure that your edit text is fulfilling all requirements as mentioned in official doc in order to requestFocus to work.
Encountered a similar problem when popping an alert dialog. In my case, postDelayed'ing a focus request or forcing the soft keyboard to pop up didn't work. Even if I could manage to pop up the keyboard, the focus stayed on an EditText in the main activity; needless to say I have tried clearing its focus and even disabling it.
However, popping the alertDialog delayed did the trick:
final AlertDialog alertDialog = alertDialogBuilder.create(); //a builder of your own
final Runnable r = new Runnable() {
public void run() {
alertDialog.show();
}
};
editTextOnMainActivity.postDelayed(r, 100);
In my app, I have an EditText, with a button to change the keyboard input type. The code:
ToggleCambiarTeclado.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (ToggleCambiarTeclado.isChecked()) {
tipoDeTecladoActual = InputType.TYPE_CLASS_NUMBER;
imagenTeclado.setImageDrawable(getResources().getDrawable(R.drawable.keyboard_numeric));
} else {
tipoDeTecladoActual = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
imagenTeclado.setImageDrawable(getResources().getDrawable(R.drawable.keyboard_querty));
}
editNumeroContador.setInputType(tipoDeTecladoActual);
}
});
It works perfectly in my phone...but my boss has a Samsung, and is not changing the keyboard type in his phone.
I have tried changing it to TYPE_TEXT_VARIATION_NORMAL, TYPE_TEXT_VARIATION_VISIBLE_PASSWORD and YPE_CLASS_TEXT, neither of them are working.
Anyone knows if this is a bug? Any known workaround?
Thank you.
EDIT:
Just realized my boss has TouchPal installed. If he changes the default keyboard to the standard it works perfectly...
Later Samsung devices have SwiftKey keyboards built in. SwiftKey intentionally decided at some point to ignore Android's InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS.
A workaround is to use InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD, which is somewhat hacky, but an unfortunately common workaround.
XML variant: android:inputType="textVisiblePassword"
Samsung's behave weirdly with most things. I've had this issue before and I seem to recall that changing the input type to email worked like a charm. Give it a try.
I have been successfully running an app under android 2.2 (api8) using spinners with OnItemSelectedListeners. It was built with tarketSdkVersion = 8 and minSdkVersion = 8. I am now trying to run it on a 3.2 device, but the spinners can not be selected. They do populate with the default array value however, so the adapter appears to be working. Clicking on the spinners results in no reaction. I tried building with tarketSdkVersion = 13 and minSdkVersion = 13, but the spinners are still dead. I am using slightly customized spinner versions to achieve "wrap_content" in a multiline_spinner_dropdown_item.xml file. Is there a compatibility issue with spinners since 2.2?
I tried the .setEnabled(true) but it didn't work. In frustration, I started to remove sections of code from main.java and layout.xml until a single spinner was left and working. As I added the code and controls back, I found that a ScrollView nestled inside a TabHost/LinearLayout/TabWidget/FrameLayout prevented the Spinners from responding. By removing the Scrollview, the Spinners worked in 3.2. For some reason the Scrollview worked in 2.2, but not 3.2.
I had the same problem, I used the spinner in 2.2 ,it was working but the same do not work in 3.2, The problem was with the default theme of 3.2, its holo. because of that the spinner is not shown properly,
Just create a theme in values/style, and apply it to your activity in android.manifest file.
Are you by any chance changing the visibility of the spinner?
I had a similar problem, and it was necessary to call setAdapter() every time the spinner was re-shown, otherwise it became immune to clicks.
You can see the change I made to my project that fixed this problem at https://github.com/nikclayton/android-squeezer/commit/7a148edf5f1b3eaca7718161de18254970290ce0.
Perhaps some visibility issues ?
Are you stacking the ScrollView on top of the area where the spinners' items show up ?
Try to use different states for the spinners by changing their icon or color for example and see if they get the click event. If they do, then it is probably something related with visibility. If they don't, it might something else.
Some code sample could help :)
Have you tried setting the spinner as enabled?
spinner.setEnabled(true);
Although it would be weird that it was disabled on default. Your symptoms do describe a disabled spinner though
Oddly, I tried another app of my that works great on 2.2. When I installed it on a 3.1 tablet or emulator, the onClick events won't fire. No spinners this time, but the listeners don't work either! Here's some of the code:
//In onCreate:
//setup listeners
rbSlab = (RadioButton)findViewById(R.id.rbSlab);
rbBeam = (RadioButton)findViewById(R.id.rbBeam);
rbSlab.setOnClickListener(radio_listener);
rbBeam.setOnClickListener(radio_listener);
etFpc.setOnEditorActionListener(this);
etFy.setOnEditorActionListener(this);
etBw.setOnEditorActionListener(this);
etDp.setOnEditorActionListener(this);
etMu.setOnEditorActionListener(this);
...
}//end onCreate
//In Main body of app:
//for radio buttons
private OnClickListener radio_listener = new View.OnClickListener()
{ //#Override
public void onClick(View v) {
DoCalcs();
}//onClick
};
//for edittext
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{ if ((actionId == EditorInfo.IME_ACTION_DONE) || //if DONE button pushed
((event.getAction()==KeyEvent.ACTION_DOWN) && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER))) //if ENTER button pushed
{
//do calcs
return(true);
}
else return(false);
}
I've built this with target API 8 and min API 8, and also with target API 14, min 8, and when installed on a API 8 the listeners work fine, but not with API 14!
I had a similar problem. It's because of the default theme of Android 3.2 and above versions.
The simpler solution is to use a custom spinner, or to make any background colour or picture for the same, like:
android:background="#drawable/spinner"
This link will help you for custom spinner.
after fixing another problem in my Android Application, i came to another thing.
It would be important that i can do something, like hide some visual elements, if the SoftKeyboard so a Input like Swipe or the normal Android Keyboard is shown.
I've tried the onConfigurationChange="KeyboardShow" (pseudocode) but had no change to get a event when for example skype got shown.
So now my question is, is there any solution or function or listener, with which i can handle such a action?
I hope someone can help me.
Sincerly,
Mike Penz
There might be better approaches, but a possibility is to add: android:configChanges="keyboardHidden" to the manifest. That will fire with any keyboard changes, so the you will need to query the Configuration object
static Configuration prevConf = Configuration();
static int ignoreMasks = Configuration.HARDKEYBOARDHIDDEN_NO|Configuration.HARDKEYBOARDHIDDEN_YES;
onCreate() {
prevConf = setToDefaults();
}
// all your code here
#Override
public void onConfigurationChanged (Configuration newConfig) {
int deltas = newConfig.diff (prevConf); // what changed?
prevConf = newConfig;
if (delta & ignoreMasks)
return; // you're not interested in hard keyboards.
// your code here
}
I suck at bitwise operators, so you might need to work around that.
This is the API documentation:
http://developer.android.com/reference/android/R.attr.html#configChanges
http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged%28android.content.res.Configuration%29
http://developer.android.com/reference/android/content/res/Configuration.html
I'm currently fighting against the OnLongClickListener on Android Api Lvl 8.
Take this code:
this.webView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
System.out.println("long click");
return true;
}
});
It works perfectly. I can press anywhere on the WebView and the event triggers every time.
Now take a look at this one:
this.webView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final EditText editText = getUrlTextField();
switch (editText.getVisibility()) {
case View.VISIBLE:
editText.setVisibility(View.GONE);
return true;
case View.GONE:
editText.setVisibility(View.VISIBLE);
return true;
default:
return false;
}
}
});
Assuming the URL EditText components is currently visible, it gets gone from the display and should be shown again when another long click event is triggered.
But if you run this, the event just works once (!) when one performs a long click on any position on the WebView. To make things complicated, the long click works again when it is performed on a link on the website...
Can anyone explain if it is a bug in the sdk and/or if there is a mistake in my thinking how the OnLongClickListener is working?!? :/
EDIT:
I've run now several different scenarios on a Nexus One and come to following conclussion: Changing the layout on runtime more or less kills the OnLongClickListener... I haven't found a way to get it work reliably at all...
I would really appreciate if anyone could give me a hint... I'm at my wits end :(
Personnally, I ended up by re-setting the listener after each relayout.
I've run into this issue as well. It seems that if the view layout changes in a way that child view bounds need to be modified (i.e. TextView is wrap_content width and you set its text to something longer/shorter than it was before), views in the hierarchy will have their onStartTemporaryDetach method called (most likely due to a layout pass, although I haven't dug deep enough to find out for sure). If you look at the source for View that onStartTemporaryDetach ultimately unsets the pressed state of the view.
Changing the views in your layout that will be updated periodically to have bounds that will not change regardless of the value you set, will fix the issue. Although, that is still not awesome.