I want to add a button to my navigation drawer menu, like so:
desired result:
I tried achieving this using the actionLayout parameter, but I seem to only be able to use some space on the right, not the entire width:
current result:
The title seems to be occupying the space on the left.
But I want to add a button with full width like in the first picture.
My current code:
...
<item
android:id="#+id/nav_login"
android:title=""
app:actionLayout="#layout/button_login"
app:showAsAction="ifRoom"/>
...
button_login.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#0000ff"
android:text="Login"
android:textColor="#ffffff"
android:layout_height="match_parent" />
Action view in drawers intended to show this "small" addition view on the right of the menu item, so it'll be restricted in size.
You can add desired button as some sort of footer like following:
<android.support.design.widget.NavigationView
android:id="#+id/drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer">
<Button
android:id="#+id/footer_item_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Footer Button 1" />
</android.support.design.widget.NavigationView>
Note that you can put everything you want as a child, if you want some more views - just add LinearLayout there and put all additional views as children of it.
My solution is now using the MaterialDrawer Library.
I just did a quick test and it solves the problem:
Code:
...
Drawer drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(findViewById(R.id.toolbar))
.addDrawerItems(
new PrimaryDrawerItem().withName("Entry 1"),
new PrimaryDrawerItem().withName("Entry 2"),
new AbstractDrawerItem() {
#Override
public RecyclerView.ViewHolder getViewHolder(View v) {
return new RecyclerView.ViewHolder(v) {
};
}
#Override
public int getType() {
return 0;
}
#Override
public int getLayoutRes() {
return R.layout.button_a;
}
#Override
public Object withSubItems(List subItems) {
return null;
}
#Override
public Object withParent(IItem parent) {
return null;
}
},
new PrimaryDrawerItem().withName("Entry 3")
)
.build();
...
button_a.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_width="match_parent"
android:text="Login"
android:layout_height="50dp"/>
Related
Note: These are randomly generated addresses
Hey Guys, Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I color coded my layouts to see if the sizes where a problem, but I dont think they are since my orange layout is plenty big to hold my two entries. Am I using the wrong layouts for this kind of application? I would appreciate any help!
Here is my translation code:
frameLayout.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
And my layout file:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipeLayout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:id="#+id/frameLayoutParent"
android:background="#android:color/holo_green_dark">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:background="#android:color/holo_green_light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:background="#android:color/holo_orange_light">
<Button
android:text="Add New Address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/addNewAddress"
android:maxHeight="20dp" />
</LinearLayout>
<ListView
android:paddingTop="50dp"
android:minWidth="25px"
android:minHeight="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:maxHeight="300dp"/>
</FrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editSearch"
android:hint="Search ZipCodes"
android:textColor="#000"/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
EDIT:
Here is my OnOptionsItemSelected Code, where my animation is triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.action_search:
//search icon has been clicked
if (isAnimating)
return true;
else
{
if (animateBool)
{
//list view is up
animation anim = new animation(myListView, myListView.Height - editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartDown; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndDown;
classSwipeRefresh.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
}
else
{
animation anim = new animation(myListView, myListView.Height + editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartUp; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndUp;
classSwipeRefresh.Animate().TranslationYBy(-editSearch.Height).SetDuration(500).Start();
}
animateBool = !animateBool;
return true;
}
default:
return base.OnOptionsItemSelected(item);
}
}
Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I use your code to test, but I have no problem when translating by Y in SwipeRefreshLayout__Refresh event.
public class MainActivity : AppCompatActivity
{
string[] items;
ListView listview1;
SwipeRefreshLayout swiplayout;
FrameLayout framelayout;
EditText edittext;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
listview1 = FindViewById<ListView>(Resource.Id.myListView);
swiplayout = FindViewById<SwipeRefreshLayout>(Resource.Id.swipeLayout);
framelayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
edittext = FindViewById<EditText>(Resource.Id.editSearch);
swiplayout.Refresh += Swiplayout_Refresh;
items = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
listview1.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);
}
private void Swiplayout_Refresh(object sender, EventArgs e)
{
framelayout.Animate().TranslationYBy(edittext.Height).SetDuration(500).Start();
}
}
This is my screenshot:
If you want to filter ListView, I suggest you can use SearchView in Toolbar to filter listview data, please take a look this sample:
https://github.com/Cheesebaron/SearchView-Sample/tree/master/SearchViewSample
I have a fragment with a navigation menu at the top-left corner. At the start of the activity, I want to gradually slide a view (let's call it black_view) out of the menu icon.
Here's a rough breakdown of how I want the animation to be in accordance with the images below:
Activity starts as the first image with black_view being invisible.
black_view gradually slides out from behind the menu icon length by length until it gets to the point of the second image.
>>>
What I've tried:
I tried achieving this by using a TranslateAnimation. However, the whole length of black_view shows up at the start of the animation and this is not what I want. I also saw a couple of sliding animation code snippets like this and this, but they all follow the TranlateAnimation model (with the whole length of black_view showing instantly).
How can I achieve this?
PS: If there's any important detail that I failed to add, kindly let me know.
It can be done easily with Slide transition from Transition API. Just use TransitionManager.beginDelayedTransition method then change visibility of black view from GONE to VISIBLE.
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
public class MainActivity extends AppCompatActivity {
private ViewGroup parent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
parent = findViewById(R.id.parent);
parent.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
parent.getViewTreeObserver().removeOnPreDrawListener(this);
animate();
return true;
}
});
}
private void animate() {
View textView = findViewById(R.id.text);
Transition transition = new Slide(Gravity.LEFT);
transition.setDuration(2000);
transition.setStartDelay(1000);
TransitionManager.beginDelayedTransition(parent, transition);
textView.setVisibility(View.VISIBLE);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="Button" />
<FrameLayout
android:id="#+id/parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/button">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000"
android:text="hello world"
android:textColor="#fff"
android:textSize="22sp"
android:visibility="gone" />
</FrameLayout>
</RelativeLayout>
Result:
All classes here are from androix package so code is backward compatible.
I would like to do something like this:
https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4
I would like to squeeze a "ViewGroup" as you can see in the video. In the meantime, I want to fade out the content in the ViewGroup at its original position. i.e. not pushing the content to the right.
Any idea how to implement this?
Thanks!
You can do such animations with Transition API. Declare two ViewGroups: first one is horizontal with cut/copy buttons, second is vertical with search/share buttons. Then switch these ViewGroups with TransitionManager. Then just provide Transition which describes how views on first and second ViewGroups appears and disappers.
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.ChangeBounds;
import androidx.transition.Fade;
import androidx.transition.Scene;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
import androidx.transition.TransitionSet;
public class MainActivity extends AppCompatActivity {
private ViewGroup mSceneRoot;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
mSceneRoot = findViewById(R.id.sceneRoot);
showPopup1();
}
private void showPopup1() {
ViewGroup popup1 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_1, mSceneRoot, false);
popup1.findViewById(R.id.btnGo).setOnClickListener(v -> {
showPopup2();
});
Scene scene = new Scene(mSceneRoot, popup1);
TransitionManager.go(scene, getTransition(false));
}
private void showPopup2() {
ViewGroup popup2 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_2, mSceneRoot, false);
popup2.findViewById(R.id.btnBack).setOnClickListener(v -> {
showPopup1();
});
Scene scene = new Scene(mSceneRoot, popup2);
TransitionManager.go(scene, getTransition(true));
}
}
activity_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sceneRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
android:orientation="vertical"
android:paddingBottom="150dp"
android:paddingRight="50dp"
android:clipToPadding="false"
android:clipChildren="false"/>
popup_1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/popup1"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="#+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="go"
android:transitionName="btn_go"/>
</androidx.cardview.widget.CardView>
popup_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/popup2"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="#+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="back"
android:transitionName="btn_back"/>
</androidx.cardview.widget.CardView>
Last thing here is getTransition method. You can just use AutoTransition, it can handle easy layout changes.
private Transition getTransition(boolean open) {
return new AutoTransition();
}
Result:
Also just for demostration I wrote more complex transition where button on first viewgroup appear/dissapear with Slide animation.
private Transition getTransition(boolean open) {
Slide btnGo = new Slide(Gravity.RIGHT);
btnGo.addTarget("btn_go");
ChangeBounds bgBounds = new ChangeBounds();
bgBounds.addTarget("bg");
Fade btnBack = new Fade();
btnBack.addTarget("btn_back");
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
if (open) {
set.addTransition(btnGo);
set.addTransition(bgBounds);
set.addTransition(btnBack);
} else {
set.addTransition(btnBack);
set.addTransition(bgBounds);
set.addTransition(btnGo);
}
return set;
}
Result:
Note that transitionName for background should be same in both layouts.
All transition classes here are from androix package so code is backward compatible. But if you need support pre Lollipop devices you should set transitionName via ViewCompat.setTransitionName method.
You can check my another answer with more difficult/custom transition.
I'm trying to make a Floating Action Button Menu in my app. It should look like the FAB in the Google Calendar app, which is the kind of a active FAB shown by the Material Design Guideline:
See here:
https://material.io/guidelines/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button
Under "The floating action button changes color on focus and lifts upon being selected." there are two videos. The right one shows what this menu should look like. I have a menu like button that works perfectly but what I cannot achive is this gray background that blocks the whole UI (like an alert) with the action and task bar...
Normal:
And selected:
As you can see, the material design guideline tells us that a selected FAB should block the whole UI. But I don't know how...
So what I have at the moment:
I have a global_fab.xml that holds my two FABs:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:id="#+id/fab_background"
android:visibility="gone">
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/global_fab_mini"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="90dp"
android:layout_marginRight="24dp"
android:src="#drawable/ic_credentials_light"
android:theme="#style/Base.Widget.AppCompat.ImageButton"
android:visibility="gone"
app:backgroundTint="#color/cool_grey"
app:fabSize="mini" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/global_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add_light"
android:theme="#style/Base.Widget.AppCompat.ImageButton"
app:fabSize="normal"
android:visibility="visible" />
</RelativeLayout>
</layout>
This FAB has a corresponding ViewGroup Class:
package de.mycompany.ui.view;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import com.mycompany.package.android.R;
import com.mycompany.package.android.databinding.GlobalFabBinding;
public class GlobalFABView extends FrameLayout implements IGlobalFABView {
private GlobalFabBinding globalFABViewBinding;
private Listener listener;
private boolean fabMenuOpen = false;
public GlobalFABView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public GlobalFABView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
globalFABViewBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.global_fab, this, false);
addView(globalFABViewBinding.getRoot());
this.globalFABViewBinding.globalFab.setOnClickListener(this::globalFabClicked);
this.globalFABViewBinding.fabBackground.setOnClickListener(this::backgroundClicked);
}
private void globalFabClicked(View v) {
this.listener.mainFabClicked();
}
private void backgroundClicked(View v) {
this.listener.backgroundClicked();
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void setListener(Listener listener) {
this.listener = listener;
}
#Override
public void toggleFabMenu() {
Animation fabAnimation = AnimationUtils.loadAnimation(this.getContext(), this.fabMenuOpen ?
R.anim.global_fab_close :
R.anim.global_fab_open);
final boolean fabMenuOpen = this.fabMenuOpen;
if (!fabMenuOpen) {
globalFABViewBinding.globalFabMini.setVisibility(VISIBLE);
}
globalFABViewBinding.fabBackground.setVisibility(
fabMenuOpen ? GONE : VISIBLE
);
fabAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// Nothing to do.
}
#Override
public void onAnimationEnd(Animation animation) {
if (fabMenuOpen) {
globalFABViewBinding.globalFabMini.setVisibility(GONE);
globalFABViewBinding.globalFab.setSelected(!fabMenuOpen);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
// Nothing to do.
}
});
globalFABViewBinding.globalFabMini.startAnimation(fabAnimation);
this.fabMenuOpen = !fabMenuOpen;
}
}
My menu opens and closes without problems (I have two anim xmls for this). The Background RelativeLayout (+id/fab_background) is there to handle the "click anywhere and close menu" event.
Now I add this into any activty I want it:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="#+id/fab_holder">
<include layout="#layout/app_bar_with_progress_bar" android:id="#+id/appbar"/>
<de.mycompany.ui.view.HomeView
android:id="#+id/home_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appbar" />
<de.mycompany.ui.view.GlobalFABView
android:id="#+id/global_fab_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
OK, I got this.
in order to lay a new layer over the whole screen we need to start a new activity that is transparent.
I created an activity that holds the menu. Into my normal activity I only added one Floating Action Button. In the click action of this, I open my MenuActivity without animations, so I can animate the appearance of the Floating Action Button Menu. This is my Activity Layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fab_background"
android:background="#color/fab_menu_background"
android:visibility="gone">
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/global_fab_mini"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="90dp"
android:layout_marginRight="24dp"
android:src="#drawable/ic_credentials_light"
android:theme="#style/Base.Widget.AppCompat.ImageButton"
android:visibility="gone"
app:backgroundTint="#color/cool_grey"
app:fabSize="mini" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/global_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add_light"
android:theme="#style/Base.Widget.AppCompat.ImageButton"
app:fabSize="normal"
android:visibility="visible" />
<TextView
android:text="#string/fab_mini_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:id="#+id/fab_mini_label"
android:background="#drawable/fab_label_background"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_marginRight="4dp"
android:elevation="2dp"
android:textSize="14dp"
android:layout_alignBottom="#+id/global_fab"
android:layout_toStartOf="#+id/global_fab"
android:visibility="gone"/>
<TextView
android:text="#string/fab_main_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fab_main_label"
android:background="#drawable/fab_label_background"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:elevation="2dp"
android:textSize="14dp"
android:layout_marginBottom="41dp"
android:layout_above="#+id/fab_mini_label"
android:layout_alignStart="#+id/fab_mini_label"
android:visibility="gone" />
</RelativeLayout>
</layout>
In my Activity I have this function:
public void toggleFabMenu() {
Animation fabAnimation = AnimationUtils.loadAnimation(this.getContext(), this.fabMenuOpen ?
R.anim.global_fab_close :
R.anim.global_fab_open);
Animation labelAnimation = AnimationUtils.loadAnimation(this.getContext(), this.fabMenuOpen ?
R.anim.global_fab_labels_close :
R.anim.global_fab_labels_open);
Animation backgroundAnimation = AnimationUtils.loadAnimation(this.getContext(), this.fabMenuOpen ?
R.anim.global_fab_menu_background_close :
R.anim.global_fab_menu_background_open);
final boolean fabMenuOpen = this.fabMenuOpen;
if (!fabMenuOpen) {
globalFABViewBinding.globalFabMini.setVisibility(VISIBLE);
globalFABViewBinding.fabMiniLabel.setVisibility(VISIBLE);
globalFABViewBinding.fabMainLabel.setVisibility(VISIBLE);
globalFABViewBinding.fabBackground.setVisibility(VISIBLE);
}
fabAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
if (fabMenuOpen) {
globalFABViewBinding.globalFabMini.setVisibility(GONE);
globalFABViewBinding.fabMiniLabel.setVisibility(GONE);
globalFABViewBinding.fabMainLabel.setVisibility(GONE);
globalFABViewBinding.globalFab.setSelected(!fabMenuOpen);
}
}
#Override
public void onAnimationEnd(Animation animation) {
if (fabMenuOpen) {
globalFABViewBinding.fabBackground.setVisibility(GONE);
listener.menuDisappeared();
}
}
#Override
public void onAnimationRepeat(Animation animation) {
// Nothing to do.
}
});
globalFABViewBinding.globalFabMini.startAnimation(fabAnimation);
globalFABViewBinding.fabMiniLabel.startAnimation(labelAnimation);
globalFABViewBinding.fabMainLabel.startAnimation(labelAnimation);
globalFABViewBinding.fabBackground.startAnimation(backgroundAnimation);
this.fabMenuOpen = !fabMenuOpen;
}
In the animations I have fade animations for the labels and the background and a transition animation that moves my fab mini button to the place it belongs.
Now the trick to fit the background even over the status bar is, we cannot do it! So we have to find a workaround and this is not very obvious. First I thought to make the activity fullscreen but then the status bar disappears. So we have to let the status bar there but we need to make it transparent. So we see the color of the statusbar that lays behind it and can lay over our background. To do this I created a new theme:
<style name="Theme.Transparent" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:immersive">false</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowAnimationStyle">#null</item>
<item name="colorPrimaryDark">#android:color/transparent</item>
</style>
Yes. this is exactly what I want.
I tried to find an answer for myself but couldn't find it.
I need make badge on the MenuItem icon in the Toolbar, like this:
How can I make this?
Here is step by step functionality:
add menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/actionNotifications"
android:icon="#drawable/ic_info_outline_white_24dp"
android:menuCategory="secondary"
android:orderInCategory="1"
android:title="Cart"
app:actionLayout="#layout/notification_layout"
app:showAsAction="always" />
</menu>
Then add notification_layout.xml, this layout will be used as the notification icons layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:background="#android:color/transparent"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/hotlist_bell"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:contentDescription="Notification Icon"
android:gravity="center"
android:src="#drawable/ic_info_outline_white_24dp" />
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/txtCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/x5dp"
android:layout_marginLeft="#dimen/x10dp"
android:layout_marginRight="0dp"
android:background="#drawable/pointer_"
android:gravity="center"
android:minWidth="17sp"
android:text="0"
android:textColor="#ffffffff"
android:textSize="12sp" />
</RelativeLayout>
now inside Activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
final View notificaitons = menu.findItem(R.id.actionNotifications).getActionView();
txtViewCount = (TextView) notificaitons.findViewById(R.id.txtCount);
updateHotCount(count++);
txtViewCount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateHotCount(count++);
}
});
notificaitons.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO
}
});
return true;
}
You can put following function (taken from stackoverflow) inside the activity to update counter:
public void updateHotCount(final int new_hot_number) {
count = new_hot_number;
if (count < 0) return;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (count == 0)
txtViewCount.setVisibility(View.GONE);
else {
txtViewCount.setVisibility(View.VISIBLE);
txtViewCount.setText(Integer.toString(count));
// supportInvalidateOptionsMenu();
}
}
});
}
I think it is possible with :
<ImageView
android:id="#+id/counterBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/unread_background" /> <!-- your icon -->
<TextView
android:id="#+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="8sp"
android:layout_centerInParent="true"
android:textColor="#FFFFFF" />
And then using it for that icon as background.also, you need to remove/disable the default icon too.
You may want to take a look:
Remove App Icon from Navigation Drawer ActionBar Does not work
Remove the navigation drawer icon and use the app icon to open
https://stackoverflow.com/a/29160904/4409113
Also, in the android-sdk/platforms/android-22/data/res, there should be that icon. You just need to find that and use it for your purpose (for example, adding that ImageView and adding it asbackground)
Take a look: https://stackoverflow.com/a/34999691/4409113
MaterialToolbar has ability to add BadgeDrawable:
For example in your Activity you can add the badge like this:
val toolbar: MaterialToolbar = findViewById(R.id.toolbar)
val badgeDrawable = BadgeDrawable.create(this).apply {
isVisible = true
backgroundColor = neededBadgeColor
number = neededNumber
}
BadgeUtils.attachBadgeDrawable(badgeDrawable, toolbar, R.id.item_in_toolbar_menu)