I am developing an Android application.
I implemented a View Pager with Tabs, as described in this link, with a FragmentStatePagerAdapter, and adding the tabs to the ActionBar on the OnCreate method of the Activity.
On my onCreateView event of my frament, I am inflating a layout that contains an EditText View, so each generated Tab has its own EditText for the user to enter data.
The thing is, I currently need to locally store the content of each textbox once its been fully filled with the input the user is writing in each EditText control. For example, I can know that the user is finished entering data, when they change the tab, or unfocus the control.
SCENARIO 1:
I tried attaching a TextWatcher to the EditText control in my onCreateView event of the fragment, but it didn't work for me because I don't need it to be called every time a letter is inserted in my control, so I discarded that option
SCENARIO 2:
I tried attaching a OnEditorActionListener to the EditText control in my onCreateView event of the fragment, but it's never called (like this link explains)
SCENARIO 3:
I was thinking of handling the onTabUnselected event of the TabListener, but I don't know how to access the PREVIOUS EditText control value. Besides, that will only work when the user selects the tab by pressing its header, but not on the swipe event. In that case I am attanching a SimpleOnPageChangeListener to the ViewPager, but again, in that context, I can't know which was the previous Tab, nor can I access its EditText control.
What can I do?
Thank you very much!
When the EditText lose focus, you simply need to add focusChangedListener to the EditText:
OnFocusChangeListener focus = new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
}
};
Every time the edit text lose focus just add the data to a singleton class that holds all of the data, from all of the TextEdits, check this out
android get value from all fragment tab
Related
I have a Layout,
that has a form .. about five items down in the form is a spinner, and everytime my activity loads Talkback seems to read this spinners content description even though the focus and flashing cursor are on the first edittext view.
I can't seem to stop it.. any ideas?
Accessibility Focus and Input Focus are tracked separately in Android. I would need more details about your specific scenario to provide a 100% answer. However, my guess is that your EditText field is requesting input focus when the view loads, so the cursor is being moved there, and potentially the keyboard is popped up (depending on Android version). However, due to tab ordering, or some other mechanism, the spinner is the first item on the page to get Accessibility Focus.
There are two solutions to this, depending on the behavior that you want.
Solution 1 (recommended): Don't have your EditText box request input focus. Allow the user to force input focus into the box on interaction. For capable users, this is just a simple tap into the EditText box.
Solution 2 (less accessibile, but perhaps more usable): Shift accessibility focus to the EditText in your onResume method (or onCreate, or wherever you deem most appropriate). A method like this would be best:
public void resetFocus() {
editTextControl.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
editTextControl.requestFocus();
}
I would recommend calling the above method in onResume, so that every time this particular view loads input and accessibility focus will be in a predictable place. Otherwise, you've created additional accessibility issues.
I solved it simply like this:
/*
This custom Spinner has the purpose of making sure that there are no accessibility events fired after
a selection is made
*/
public class SilentSpinner<T> extends SimpleSpinner<T> {
//region constructors
...
//endregion
//region public methods
#Override
public void sendAccessibilityEvent(int eventType) {
if (eventType != AccessibilityEvent.TYPE_VIEW_SELECTED) {
super.sendAccessibilityEvent(eventType);
}
}
//endregion
}
I have been looking and scouring around the web, even tried to check the official Android doc for "communicating between fragments" or communicating with fragment and activity (http://developer.android.com/training/basics/fragments/communicating.html), and even tried searching a few questions here at StackOverflow just to get a hint to my problem, but none of them seem to answer my case.
I know of the interface listener that is implemented by a host Activity to pass data from Fragment to the host Activity, and used it A LOT in my projects. But I think that model of fragment data passing is actually useful only if there is a "meta" event i.e. onClick, onItemClick, etc) that would fire that custom event.
But for my case, I have a Fragment containing RadioGroup, with the RadioGroup's content, first of which is a view group with several EditTexts, in which I need to send its contents back to the Fragment's host Activity with several other objects. My custom event is being fire by a "meta" event, that is, the RadioGroup.setOnCheckedChangeListener().
To visualize, this is how it is layed out in my layout resource:
RadioGroup
-RadioButton 1
--- LinearLayout (which is toggled to be shown by checking RadioButton 1, hidden when other RadioButton is checked) containing several EditText s
------EditText 1
------EditText 2
------EditText 3
------EditText 4
-RadioButton 2
-RadioButton 3
-RadioButton 4
Every time I check RadioButton 1, it toggles to show the LinearLayout with the EditText, obviously it fires setOnCheckedChangeListener() of the RadioGroup, within which it fires my custom event with parameters like a custom object with contents coming from the EditText s. HOWEVER, my custom event won't be called when I don't check the RadioGroup and when I edit/update the EditText.
I think of using EditText.addTextChangedListener() on those EditTexts and fire my custom event whenever I fill all the data on my form. But I think it's a bit not elegant to do that, and I guess there would be a more elegant and better, if any, way of passing those EditText data from their host fragment back to the Activity, or may be to get the data from Fragment in to the Activity
My question is, how do I pass OR get data FROM fragment to Activity in which I won't depend on "meta" events to fire my custom event or in some other way around.
To communicate back to my activities, I simply add a method which the fragment can call directly. In the Activity class:
public void sendMessage(String message) {
// Do something with the message
}
In the fragment:
((MyActivity)getActivity()).sendMessage("Code Apprentice is the best!");
Basically, I have a list of detail fragments and each one represents a list of peers of that phone. When one of these DeviceDetails is tapped on, a selection of buttons and text appears. Which of these buttons and text appears depends on the status of the phone; it is either connected to the phone being used, or it is available for connection.
I currently use the fragment's onCreateView to make 3 buttons appear. 1 of these buttons should appear every time, and the other 2 alternate depending on the connected/available state.
I am trying to figure out which overridden fragment method should handle the changing UI's. It should just be a case of if statements (or maybe switch statements?) but I am not sure where to place these?
Well if let's say you have an Activity and it is hosting all these Fragments.
I assume there is some event that triggers this state to happen, maybe in that Activity
public void onSomeEventThatICareAbout(EventDetails deets) {
Fragment fragment = getFragmentManager().findFragmentById(R.id.my_fragment_with_buttons);
if (fragment != null) {
((MyButtonsFragment)).disableButtons(deets);
}
}
Basically just treat the fragment like any other component and call methods on it based on events like normal, whether it is an onClick(), a AsyncTask callback, or whatever. Just call the function right on the fragment.
Define your own way for your fragment to do what you want,
public void disableButtons(EventDetails deets) {
View view = getView();
view.findViewById(R.id.button1).setEnabled(false);
view.findViewById(R.id.button2).setEnabled(false);
}
I currently have a ListView and each element of that list consists of at least two TextViews. I'm adding accessibility to my app, so whenever I focus on a certain list element, it reads out the text in each TextView.
Right now, I'm sending it a TalkBack event, but right after it completes it, it reads out the TextViews again. I want it to only complete my TalkBack event and nothing else.
Anyone have a clue how to do this?
Thanks in advance!
Sure, just override View.dispatchPopulateAccessibilityEvent.
From the doc (emphasis mine):
A typical implementation will call onPopulateAccessibilityEvent(AccessibilityEvent) on the this view and then call the dispatchPopulateAccessibilityEvent(AccessibilityEvent) on each child. Override this method if custom population of the event text content is required.
Within that method, you can add any text you want to the event in the following manner:
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
event.getText().add("Hey look!");
return true;
}
I'm not sure if my title is clear so let me explain.
Tab A - contains a listview populated from a database
Tab B - search form
I need to update the contents of tab A after coming back from a search results screen. Using onResume() works great but this also reloads the Tab whenever I click back and forth through between tabs. Is there another method I could use here?
EDIT: I guess it's a bit more complex than this. The search form loads a new intent that displays the results in a listview. An item can be select which then loads a item info screen. From here the user can select from a few option, one being Add. This is the action that needs to reload the original listview in Tab A.
In tab A trigger the search activity with startIntentForResult() and then in onActivityResult() get your Adapter of the ListView and set the new data of the ListView.
You can use onWindowFocusChanged method if you need to add some more process when getting the focus for a particular tab..
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
//You can add your own method to refresh data within the tab //(Ex: refreshData())
super.onWindowFocusChanged(hasFocus);
}