In my android app
I need to check whether a particular view is focussed.
Now I found the getCurrentFocus() function in Activity class
but this returns a View Object.
How can I compare and check whether this returned View is same as the one in question.
I mean there is no getName() function here.
So after getting the View object, how can I compare to check which View class is this ?
The View.isFocused() method tells whether the view in question is focused or not.
if (myView.isFocused()) {
// your code
}
If you still want to use the getCurrentFocus() method, you can simply check:
View focusView = getCurrentFocus();
if (myView == focusView) {
// your code
}
Or else, you can compare your views by id.
View focusView = getCurrentFocus();
if (focusView != null && myView.getId() == focusView.getId()) {
// your code
}
You could use the getId() method I guess?
e.g.
getCurrentFocus() == R.id.myView;
getCurrentFocus() on the parent view
http://developer.android.com/reference/android/app/Activity.html#getCurrentFocus%28%29
No need for getName(). Just use the == operator. See:
View myView = findViewById(...);
if (activitygetCurrentFocus() == myView)
// ha focus
}
Another option, one I usually prefer, is to set a focus listener for the views you are interested in monitoring:
myView.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
// got focus logic
}
}
});
Related
Let's say I got a fragment (of a ViewPager) with an EditText and I got somewhere this line of code: myEditText.setError("there is an error");
Now I want to know if I should allow the user to move forward to the next page. How can I check if there are any validation errors in the ENTIRE fragment (not just the single edit text from my example) in order to determine if the user can move to the next page? something like if(!this.containsErrors()) return true;
you can check the return value of TextView's getError():
Returns the error message that was set to be displayed with
setError(CharSequence), or null if no error was set or if it the error
was cleared by the widget after user input.
if (TextUtils.isEmpty(myEditText.getError()) {
// go ahead, no error set!
return true;
}
a simple routine to make the check could be:
boolean isErrorFree() {
ViewGroup viewGroup = (ViewGroup) getView();
if (viewGroup == null) {
return true;
}
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View view = viewGroup.getChildAt(i);
if (view instanceof TextView) {
if (!TextUtils.isEmpty(((TextView)view).getError()) {
return false;
}
}
}
return true;
}
check for typo
I am trying to fire a custom AccessibilityEvent using the AccessibilityManager and TalkBack.
The use case for the event is when the user clicks an action bar, the fragment polls a list of objects, and then fashions its AccessibilityEvent content based on the size of a list.
When I try to run this, I do not get the expected TalkBack message. I am pretty sure that I'm missing something basic with instantiating an AccessibilityEvent.
I am also not sure whether I need to use, or how to apply AccessibilityDelegates here because the callback is coming from a MenuItem rather than a View. I know I can call findViewById to get the view for this MenuItem, but I am not very knowledgeable on these APIs.
Any guidance on these two points would be great!
The problem in question is described basically by the following pseudocode:
public class MyFragment extends Fragment {
//...
private List<Pojo> mPojoList;
//...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.the_id_for_my_menuitem) {
if (booleanCheck() && !mPojoList.isEmpty()) {
//create the Accessibility event
final AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_CLICKED);
event.setContentDescription(String.format("deleting %2d pojos", mPojoList.size()));
//Send a custom accessibility event to let the user know that we're deleting X objects.
final AccessibilityManager mgr = (AccessibilityManager) this.getActivity().getSystemService(Context.ACCESSIBILITY_SERVICE);
//PROBLEM: We're not seeing this event come through in TalkBack.
mgr.sendAccessibilityEvent(event);
//Delete the objects.
myDeleteObjectsFunction();
}
}
}}
Try to fire accessibility events using View object.
AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_CLICKED);
event.setContentDescription(String.format("deleting %2d pojos", mPojoList.size()));
View view = getActivity().findViewById(R.id.child_view);
ViewParent parent = view.getParent();
if (parent != null) {
parent.requestSendAccessibilityEvent(view, event);
}
Although it is an old question, I'm going to publish my answer because the answer gave before did not work for me.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.the_id_for_my_menuitem) {
if (booleanCheck() && !mPojoList.isEmpty()) {
AccessibilityManager manager = (AccessibilityManager)this.getSystemService(Context.ACCESSIBILITY_SERVICE);
if(manager.isEnabled()){
AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
event.setClassName(getClass().getName());
event.getText().add(*yourString*);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
event.setSource(findViewById(*yourButton*));
}
manager.sendAccessibilityEvent(event);
}
}
}
}
In one of my activities I have three EditTexts and an OK button. The OnFocusChangeListener is set to all three EditTexts. The listener should trigger every time the focus is lost.
Switching between EditTexts works perfectly. But if the user presses the OK button there's no focus change (losing the focus) triggered for the EditText the user focused before pressing the button.
What's wrong with my code?
private class MyOnFocusChangeListener implements OnFocusChangeListener {
private EditText editText;
public MyOnFocusChangeListener(final EditText editText) {
super();
this.editText = editText;
}
#Override
public void onFocusChange(final View view, final boolean isFocused) {
if (!isFocused) {
if (editText == editText1) {
// Do a calculation
} else if (editText == editText2) {
// Do another calculation
} else if (editText == editText3) {
// Do a different calculation
}
}
}
}
#Override
public void onCreate(final Bundle bundle) {
// ...
editText1.setOnFocusChangeListener(new MyOnFocusChangeListener(editText1));
editText2.setOnFocusChangeListener(new MyOnFocusChangeListener(editText2));
editText3.setOnFocusChangeListener(new MyOnFocusChangeListener(editText3));
// ...
}
You could try to clear the focus when user click on OK or other button....
e.g.
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
editText1.clearfocus();
editText2.clearfocus();
editText3.clearfocus();
....
}
}
You might want to try using: addTextChangedListener(..) in this case.
Sounds like you could be having issues with touch mode, from the android docs:
"The relationship between touch mode, selection, and focus means you must not rely on selection and/or focus to exist in your application."
To expand on #dong221, and incorporating the comment made by #Harald, one way to clear the focus without having to keep track of the last selected EditText is to get a reference to the currentFocus from the window object. Something like this:
myDoneButton.setOnClickListener { v ->
// Assuming we are in an Activity, otherwise get a reference to the Activity first
window.currentFocus?.clearFocus()
}
It works if you bind onFocusChangeListener to the view element you want to be observed
editText.onFocusChangeListener = this
editText.setOnClickListener(this)
by keyword this it means the ViewHolder class
I have read some code that people use something like this
view.setOnLongClickListener(null);
What does it means and for what can be useful ? why someone uses this ?
is that the same as this
view.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
return true;
}
});
Null would remove any callbacks that are currently set as the views listener.
It definitely isn't the same as the second one, which assigns a listener to the view to control what will happen when you perform a long click on your view.
I have found that when using a d-pad or trackball to navigate in my app if you move to the right and the list view looses focus, when the list view regains focus, a different child is given focus than last had focus. I tried to use onFocusChange(...) to save which child had focus but it looks like this isn't called until after the focus is lost so I can never grab which child last had focus. Is there a way to grab who had focus so I can then call requestFocus() on the child once the list view grabs focus again?
Unfortunately I cannot use a handler because this isn't a much used feature and I don't want to sacrifice the performance for a smaller feature.
Here is the code I had that didn't work (focusedView was always null no matter what):
mainListView.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(focusedView == null ) { Log.i("focus", "focusedView == null"); }
if(hasFocus && focusedView != null) {
Log.i("focus", "Focus has been Recieved.............");
focusedView.requestFocus();
} else {
// Focus has been lost so save the id of what the user had selected
Log.i("focus", "Focus has been Lost.............");
focusedView = mainListView.findFocus();
}
}
});
Thanks!
I think you are spot on with your own answer, bascially since the focus listener is called after its lost focus, no child will be in focus and therefore .findFocus() will return null.
I recon you best bet is to extend the ListView class, and override the onFocusChanged method. Basically do what you are doing, but do it inthere when gainFocus is true.
#Override
protected void onFocusChanged (boolean gainFocus,
int direction, Rect previouslyFocusedRect) {
if(gainFocus)
focusedView = mainListView.findFocus();
}
This one