I could not find a way to do a tablet multi-pane layout easily with NavigationDrawer. Play Music app does that.
I have used LOCK_MODE_LOCKED_OPENED but it opens the drawer on top of the content as expected and it cannot be closed. Therefore the content is not completely visible.
Do we have to do it manually?
The only way we found is to do it manually, we created a simple linear layout for tablet and check the view instance in activity:
View layout = findViewById(R.id.navigation_layout);
if (layout instanceof DrawerLayout) {
drawerLayout = (DrawerLayout) layout;
// initialization of drawer toggle etc.
...
} else {
// linear layout
getSupportActionBar().setHomeButtonEnabled(false);
}
Related
I was using Collapsible Toolbar in my app. On activity launch Collapsible Toolbar is expanded state with scrolling enabled and its working well normally. But now I have a requirement to show a full screen error layout in case my API fails. In that case I have to collapsed toolbar with scrolling effect blocked.
Error Layout shows a Retry Button. On Retry I make API call again and if API gives success I have to again expand Toolbar and enable scrolling effect.
I was able to collapse toolbar with setExpanded(flag, animate) but in that case I am not able to block scrolling effect of Collapsible Toolbar while error layout is shown.
I need to provide a way to block as well as unblock scroll effect + Expand/Collapse Toolbar. Any help would be really appreciated.. !!!
Make your error layout such that it will overlap Collapsible Toolbar. Also set android:clickable="true" to your error layout.
When you set visibility to your error layout, set Toolbar scrolling accordingly.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f3f3f3"
android:orientation="vertical"
>
<!-- Add your other layout including Collapsible Toolbar here.-->
<RelativeLayout
android:id="#+id/errorLayout"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
I created a library AppBarrr to lock the screen in expanded mode, based on my previous answer.
As I said, the height of the Toolbar is the key: the CollapsingToolbarLayout will collapse until the Toolbar's height and will expand until the AppBarLayout's height.
With this library, you must set two layouts as the Toolbar and your Expanded Layout (used to lock the screen and the scroll), it will create a CollapsingToolbarLayout and inflate these layouts inside.
You can declare the animations duration, the color of the inner CollapsingToolbarLayout, the collapsed/expanded title's style, even the height of the locked layout... You could also hide the Expanded Layout if you click outside it. It can support NestedScrollView and ScrollView inside the Expanded Layout. The documentation and a sample app are available on Github.
For those who don't want to use the library, my previous answer shows the way to do it. Here's the output of the previous answer:
Basically, this is the same concept, but no need to write a full class, with the lib you just need to have a simple widget in xml and that's it!
Feel free to use, fork or test. Hope it will be useful ;)
If you use AlertDialog to communicate the error and a ProgressDialog (spinner) to show you are doing stuff, you can block user input while your app is doing it's thing.
A simple solution that you can apply is just use the property
android:visibility="gone"
for the content that you don't want to show and just make your error layout visible by using property android:visibility="visible"
place the error layout at the bottom of your parent layout
once the contents are not visible on screen and error layout is just visible you will achieve the desired result that you want. Hope this helps you.
You can implement the interface and call its methods when to enable or disable the collapsing effect.
public interface AppbarRequestListener {
void unlockAppBarOpen();
void lockAppBarClosed();
}
#Override
public void unlockAppBarOpen() {
appBarLayout.setExpanded(true, false);
appBarLayout.setActivated(true);
setAppBarDragging(false);
}
#Override
public void lockAppBarClosed() {
appBarLayout.setExpanded(false, false);
appBarLayout.setActivated(false);
setAppBarDragging(false);
}
private void setAppBarDragging(final boolean isEnabled) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
#Override
public boolean canDrag(AppBarLayout appBarLayout) {
return isEnabled;
}
});
params.setBehavior(behavior);
}
I have a NavigationView in a Drawer Layout which contains a HeaderView followed by a Menu (as given in AndroidStudio's Navigation Drawer Activity's template). My Header contains an Image and couple of TextViews in a LinearLayout. I want to edit of one of the TextViews in the header from SharedPreferences. I use following function to do so
public void navUpdate()
{
navigationView=(NavigationView)findViewById(R.id.nav_view);
linearLayout=(LinearLayout) LayoutInflater.from(this).inflate(R.layout.nav_header_main, null);
textView_nname=(TextView)linearLayout.findViewById(R.id.textView_nname);
String name=sharedPreferences.getString("name","Your Name");
textView_nname.setText(name);
navigationView.removeHeaderView(linearLayout);
navigationView.addHeaderView(linearLayout);
}
The problem is , though I've added the line
navigationView.removeHeaderView(linearLayout);
my previous headerview is still visible above the new one. And previous one is not updated. I read about the method navigationview.getHeaderAt() in many answers but believe me, that method is not available.
Here's how it looks
Is there any solution for this problem, if not is there any other way to do so?
in order for you to get the Header from the NavigationView you'll have to call getHeaderView(int index) for instance:
View headerView = navigationView.getHeaderView(0);
textView_nname = (TextView)headerView.findViewById(R.id.textView_nname);
// set whatever you like on the textView.
In my app, I want to show some buttons in a LinearLayout that expands over whole width of the screen. Depending on screen size and/or orientation, I would like to hide those buttons, that don't fit in the row, in some OverflowMenu, similar to the behaviour of the ActionBar. If possible, I would like to describe the buttons in a menu resource file with the ifRoom|always attributes.
I considered displaying a Toolbar from the latest AppCompat library, but that contains too many elements that I don't need and don't know how to turn off.
Is there some library or simple way to do this?
Here is an example to do what you want. Make sure your ActionMenuView XML item is wrap_content for height and width, then gravity to the right. Surround it in a LinearLayout which takes the whole width and provides background color.
Use this code to initialize the ActionMenuView (obviously you will need to change the button callbacks)
ActionMenuView actionMenuView = (ActionMenuView) findViewById(R.id.editBar);
final Context context = this;
MenuBuilder menuBuilder = new MenuBuilder(context);
menuBuilder.setCallback(new MenuBuilder.Callback() {
#Override
public boolean onMenuItemSelected(MenuBuilder menuBuilder, MenuItem menuItem) {
return onOptionsItemSelected(menuItem);
}
#Override
public void onMenuModeChange(MenuBuilder menuBuilder) {
}
});
// setup a actionMenuPresenter which will use up as much space as it can, even with width=wrap_content
ActionMenuPresenter presenter = new ActionMenuPresenter(context);
presenter.setReserveOverflow(true);
presenter.setWidthLimit(getResources().getDisplayMetrics().widthPixels, true);
presenter.setItemLimit(Integer.MAX_VALUE);
// open a menu xml into the menubuilder
getMenuInflater().inflate(R.menu.editbar, menuBuilder);
// runs presenter.initformenu(mMenu) too, setting up presenter's mmenu ref... this must be before setmenuview
menuBuilder.addMenuPresenter(presenter, this);
// runs menuview.initialize too, so menuview.mmenu = mpresenter.mmenu
actionMenuView.setPresenter(presenter);
presenter.updateMenuView(true);
For what it's worth, I had to read the support library source code for 8 hours to get this to work. The documentation is garbage.
ActionMenuView is the part of a Toolbar which specifically controls the actions and overflow part of the Toolbar. In your case, you can use an ActionMenuView alone to implement just the actions/overflow part of the Toolbar:
Add an ActionMenuView to the appropriate place in your XML layout
Retrieve a MenuInflater (easiest way is through an Activity's getMenuInflater() method
Call menuInflater.inflate(R.menu.your_menu, actionMenuView.getMenu()) to inflate your menu into the ActionMenuView
In my application I use DrawerLayout to show same help information. So I put it over actuall activity. Now I want to add TalckBack function and I cannot make that the any of view in DrawerLayout get the yellow rectangle (which marks focus in talkback mode).
The Drawerlayout view is loaded on demand by inflantign it.
drawerLayout = (DrawerLayout) ((Activity) mContext).findViewById(R.id.drawer);
drawerHelp = (RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.help, drawerLayout, false);
What I try:
in xml add:
android:focusable="true"
android:focusableInTouchMode="true"
android:importantForAccessibility="yes"
In code:
requestChildFocus()
requestFocus()
requestChildFocusFromTouch()
but still no luck.
So how to force the rectangle mark in talkback mode for ImageButton?
I solve my problem by adding
android:importantForAccessibility="no"
to all element in drawer layout and to other not nedeed elements in help layout.
I have a problem, I would like to put in my Layout the Drawer Layout and the FlyOutContainer but in the error Log it shows an error:that DrawerLayout cannot be cast to FlyOutContainer what can I do to fix this problem. I need the Drawer Layout to go to the MainActivity.
Hope you can help me and sorry for my bad english.
The code in that demo inflates a layout and casts the root view of the Layout to FlyOutContainer. If you change your layout xml so that the root is now DrawerLayout, then that code no longer runs correctly and you are probably getting ClassCastException. You should do it this way instead (in onCreate()):
setContentView(R.layout.your_activity_layout);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout_id);
FlyOutContainer flyOutContainner = (FlyOutContainer) findViewById(R.id.fly_out_container_id);
Of course, if you don't actually need a reference to these views/layouts, you can just stop after setContentView(...)