How to activate Talkback inside of an fragment's views? - android

I'm currently adding accessibility as a new feature inside my app.
My goal is that the user would be navigating it using the TalkBack service integrated by Android.
Everything is working well, since I'm setting content description on the elements that are inside my activity layout i.e.
<View
style="#style/custom.style"
android:contentDescription="#string/my_string_value"/>
This way, every time that my activity is displayed the TalkBack is reading the content description value.
I haven't had the same success using just one activity which is pushing several fragments on it. So if I try to set a content description on any element inside the fragment layout this is not gonna be read (automatically) till it detects a touch event (I'm expecting to the TalkBack does it automatically, just like the views that are in the activity layout)
In order to get a result as the one that I expect I this this inside the fragment class:
public abstract class myFragment extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
myCustomView = (LinearLayout) rootView.findViewById(R.id.duende);
myCustomView.requestFocus();
}
}
This haven't had success so far, same thing setting the accessibility as a content changed.
getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
Does anyone had faced a similar issue?

Not sure your still looking for the solution but for future seekers :) -
Many times the focus request works only once called from within a post/postdelay function.
Example -
myCustomView.postDelayed(new Runnable() {
#Override
public void run() {
myCustomView.setFocusable(true);
myCustomView.requestFocus();
myCustomView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
}
},1000);
While working with fragments, I like calling both the focuses, input focus, like called by the guy in the previous answer, and the accessibility focus because while implementing accessibility onto fragments you can get pass some irritating problems. hence this always does the job for me.

First, it's important to note that Fragments function no different than layouts within normal activities. Fragments are just a convenient way of structuring the code. What Android/the Accessibility APIs see if you code up your application as a series of fragments, or a bunch of layouts within a single activity is identical. That being said, I believe what you're looking for is the following:
What you need to do is move accessibility focus.
myCustomView.requestFocus();
is moving what I consider input focus. This will have no effect on TalkBack, and is in fact all but completely meaningless, unless you are using keyboard navigation, or we are talking about an EditText box. What you want to do is move Accessibility/TalkBack focus. This can be accomplished with the following line of code:
myCustomView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
NOTE: Please keep in mind WCag 2.0 criteria, especially when it comes to moving focus around on TalkBack users automatically. This can become very confusing for non-sighted users!

Related

Android InputManagerCompat.InputDeviceListener custom class not receiving callback on any method

I have an Android application that uses a class extending the following type:
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class GamePadController extends View implements InputManagerCompat.InputDeviceListener {
// The current device that is controlling the ship
private InputDevice mInputDevice;
private int mDPadState;
...
When I run the apk in a mobile sometimes the Gamepad is captured in android and my custom methods onGenericMotionEvent and onKeyUp are called.
It is a random behaviour, sometimes my methods are called and my behaviour is executed but sometimes only the default behaviour happens (like if my classes were not registered).
Things I observed:
In any case when I run the app it takes some time for my methods to
be called, like if there was some lazy loading that I should force
sooner (maybe).
The code my changes is based on did work, but I introduced
other things that don't look related at all (other classes, a thread)
No exceptions or errors in the LogCat, already made sure of no empty catches and things alike
Do you have any clue or advice on this behaviour?
Thanks in advance
So it seems like I was putting the callback methods in a specific View within the Activity (which had other elements like textviews), meaning that only when that specific element was focused the input was captured in the callback... that is why the documentation tells you to put the callbacks in the Activity or the View... probably it made more sense to put this behaviour in the activity so it was captured no matter what was in focus.

Android Calling objects from fragments

I'm not sure the best way to go about what I intend to do. I have an app that involves three fragments, each navigated to by a single activity that has a navigation drawer.
I have a text to speech class that initialises the text to speech engine. The problem is, is that it needs to be used by multiple different fragments. My idea was to create an object of the TTS class in the main Activity and extend functions so that they can be called by the fragments, like so:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTextToSpeechService = ((NavigationActivity)this.getActivity()).GetTextToSpeechService();
}
The problem I see here is, what if I need to do something such as change the language within one fragment. That would mean I'd have to expose another function to set the TTS class within the activity, which doesn't seem right.
What is the best way to go about this?
There are three options:
Inherit from application and store singleton there. You can see how to do that here.
Create started service and use it from activity.(not bounded) See the link.
Store language setting in SharedPreferences and apply them to textspeech engine in activity lifecycle methods (onResume method).
Services are designed for tasks which are not connected to UI. If it's too much work to be done you may find third option to be a candidate for this particular problem.

Fragment not instantiating correctly

I'm having a problem instantiating Fragments in my program using the Support Library implementation. Here's a brief description of the task I'm attempting to perform and some of my attempts which haven't yet borne fruit:
The UI of my application is subject to change to meet user preferences. In order to do this, I'm using a Fragment for each different layout and replacing the active Fragment in the UI at a given time as per the user's instructions. Here are some ways I've tried (and failed) to do this:
I've tried adding the Fragments as non-static inner classes in my Activity. This approach worked so long as the user did not rotate the device. As soon as the user rotated the device, the application crashed (this is true for Portrait -> Landscape rotation and for Landscape -> Portrait rotation). Upon checking the issue using the emulator, I was getting an InstantiationException. I checked SO for some help, which led me to:
Implement the Fragment as a static inner class. When the Fragment initiates, it will expand its layout, and then from later in the control flow of the Activity, I can do stuff to the Fragment's subviews (in particular, add listeners to the buttons). Unfortunately this didn't work because I couldn't refer to the Fragment's subviews using [frag_name].getView().findViewById(). Something about referencing static objects in a non-static context. Once again, I checked SO, which led me to:
Implement the Fragment as a separate class altogether from the Activity. This seems to be what the Dev docs on developer.android.com recommend. Upon doing this, everything seems to compile fine, but when I try to refer to the Fragment's subviews (once again, using [frag_name].getView().findViewById()), I get a NullPointerException. When I add System.out.println() statements across my code to find out exactly what is happening, I find that the print statement inside onCreateView in the fragment is never getting fired, which implies that onCreateView is never getting triggered.
So now, I'm stuck. What am I doing wrong? The precise implementation of this isn't as important as learning something from the experience so I can get better at Android development, so if seperate classes are better than static classes or vice-versa, I don't really care which I use.
Thanks.
Figured it out. Turns out that in order to do what I wanted, I had to register the Activity as a Listener to each of the Fragments and pass "ready to enable buttons" messages back and forth between the two. To anyone using this question for further research, the guide on how to do that is located on the Android Developer guide, here: http://developer.android.com/training/basics/fragments/communicating.html

What is Bundle, View, Context?

Guys I have watched tutorial on YouTube about android it has 200 videos but didn't explain what is Bundle, View and Context.
1st question what is Bundle?
2nd question what is bundle inside onCreate method where that come from? what inside that bundle?
3nd question what is Context? what I found is that Activity extends Context, so is it right to say that Context is the activity itself? or the Context of that activity?
4th question what is View? what I found is that TextView extends View and other widgets like Button EditText extend TextView so it means they also extends View.
I also found that the syntax of Button, EditText and other widgets is this...
TextView(Context);
Button(Context);
EditText(Context);
so my assumption here is that "Context = Activity = Screen" and that "View = Button = TextView = EditText"
so in this example
public Example extends Activity{
onCreate(){
Button buttonObj = new Button(this):
}
}
Button buttonObj = new Button(this);
"this keyword" here is refering to the Example class which extends Activity. Is this code here basically says "put this Button which is View inside the Context which is Activity which is the Screen"?
If I am right then why Activity passed inside Button? because it makes sense if button is passed inside Activity.
5th question what happen here?
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//code here
}
});
What is new View.onclickListener() ?? is this a static method that returns an object who implements onClickListener??
Can you also suggest good books in learning android?
Bundle ~ a Bundle is a collection of data. When an Activity starts (via onCreate), the Android OS (or you!) can pass off some extra data to this activity via this bundle. Do you know what a HashMap is? A bundle is a glorified hashmap in that supports multiple different types.
OnCreate Bundle ~ This bundle comes from Android. Honestly, don't worry about it too much. If you want to start one activity from another, you use an intent (do you know this yet?). As such, you can "bundle" data into the intent (using the setExtra methods). This data from the intent will be included in this onCreate bundle, and you can access it through there.
Context ~ your running application and anything associated with it. When you run your application, everything associated with your application is referenced by this context. All of you activities, views, resources, EVERYTHING is associated with the context. Think of it as the word defines: It is the context of your application. Every application has a unique context.
View ~ A view is anything that can be drawn on screen.
OnCreate():
The entire lifetime of an activity happens between the first call
to onCreate() through to a single final call to onDestroy().
An activity does all its initial setup of "global" state in
onCreate(), and releases all remaining resources in
onDestroy(). For example, if it has a thread running in the
background to download data from the network, it may create
that thread in onCreate() and then stop the thread in
onDestroy().
OnCreate method is called when the activity is first
created. This is where you
should do all of your normal
static set up — create views,
bind data to lists, and so on.
This method is passed a Bundle
object containing the activity's
previous state, if that state was
captured.
Views:
The visual content of the window is provided by a hierarchy of views — objects derived from the base View class.
Each view controls a particular rectangular space within the window. Parent views contain and organize the layout of their children. Leaf views (those at the bottom of the hierarchy) draw in the rectangles they control and respond to user actions directed at that space. Thus, views are where the activity's interaction with the user takes place.
For example, a view might display a small image and initiate an action when the user taps that image. Android has a number of ready-made views(Widgets) that you can use — including buttons, text fields, scroll bars, menu items,check boxes, and more.
I would suggest that you look at some text based tutorials rather than video as it will be easier to look at things and reread when you are confused.
I'll get started to help you with figuring out what these terms means.
Bundle - not super important for you to understand. When an activity is called, you can add things to your bundle to be sent to the next activity so that the new activity has the information you want.
Context - each activity has its own context and its important to have a basic understanding of it. Your first applications will have one activity (or class) from which everything is done. In this case you only have to worry about the "this" context which means the current active activity. But if you use an application with multiple activities, some may be active and others not. The context tells your app which of the activities is requesting an action, such as showing text or an image on the screen.
Views are your basic UI elements. They can be simple like TextViews (just shows text), Buttons, or more complex like a layout which organizes the other views.
For your example :
public Example extends Activity{
onCreate(){
Button buttonObj = new Button(this):
}
}
Example is the name of your class which uses the Activity resources.
When the activity "Example" is started it calls the onCreate method first.
It then creates a button object that you can "attach" to a physical button found in your layout file.
The setOnClickListener method is used to ready your activity for a button click. The code that goes into the onClick section is what will happen if the user clicks the button.
If you want to get into android programming, you really should first read the FAQ on this site. You should only be posting answerable questions not asking for opinions such as what's a good book. Hundreds of people have already asked that question and if you can't do a simple google search, you might want to wait on learning to program.
But I"m nice so here are some online tutorials that will get you started and explain some of the things you are confused about:
http://developer.android.com/guide/index.html
http://www.codeproject.com/Articles/102065/Android-A-beginner-s-guide

What is the benefit of using Fragments in Android, rather than Views?

When developing for Android, you can set your target (or minimum) sdk to 4 (API 1.6) and add the android compatibility package (v4) to add support for Fragments. Yesterday I did this and successfully implemented Fragments to visualize data from a custom class.
My question is this: what is the benefit for using Fragments as opposed to simply getting a View from a custom object, and still supporting API 1.5?
For example, say I have the class Foo.java:
public class Foo extends Fragment {
/** Title of the Foo object*/
private String title;
/** A description of Foo */
private String message;
/** Create a new Foo
* #param title
* #param message */
public Foo(String title, String message) {
this.title = title;
this.message = message;
}//Foo
/** Retrieves the View to display (supports API 1.5. To use,
* remove 'extends Fragment' from the class statement, along with
* the method {#link #onCreateView(LayoutInflater, ViewGroup, Bundle)})
* #param context Used for retrieving the inflater */
public View getView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//getView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//onCreateView
}//Foo
Both methods are very simple to create and to work with in an Activity that, say, has a List<Foo> to display (for example, programmatically adding each to a ScrollView), so are Fragments really all that useful, or are they just an over-glorified simplification of getting a View, such as through the code above?
The main reason to use Fragments are for the backstack and lifecycle features. Otherwise, custom views are more light weight and simpler to implement.
At first, I actually tried to build a phone/tablet app using custom views. Everything appeared to work across phones AND tablets, even switching from single panel to split panel. Where I ran into trouble was with the back button and life cycle. Since I was simply updating views manually...there was nothing keeping track of the history of views and their states. Therefore, the back button did not work as expected and it was difficult to recreate even the latest state during life cycle events, such as when rotating the app. To fix that, I had to wrap my custom views in fragments and use the FragmentManager so that the previous states would be saved and recreated.
I realized after answering that I posted to a similar question a year earlier: https://stackoverflow.com/a/11126397/618881
I'd say Fragments are useful in two scenarios: if you split up views on some devices/orientations and show them in two activities and show all the content in one on other devices. That would be a use case if you go on a tablet or maybe even in landscape mode on a phone: e.g. you show the list of items and the details on one screen. on a phone or in portrait mode you just show one part.
Another use case are reusable views. So if you have some views that are visible on different activities and also perform some actions you could put this behaviour into a fragment and then reuse it. Obviously you could probably do that with custom widgets too.
I wouldn't see any reason for using Fragments for every View and I guess it would just be an overhead. I'm only using them in the first use case and I'd say here it is a simplification.
Android introduced fragments in Android 3.0 (API level 11), primarily to support more dynamic and flexible UI designs on large screens, such as tablets. Because a tablet's screen is much larger than that of a handset, there's more room to combine and interchange UI components. Fragments allow such designs without the need for you to manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, you become able to modify the activity's appearance at runtime and preserve those changes in a back stack that's managed by the activity.
Here you can read more.
Scenario Activity Split screen - We have One Layout and one activity which handle left right screen part
Scenario FragmentActivity we have One layout for Main screen, one for left one for right
Scenario one is good if you have simple application.
Scenario two is good if you want to have Multiple Fragments and multiple FragmentActivities
and you can combine each of those. Also you can make interaction between fragments.
I have split screen Fragmentactivity i can call it with 'Intent Extras' and tell to fragmentActivity which fragment are to be loaded. Fragments are good because they are not in manifest so you could make reusable fragments and FragmentActvity.
But it make your project larger. But if you make large project you can save many. Because you can use same Fragments or same Fragment activity.
And i thing that this fragments come little late so you must try to think in new way.
Maybe just try to convert your activity to FragmentActivity. Later try to find reusable code and make Fragment from it.
Its usefull but i dont know how right now. But i have some ideas.
This is always problem. Android Team made somethink and nobody know what is good for. Because we are hardly learn like it was and here it comes some new things.
In my opinion it is good but not for reason that google tell us.
Add one case when using Fragment or Activity over CustomView:
When you are using CursorLoader to observe certain views, ListView or TextView and want to update their display value whenever your ContentProvider's data updates at back end(most common case you have a service which updates your local database by polling data from remote database/cloud periodically)
One big thing all the above comments don't mention is that a fragment remains resident in memory even if Android kills the activity and restarts it when you do something like change the orientation of your device. This is done for performance reasons but can also lead to unexpected results if you were expecting fragments to be destroyed only to find that they are getting recreated out of nowhere.

Categories

Resources