i'ld like to know how i can switch my dialogs layout file without creating a separate one.
I have a custom dialog fragment i use for connecting to bluetooth devices in my app. It pops up a list of devices and i connect to a device of my choosing.
I have two xml layouts i want to use with this dialog fragment:
- The first one holds the listview for devices i want to connect to
- The other houses and image view
When i connect to a device, i want to switch the layout from the list to the one that houses the imageview. Some where in my code, i have a variable that checks the connection status.
if i'm connected, i switch to the other layout like this:
getDialog().setContentView(R.layout.xml2);
and it works but then when i want to show the dialog again, i get this error.
Attempt to invoke virtual method 'void android.app.Dialog.setContentView(int)' on a null object reference
In my onCreateView method, i'm check my connection state.
if (connected) {
return inflater.inflate(R.layout.xml2, container, false);
} else {
return inflater.inflate(R.layout.xml1, container, false);
}
I know the error has to do with the changing getDialog().setContentView when state changed to connected. I'm thinking about how to revert back to the default view on dismiss so the onCreateView can take effect. If there is another method to doing this, i'ld like to hear about it. Any Ideas?
Thanks in advance...
Your getDialog() method returns null. You may want to have a look at it.
Related
I need to hide the content of my application when it goes to the background so sensitive information are not showing up on the android multitasking view.
It's been suggested to use the following line to hide the screen
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
It works fine.
However, this prevents the user from taking screenshot as well which is not an expected behavior for me. I want to let the user take screenshot of the app if they need to. What I don't want is Android to display the latest screen on the multitasking view.
Would it be possible to set the FLAG_SECURE only when the app goes in the background?
We've ended up with this solution which worked the best for us:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
You can use Activity Lifecycle Callbacks. Just call setVisiblity(View.INVISIBLE) on the views that you want to hide in the onPause() Callback and setVisiblity(View.VISIBLE) in onResume() Callback.
I have a Fragment that shows different view by a AdapterViewFlipper.
The AdapterViewFlipper is being set with MyCustomAdapter that contains 'View 1', 'View 2', 'View 3', and 'View 4', and its in a layout resource file that I inflated in my own Fragment "onCreateView()".
The Problem I'm facing is whenever I rotate my device, the current view in the AdapterViewFlipper goes back to the first view that was added in MyCustomAdapter.
For Example: if the current view in the AdapterViewFlipper is showing 'View 2' and the user rotates the device, it returns back to 'View 1'.
So what I'm trying to do is to restore the current view in the AdapterViewFlipper and its state in the Fragment whenever I rotate my device.
Although I found this method that says I should declare the android:configChanges attribute at the element in the AndroidManifest and it worked like a charm but when I was reading about it Android didn't recommend it.
But this works fine in Activity.
So is there a way I can go through this myself?
So the first thing you need to do, is to make sure you are retaining the fragment itself. And not place a new instance every time your activity is re-created.
You can establish that with a simple check in your onCreate() method.
You can either check if the savedInstance Bundle parameter to onCreate() is null, in that case only you need to replace your fragment OR check if your fragment is already added to your FragmentManager.
if (savedInstanceState == null) {
// This is a brand new activity, and not a re-creation due to config change
getSupportFragmentManager().beginTransaction().replace(id, yourFragmentInstnace, stringTag);
}
OR
if (getSupportFragmentManager().findFragmentByTag(fragmentTag) == null) {
// This is a brand new activity, and not a re-creation due to config change
getSupportFragmentManager().beginTransaction().replace(id, yourFragmentInstnace, fragmentTag);
}
And you also need to call setRetainInstance(true) in your fragment's onCreate() or something.
That will retain the same instance of your fragment during a configuration change.
This should automatically allow your AdapterViewFlipper to maintain its UI state, which is the current item it's showing.
You can find a nice example here
I am Checking if the device screen is twopane or singlepane. If twopane i want to pass arguments(Object) to another fragment in view by using bundle for it to dynamically load. if single pane i want to start a new activity by using start intent for the fragment. How can i do this?
I think you should create a bool resource in your strings.xml file. This bool resource "is_tablet" should be set to true in sw600dp/strings.xml and false in values/strings.xml.
Hence you would know if this device is using a single pane or double pane. Now with this check you can launch a new activity or pass the data to other fragment.
I'm using a viewpager which is made up of some number of relative layout siblings which are quite complex.
If I click on the relative layout, it will highlight the entire page and read the title and a few textviews one after the other as expected.
If I scroll the viewpager I'd like talkback to read the next page in the same way it reads the first if I click. Secondly, if I scroll to the second, third, etc. pages and click on those layouts, talkback will read as expected.
I am trying to achieve the click behavior after the scroll event has completed.
Here is what I have for the accessibilityDelegate.
viewPager.setAccessibilityDelegate(new AccessibilityDelegate () {
#Override
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
View page = viewPager.getCurrentPageView();
performAccessibilityAction(page, AccessibilityNodeInfo.ACTION_CLICK, Bundle.EMPTY);
}
return super.onRequestSendAccessibilityEvent(host, child, event);
}
});
I've verified that 'page' is the RelativeLayout parent that I think it is. I've also confirmed that the onRequestSendAccessibilityEvent is being fired, but it doesn't read the contents of its children. Am I missing something?
Updated
I've also tried using
viewpager.getCurrentPageView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
The above worked for another example when I needed to force talkback to reread a single item but does not have any affect if I try it on the page.
Thanks
Some background -- When you tap on the relative layout, TalkBack generates speech based on the layout's contents. On ICS, this is triggered by a HOVER_ENTER event. On Jelly Bean, it's triggered by an ACCESSIBILITY_FOCUS event. These events are sent automatically by the framework and should, generally speaking, never be sent manually from an app. The same goes for FOCUS events, except in the special case of custom views (see Accessibility talk from Google I/O 2013 for more details).
So, back on topic.
You can control the speech for SCROLLED events by populating the outgoing event with the text you want read. The down side of this is that you'll need to manually generate the text you want read, and it's very likely that this text will differ from what TalkBack will read if the user touches the layout.
viewPager.setAccessibilityDelegate(new AccessibilityDelegate () {
#Override
public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(host, event);
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
event.setContentDescription(/** your text */);
}
}
});
Another option is to do nothing and let the user explore the view on their own. This is the preferred interaction model for Android accessibility.
Edit: Video URL is broken, Changed.
This issue was reported on google check
where ViewPager does not set AccessibilityEvent parameters properly
when scrolling.
But after releas of Android Support Library, revision 23.2.1 (March 2016) This issue has been resolved.
update Support Library to Android Support Library to 23.2.1
I had the same issue before. And now I add android:focusable="true" to the ViewGroup, the TalkBalk will read the ViewGroup, instead of its children
I'm attempting to implement accessibility on a few custom views for an Android app.
I've condensed what is done in the Google Authenticator app with no luck:
public class CardView extends RelativeLayout {
// ...
#Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
event.setClassName(this.getClass().getName());
event.setPackageName(this.getContext().getPackageName());
event.getText().add("Card Test");
return true;
}
}
All TalkBack reports back is "Double-tap to select" when it's inside a ListView or ViewPager.
Does ViewPager override accessibility events?
What do I need to do in order to have TalkBack say "Card Test" inside ViewPagers and ListViews like I expect it to?
For current versions of Android, you need to set the content description of the view.
myView.setContentDescription("Card Test");
ListView and associated classes expect you to use the onItemSelectedListener instead of assigning an onClickListener to each View (and rightfully so).
If incorporating alanv's suggestion, try to convince android system to read out the content description
by either
If(accessibilityModeIsEnabled())//custom method that checks context.getSystemService(Context.ACCESSIBILITY_SERVICE).isEnabled()
myView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
or AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED.
or requestFocus
Above should done when myView is visible. May be during onMesasure when width and height are both positive
If list view is still unable to do so, then try doing the above tricks on the first element of list view. Accessibility in Android varies devices to device and not one strategy fits all