I have a Bottom-Navigation in portrait Mode and a Navigation-Rail-View in landscape mode.
How can I update the selected item when the device is rotated?
I tried it with savedInstanceState, with override theonSaveInstanceState and onRestoreInstanceState.
But because I use savedInstanceState for other things too, overide the two above methods cause crash.
Eventually I found a solution.
But before that, I should mention that a better title for this question could be: How to share selection item between the BottomNavigation and NavigationRail.
Ok, solution:
Just replace setSelectedItemId with getMenu().getItem(itemIndex).setChecked(true)
Example:
Use:
bottomNavigationView.getMenu().getItem(indexOfItem2).setChecked(true);
Instead of:
bottomNavigationView.setSelectedItemId(R.id.item2);
try this
navigationRailView.setSelected(false);
Related
In a master detail flow, when I go from landscape to portrait, my detail fragment is still there.
What's the best place and time (lifecycle callback) to get rid of it? I only have to get rid of it because my menu items and actionbar title are coming from the detail fragment, in portrait mode, and so it doesn't make any sense.
In the onCreate method of your activity, you could try that:
DetailFragment detailFrag = getFragmentManager().findFragmentByTag
if( <your logic to see if portrait> && detailFrag !=null && detailFrag.isVisible()){
<Remove the Fragment using a normal fragment transaction>
}
Short answer would be onCreate
And there are multiple things you would need to know
When screen orientation change, which is one of the configuration changes, which will trigger Activity recreation.
You can stop Activity recreation by setting onConfigChange, but do NOT do this unless this is a special app, e.g. Camera
Activity recreate is trying to help you, and your case is exactly where it is needed, and you can do the correct setup in onCreate
There are multiple ways to handle the different orientation, the basic way would be to use different layout, e.g. for your layout, say activity_main.xml, you can define a similar xml with the same name, under layout-land folder. When you setContentView(R.layout.activity_main), Android will select the right layout for you depending on your configuration.
In your case, you are switching between 2 fragments and 1 fragment, there are additional works you need to handle for the fragment transaction. However, this would depends on your existing FragmentTransaction and this will go too broad to go on, so I will stop here.
I tried implement tab view in my app. This is the code that I used
http://developer.android.com/training/implementing-navigation/lateral.html
I created my fragment and I can go change between them. In the main activity I have menu the default menu (three points up right corner).
My question is how can I make that when I click on button in the menu one tab will be update/refresh/become another framgent, The name and the fragment. (I override onOptionsItemSelected..)
Thanks
If it help for someone. The solution is to use FragmentStatePagerAdapter and not FragmentPagerAdapter.
and manipulate the getItem function.
If I understand you correctly you want to use a menu item to switch to a specific tab, right?
To change to a tab grammatically you can use setSelectedNavigationItem like this:
ActionBar actionBar = getActionBar();
actionBar.setSelectedNavigationItem(0);
//this will put the screen to the first tab (tab at index 0).
If you want to do this with a menu item just put it in onMenuItemSelected.
Let me know if you need me to explain in more detail.
=================EDIT=====================
ah i think i understand, so replace the current tab fragment with another one in its place?
I think you can do that by:
actionBar.removeTabAt(position); //position is the current tab position.
actionBar.addTab(tab, position); //insert a new tab at that position
if its not selected after you insert it, try this:
actionBar.addTab(tab, position, setSelected)
i did not test this, so let me know if it does not work.
I'm making an app with 4 main Views. I want that all of them stay on a LIST menu on top (That's ok for now).
Using Fragments, I have the ability to change the view without actualy going to other activity, but since one of my Views have a ViewPager, it's NOT working at all (When I first load the view, the content is OK, but on the seccond time, views on the ViewPager disapear, and appear only if I go 2 index positions away, and go back) (See picture, shown for the first load time, and seccond)
Note that the ViewPager IS NOT to show de menu's items, it's in fact, part of the Fragment of the current menu item (in this case, "Simula'c~ao")
My question is: Is this a known issue, is there a simple way to fix it, or I must do it in another way? I already searched for this problem on the internet, but nothing worked for me (invalidating, setting up the on getItemPosition to return POSITION_NONE...)
I have looked into the ViewPager class, and everything seems to be OK, I have modified it, so that everytime I render the views, it forces to render everything, but neither this way worked.
I have tried to set visibility to GONE and VISIBLE
I have tried to detach and attach the adapter
Tried to cache the views, and return cached.
One thing that semmed to work: Changing the orientation of the Phone. That worked.
Tried lots of things that I even remember... I'm a little furious with this, because the past 24 hours didn't helped me to solve this "mistery" at all. I hope that some of you can =]
My code:
https://www.dropbox.com/s/u4mlxr3k6ta9yrm/MainActivity.java
https://www.dropbox.com/s/2dqfnzjs2wl89hj/SimulationFragment.java
Views:
https://www.dropbox.com/s/d6ruc1zjovqu6ob/activity_main.xml
https://www.dropbox.com/s/lp1iea13klr77iq/activity_simulation.xml
https://www.dropbox.com/s/1mkl3jqmo7g4wh8/item_simulation.xml
Well, after long hours trying to discover what the hell was this about, #anup-cowkur guided me to a path that would solve my problem.
At first, I tought that the problem was on the PageView, I downloaded the support library, edited, changed LOTS of things, but the problem was not there.
In fact, the problem is on the FragmentPagerAdapter. He uses a sort of "caching" for each of the ViewPager fragment. Because of that, he wasn't "notified" when I returned to the view, causing the last fragments shown to not "actualy" exist on the parents view (in this case, the main fragment, that holds my others fragments from the ViewPager).
Since they are registered on the FragmentManager, what I did was hack into the FragmentPagerAdapter, implementing this method:
FragmentPagerAdapter.java
public void clear(ViewGroup container){
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for(int i = 0; i < getCount(); i++){
final long itemId = getItemId(i);
// Do we already have this fragment?
String name = "android:switcher:" + container.getId() + ":" + itemId;
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if(fragment != null){
mCurTransaction.detach(fragment);
}
}
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
}
And then, call it on my "onCreate":
myPagerAdapter.clear(mViewPager);
done. All fragments are FORCED to be removed from the FragmentManager, causing the "cache" to disapear.
It's not the best solution, but the only one that worked.
EDIT
You can find the hole file here:
http://pastebin.com/07adWVrr
You are using a FragmentStatePagerAdapter. This adapter uses fragments inside the ViewPager. You have this ViewPager inside another parent Fragment. So you have Fragments inside a Fragment. Nested fragments are not supported. This is why you are having problems. See: Why it is not possible to use ViewPager within a Fragment? It actually is
Your best bet is to use a normal PagerAdapter instead of a FragmentStatePagerAdapter. This uses regular views instead of Fragments and should work fine.
If the issue occur when it is necessary to make more than one swipe to obtain get the page on screen, this code solves it:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
I'm currently implementing theme support for my application and a part of it is changing the action bar app icon. I want to use a dark icon when Holo Light is selected. Everything is done in the method except for the part where the action bar app icon is set. The code that I'm trying to use is:
getActionBar();
ActionBar.setIcon(R.drawable.my_icon);
"There is no such reference available here" is the error that I'm getting. How should this be done correctly?
BTW my minSdkVersion is 14 so no action bar Sherlock stuff.
getActionBar();
You're throwing the action bar away right there. getActionBar() returns an instance of ActionBar, which you then need to call setIcon() on. Like so:
ActionBar actionBar = getActionBar();
actionBar.setIcon(R.drawable.my_icon);
Though its a bit late answer but i thought it might be useful.
From inside an activity:
For API level 14 or higher:
getActionBar().setIcon(R.drawable.my_icon);
For lower API level we have to extend ActionBarActivity and then:
getSupportActionBar().setIcon(R.drawable.my_icon);
From inside a Fragment:
For API level 14 or higher:
getActivity().getActionBar().setIcon(R.drawable.my_icon);
For lower API level we can use (activity must extend ActionBarActivity):
((ActionBarActivity)getActivity()).getSupportActionBar().setIcon(R.drawable.my_icon);
And in both cases we have to call setDisplayShowHomeEnabled(true) before setting the icon or logo.
((ActionBarActivity)getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
((ActionBarActivity)getActivity()).getSupportActionBar().setIcon(R.drawable.my_icon);
I am using this for my use , and it's working for me. Hope this help all
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.icon);
You need to add the drawable that you want to reference into your drawable/ folder under res/.
edit: In your Android installation folder there are a lot of stock images to use. You can probably find it there.
The existing answer is very correct. There is, however, also an alternative.
A minimal approach would be to use
getActionBar().setIcon(R.drawable.my_icon);
Gets your job done right away. :)
Technical Details: Since getActionBar() by default returns an object, you can directly manipulate it without having to receive it in an in-scope object explicitly.
Calling to setIcon wasn't enough for me.
Before that, I had to switch the display from activity logo to activity icon:
actionBar.setDisplayUseLogoEnabled(false);
For the differences between activity icon and logo see Android icon vs logo.
Try this
setSupportActionBar(toolbar);
if (getSupportActionBar() != null)
getSupportActionBar().setIcon(R.drawable.your_icon);
Kotlin answer:
In your activity just paste this code.
You need to enable the option first:
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(R.drawable.your_icon)
I have another question!
I have a configure Activity in my app. On it, I have a ListView. Now adding & removing items to & from it works, but when I rotate the screen to landscape or back, all added & non-saved items in the ListView get removed... I wonder why this is... Why is this?
When screen orientation changes, by default, the activity will be destroyed and create again. That means, the onCreate will be called again once the orientation changed. There are basically two way to solve your problem:
Save your activity state before destory and load it back when create
Set the Activity in AndroidManifest that not to handle screen orientation change.
E.g.
<activity name="..."
android:configChanges="orientation" .../>
When you rotate the handset, the onStart method of you Activity is invoked. Check maybe you do some sort of initialization there.
I've solved it partially. Now it is able to hold on to the changes when changing to landscape view, but not the other way back to the normal view. I did it through the use of protected void onSaveInstanceState(Bundle saveState). But as I said, this doesn't work when it changes back from Landscape... Anybody got any ideas about this?