I am working on Android L trying to implement a drawer menu that overlaps the action bar. I have done it the normal way where it appears under the action bar, as described here: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/.
It was done in the google IO 2014 app and I would like to replicate it. I have been looking through the code (https://github.com/google/iosched) but I can't figure out how they done it.
Here is an image:
Does anyone have any idea how they done it?
To obtain this you have to use the new Toolbar.
You can use a layout like this:
<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/ActionBarThemeOverlay"
android:id="#+id/toolbar_actionbar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize" />
Then in your activity you can do:
Toolbar mActionBarToolbar = (Toolbar) mActivity.findViewById(R.id.toolbar_actionbar);
if (mActionBarToolbar != null) {
mActivity.setActionBar(mActionBarToolbar);
}
Finally you have to setup the toolbar to work with the navigation drawer:
if (mActionBarToolbar != null) {
mActionBarToolbar.setNavigationIcon(R.drawable.ic_navigation_drawer);
mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else {
mDrawerLayout.openDrawer(Gravity.START);
}
}
});
}
Pay attention because currently the new Toolbar class is only API-21.
Related
I want to implement the Extended FAB button in the format mentioned on the material website (https://kstatic.googleusercontent.com/files/8f9b57829c943c97be7c4b2485cf678f041dfe7c7ef523cfb2e97f1aeee21431f83d98cc07befeeed904fabb258298e3a7ac95f9da5d3da7a4adcff658cea851)
https://material.io/components/buttons-floating-action-button#types-of-transitions
Kindly help on how to achieve the same.
You can use the Material motion and the Transition between Views.
For example define in your layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/root"
..>
<com.google.android.material.card.MaterialCardView
android:id="#+id/end_card"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
.. />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Then just define the MaterialContainerTransform:
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showEndView(fab);
}
});
with:
private void showEndView(View startView) {
// Construct a container transform transition between two views.
MaterialContainerTransform transition = new MaterialContainerTransform();
transition.setScrimColor(Color.TRANSPARENT);
transition.setInterpolator(new FastOutSlowInInterpolator());
//set the duration....
//Define the start and the end view
transition.setStartView(startView);
transition.setEndView(endCard);
transition.addTarget(startView);
// Trigger the container transform transition.
TransitionManager.beginDelayedTransition(root, transition);
if (startView != null) {
startView.setVisibility(View.INVISIBLE);
}
if (endCard != null) {
endCard.setVisibility(View.VISIBLE);
}
}
Note: it requires at least the version 1.3.0-alpha01.
I'm using a YouTubePlayerFragment in my activity, and attempting to overlay the player with an app bar (aka action bar) when the player is in fullscreen. I'm following the guidelines and example in the YouTube Player API "Overlay ActionBar Demo" sample application and YouTubePlayerFragment documentation (more detail below).
All of this worked fine when I was extending from Activity and using the core ActionBar. But when I switch to using AppCompatActivity with the support Toolbar, a few issues arise:
The Toolbar is laid out under the status bar and navigation bar
The player no longer plays when the Toolbar is on top of it
It seems as though the player fullscreen mode used to treat the action bar as part of the system UI (along with the status bar and navigation bar), in terms of positioning and overlay, but no longer does so with the Toolbar.
Any thoughts on why this is happening or how I can use the Toolbar to properly overlay the YouTube player in fullscreen mode? I realize the Toolbar is just another view and I could probably force it to resize and reposition under the status bar, and I could set up a listener for system UI changes and show and hide my Toolbar accordingly, but I'm hoping there's a cleaner fix that I'm missing.
Here's a screenshot:
More detail: I was able to reproduce this behavior in the "Overlay ActionBar Demo" sample app (ActionBarDemoActivity), with the following changes:
Extend AppCompatActivity
Change import from android.app.ActionBar to android.support.v7.app.ActionBar
Add Toolbar to layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view
class="com.examples.youtubeapidemo.ActionBarDemoActivity$ActionBarPaddedFrameLayout"
android:id="#+id/view_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="#color/material_deep_teal_500" />
</FrameLayout>
Change the theme to Theme.AppCompat.Light.NoActionBar and add windowActionBarOverlay
<style name="OverlayActionBarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
</style>
Set the Toolbar as the action bar in onCreate()
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Note that the sample app also does the following (I didn't change these):
Implement YouTubePlayer.OnFullscreenListener
Extend the layout and set padding when not in fullscreen so that content displays below Toolbar
#Override
public void onFullscreen(boolean fullscreen) {
viewContainer.setEnablePadding(!fullscreen);
...
}
public static final class ActionBarPaddedFrameLayout extends FrameLayout {
public void setEnablePadding(boolean enable) {
paddingEnabled = enable;
requestLayout();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int topPadding =
paddingEnabled && actionBar != null && actionBar.isShowing() ? actionBar.getHeight() : 0;
setPadding(0, topPadding, 0, 0);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Set YouTube player fullscreen control flag
player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT);
Handle config changes
<activity
...
android:configChanges="keyboardHidden|orientation|screenSize"
...
</activity>
I suspect this is a bug. I filed a new bug report for the layout problem, and added a comment to an existing report about the support ActionBar/Toolbar being treated as an illegal overlay.
Toolbar overlay hidden under system UI in YouTube player fullscreen
With AppCompat theme on older devices, ActionBar is detected as an illegal overlay
In the meantime, as a workaround I'm doing the following:
Layout issue
As Troy suggested, I added android:fitsSystemWindows="true" to the Toolbar XML. This fixed the layout in fullscreen, but caused padding to be added to the Toolbar when leaving fullscreen (screenshot). I added logic to the onFullscreen(boolean) method to remove the Toolbar padding (toolbar.setPadding(0, 0, 0, 0)) but this unfortunately still shows white space in place of the padding, which disappears when the layout is next redrawn (e.g., when clicking an item, starting the player, etc). I'm still a little stumped on how to properly set the layout/padding, but the current workaround will do for now.
Illegal overlay issue
Given that showing the Toolbar will pause the YouTube player in fullscreen, I've added logic to only show the Toolbar when the player is already paused. This isn't ideal, as it forces the user to pause the player to see the Toolbar, but it's the best option I can think of.
In onFullscreen(boolean), if we enter fullscreen and the player is playing, the Toolbar is hidden.
public void onFullscreen(boolean isFullscreen) {
mFullscreen = isFullscreen;
if (isFullscreen && youTubePlayer.isPlaying()) {
toolbar.setVisibility(View.GONE);
}
else {
toolbar.setVisibility(View.VISIBLE);
}
}
When setting up the player (in onInitializationSuccess()), I added a listener to show and hide the Toolbar on play and pause:
youTubePlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
...
#Override
public void onPlaying() {
if (mFullscreen) {
toolbar.setVisibility(View.GONE);
}
}
#Override
public void onPaused() {
if (mFullscreen) {
toolbar.setVisibility(View.VISIBLE);
}
}
});
This code will solved your issue.
To hide navigation bar and toolbar
public void fullScreenCall() {
if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { //lower api
View v = getActivity().getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if(Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
to back normal mode
public void normalScreenCall() {
if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = getActivity().getWindow().getDecorView();
v.setSystemUiVisibility(View.VISIBLE);
} else if(Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(0);
}
}
Try adding android:fitsSystemWindows="true" to your toolbar in your XML file.
I made this issue:
https://code.google.com/p/android/issues/detail?id=189760
basically when
android:animateLayoutChanges="true"
Hiding up indicator hides makes it only invisible, not gone.
Full xml :
Program code:
public void updateToolbar(boolean show)
{
if(getSupportActionBar() != null) {
if(show) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
}
}
use below method for hide and remove up indicator space
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
I am using AppCompat action bar and i want to change the back icon of the searchview I use in the action bar. I searched but i couldn't find a solution.
I have tried setting the icon in the style :
<item name="homeAsUpIndicator">#drawable/myBackButton</item>
but I want to set another one programmatically when the user selects the search view.
Any ideas on how I can do it?
To customize SearchView "up" icon, you can use style attribute:
collapseIcon="#drawable/ic_discard_icon"
in your Toolbar layout:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:collapseIcon="#drawable/ic_discard_icon"/>
Or you can move this attribute into Toolbar style. As you wish.
Try this code snippet:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// get the parent view of home (app icon) imageview
ViewGroup home = (ViewGroup) findViewById(android.R.id.home).getParent();
// get the first child (up imageview)
( (ImageView) home.getChildAt(0) )
// change the icon according to your needs
.setImageDrawable(getResources().getDrawable(R.drawable.custom_icon_up));
} else {
// get the up imageview directly with R.id.up
( (ImageView) findViewById(R.id.up) )
.setImageDrawable(getResources().getDrawable(R.drawable.custom_icon_up));
}
You can change the background of the back icon like this
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initToolbar();
}
private void initToolbar() {
toolbar = (Toolbar) findViewById(R.id.tbMaster);
setSupportActionBar(toolbar);
if (toolbar != null) {
toolbar.setBackgroundColor(getResources().getColor(R.color.base_color));
getSupportActionBar().setTitle("Title");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.image);
}
}
For specific customer requirement, I need to allow the user of my app ( won't be published in Market) to click on the ActionBar title to execute some actions.
I have been looking in the Android source, but I am not able to find an ID for the actionBar TextView title.
Is there a proper way to handle such clicks?
The title is non-clickable AFAIK. The icon/logo is clickable -- you'll get that via android.R.id.home in onOptionsItemSelected(). Conceivably, the title also routes this way, though they don't mention it and I wouldn't rely upon it.
It sounds like you want a Spinner for the user to choose the actions to execute. If so, use setListNavigationCallbacks(). If you want to remove the title as now being superfluous, use setDisplayOptions(0, DISPLAY_SHOW_TITLE).
If you want something other than a Spinner on the left side of the action bar, use setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM) and setCustomView(). Note that this approach is not recommended ("Avoid using custom navigation modes in the action bar"), as it may not work well with phones, particularly in portrait mode.
Another possibility would be to remove the title and use a logo instead of the icon, and in the logo have your "title" as part of the image. The whole logo should be clickable, picked up via onOptionsItemSelected().
//onCreate
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
// View actionBarView = getLayoutInflater().inflate(R.layout.action_bar_custom_view, null);
actionBar.setCustomView(actionBarView);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
//your logic for click listner
setListenerForActionBarCustomView(actionBarView);
private void setListenerForActionBarCustomView(View actionBarView) {
ActionBarCustomViewOnClickListener actionBarCustomViewOnClickListener = new ActionBarCustomViewOnClickListener();
actionBarView.findViewById(R.id.text_view_title).setOnClickListener(actionBarCustomViewOnClickListener);
}
private class ActionBarCustomViewOnClickListener implements OnClickListener {
public void onClick(View v) {
switch(v.getId()) {
case R.id.text_view_title:
//finish();
break;
}
}
You can set up a custom toolbar from Support Library by declaring <android.support.v7.widget.Toolbar> in your layout (see Chris Banes' answer for full toolbar layout example).
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- We use a Toolbar so that our drawer can be displayed
in front of the action bar -->
<android.support.v7.widget.Toolbar
android:id="#+id/my_awesome_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/main_toolbar"
android:minHeight="?attr/actionBarSize" />
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
After you can add on click listener in your activity just like to most other Views.
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
toolbar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MyActivity.this, "Test", Toast.LENGTH_LONG).show();
}
});
If you want to capture touch events on title:
toolbar.setOnTouchListener(new View.OnTouchListener() {
Rect hitrect = new Rect();
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
boolean hit = false;
for (int i = toolbar.getChildCount() - 1; i != -1; i--) {
View view = toolbar.getChildAt(i);
if (view instanceof TextView) {
view.getHitRect(hitrect);
if (hitrect.contains((int)event.getX(), (int)event.getY())) {
hit = true;
break;
}
}
}
if (hit) {
//Hit action
}
}
return false;
}
});