I've been searching for a while as shown on the following images but unfortunately I was not able to find anything similar
edit menu item
is moving to bottom of CollapsingToolbarLayout
when it is expanded
I tried a long combination of atributes for menu item but without success
This is my attempt
My screen xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".ui.activities.AmbassadorActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<ImageView
android:id="@+id/photo"
android:scaleType="centerCrop"
android:transitionName="@string/ambassador_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:contentDescription="@string/ambassador_photo" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_ambassador" />
</android.support.design.widget.CoordinatorLayout>
My menu xml
<menu 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"
tools:context=".ui.activities.AmbassadorActivity">
<item
android:id="@+id/action_save"
android:title="@string/save"
android:icon="@drawable/ic_save_white_24dp"
android:orderInCategory="300"
app:showAsAction="always" />
<item android:id="@+id/action_skills"
android:title="@string/skills"
app:showAsAction="ifRoom"
android:orderInCategory="200"
android:icon="@drawable/ic_local_activity_white_24dp"/>
<item android:id="@+id/action_edit_name"
android:title="@string/edit_name"
app:showAsAction="ifRoom"
android:orderInCategory="100"
android:icon="@drawable/ic_edit_white_24dp"/>
</menu>
How to implement this menu item behavior like WhatsApp group?
Thanks for any suggestion!
CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout .
The solution is simple, we just need to set the app:scrimAnimationDuration=”0" in our collapsing toolbar layout like the below code snippet. Now just run the code and see the results, you will see then there will be no fading animation anymore.
From the suggested project i will show you some modified approach to get your desired behaviour.
Also i added my project in github also Check Here
Demonstration
Coordinatelayout
behaviour to extended view.onOffsetchangedListener
.Both TopView & ExtendedView should be same view which is stayed at top & extended in collapsing.
Here is the code
header_view.xml(Extended View)
<?xml version="1.0" encoding="utf-8"?>
<com.md.whatsappgroup_collapseview.HeaderView
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="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/edit"
android:layout_toStartOf="@id/edit"
android:gravity="start|center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="@dimen/header_view_start_text_size"
android:textStyle="bold" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/edit"
android:layout_toStartOf="@id/edit"
android:singleLine="true"
android:gravity="start"
android:textColor="@android:color/white"
android:layout_below="@+id/name"/>
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="@android:color/transparent"
app:srcCompat="@drawable/ic_edit_white_24dp"
/>
</com.md.whatsappgroup_collapseview.HeaderView>
header_view_top.xml(Top View)
<?xml version="1.0" encoding="utf-8"?>
<com.md.whatsappgroup_collapseview.HeaderView
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="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/edit"
android:layout_toStartOf="@id/edit"
android:gravity="start"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="@dimen/header_view_end_text_size"
android:textStyle="bold" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/edit"
android:layout_toStartOf="@id/edit"
android:singleLine="true"
android:gravity="start"
android:textColor="@android:color/white"
android:layout_below="@+id/name"/>
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:background="@android:color/transparent"
app:srcCompat="@drawable/ic_edit_white_24dp"
/>
</com.md.whatsappgroup_collapseview.HeaderView>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="400dp"
android:fitsSystemWindows="true"
app:scrimVisibleHeightTrigger="60dp"
app:scrimAnimationDuration="300"
app:statusBarScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/photo"
android:contentDescription="@string/thumbnail"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"
android:fitsSystemWindows="true"
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay">
<include
android:id="@+id/toolbar_header_view"
layout="@layout/header_view_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include
android:id="@+id/float_header_view"
layout="@layout/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/scrollView"
app:layout_behavior="com.md.whatsappgroup_collapseview.HeaderBehaviour" />
<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include layout="@layout/content_main" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
HeaderView.Java(Custom class)
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.RelativeLayout;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
public class HeaderView extends RelativeLayout {
@BindView(R.id.name)
TextView tvName;
@BindView(R.id.description)
TextView tvDescription;
public HeaderView(Context context) {
super(context);
}
public HeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
ButterKnife.bind(this);
}
public void bindTo(String name, String lastSeen) {
this.tvName.setText(name);
this.tvDescription.setText(lastSeen);
}
public void setTextSize(float size) {
tvName.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
}
}
Header_behaviour.java
public class HeaderBehaviour extends CoordinatorLayout.Behavior<HeaderView> {
private Context mContext;
private int mStartMarginLeft;
private int mEndMarginLeft;
private int mMarginRight;
private int mStartMarginBottom;
private float mTitleStartSize;
private float mTitleEndSize;
private boolean isHide;
public HeaderBehaviour(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public HeaderBehaviour(Context context, AttributeSet attrs, Context mContext) {
super(context, attrs);
this.mContext = mContext;
}
public static int getToolbarHeight(Context context) {
int result = 0;
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
return result;
}
@Override
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull HeaderView child, @NonNull View dependency) {
return dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull HeaderView child, @NonNull View dependency) {
shouldInitProperties();
int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange();
float percentage = Math.abs(dependency.getY()) / (float) maxScroll;
float childPosition = dependency.getHeight()
+ dependency.getY()
- child.getHeight()
- (getToolbarHeight(mContext) - child.getHeight()) * percentage / 2;
childPosition = childPosition - mStartMarginBottom * (1f - percentage);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
if (Math.abs(dependency.getY()) >= maxScroll / 2) {
float layoutPercentage = (Math.abs(dependency.getY()) - (maxScroll / 2)) / Math.abs(maxScroll / 2);
lp.leftMargin = (int) (layoutPercentage * mEndMarginLeft) + mStartMarginLeft;
lp.rightMargin = (int) (layoutPercentage * mEndMarginLeft) + mStartMarginLeft;
child.setTextSize(getTranslationOffset(mTitleStartSize, mTitleEndSize, layoutPercentage));
} else {
lp.leftMargin = mStartMarginLeft;
lp.rightMargin = mStartMarginLeft;
}
child.setLayoutParams(lp);
child.setY(childPosition);
if (isHide && percentage < 1) {
child.setVisibility(View.VISIBLE);
isHide = false;
} else if (!isHide && percentage == 1) {
child.setVisibility(View.GONE);
isHide = true;
}
return true;
}
private float getTranslationOffset(float expandedOffset, float collapsedOffset, float ratio) {
return expandedOffset + ratio * (collapsedOffset - expandedOffset);
}
private void shouldInitProperties() {
if (mStartMarginLeft == 0) {
mStartMarginLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_left);
}
if (mEndMarginLeft == 0) {
mEndMarginLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left);
}
if (mStartMarginBottom == 0) {
mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom);
}
if (mMarginRight == 0) {
mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right);
}
if (mTitleStartSize == 0) {
mTitleEndSize = mContext.getResources().getDimensionPixelSize(R.dimen.header_view_end_text_size);
}
if (mTitleStartSize == 0) {
mTitleStartSize = mContext.getResources().getDimensionPixelSize(R.dimen.header_view_start_text_size);
}
}
}
Mainactivity.java
public class MainActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener{
@BindView(R.id.toolbar_header_view)
protected HeaderView toolbarHeaderView;
@BindView(R.id.float_header_view)
protected HeaderView floatHeaderView;
@BindView(R.id.appbar)
protected AppBarLayout appBarLayout;
@BindView(R.id.toolbar)
protected Toolbar toolbar;
@BindView(R.id.collapsing_toolbar)
protected CollapsingToolbarLayout collapsingToolbarLayout;
private boolean isHideToolbarView = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
initUi();
/*Remove no need to change custom scrim colour */
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.photo);
int color = getDominantColor(icon);
collapsingToolbarLayout.setContentScrimColor(color);
collapsingToolbarLayout.setStatusBarScrimColor(color);
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setStatusBarColor(darker(color,0.8f));
}
/*Remove no need to change custom scrim colour*/
}
public static int darker (int color, float factor) {
int a = Color.alpha( color );
int r = Color.red( color );
int g = Color.green( color );
int b = Color.blue( color );
return Color.argb( a,
Math.max( (int)(r * factor), 0 ),
Math.max( (int)(g * factor), 0 ),
Math.max( (int)(b * factor), 0 ) );
}
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
private void initUi() {
appBarLayout.addOnOffsetChangedListener(this);
toolbarHeaderView.bindTo("Group Name", "Created by Developer");
floatHeaderView.bindTo("Group Name", "Created by Developer");
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int maxScroll = appBarLayout.getTotalScrollRange();
float percentage = (float) Math.abs(verticalOffset) / (float) maxScroll;
if (percentage == 1f && isHideToolbarView) {
toolbarHeaderView.setVisibility(View.VISIBLE);
isHideToolbarView = !isHideToolbarView;
} else if (percentage < 1f && !isHideToolbarView) {
toolbarHeaderView.setVisibility(View.GONE);
isHideToolbarView = !isHideToolbarView;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_person_add) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
OUTPUT
Hope this will help you.!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With