Menu item on bottom of CollapsingToolbarLayout when expanded

前端 未结 3 595
醉酒成梦
醉酒成梦 2020-12-14 12:58

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

相关标签:
3条回答
  • 2020-12-14 13:41

    Edit/ Pencil icon doesn't have to be a part of menu.xml, does it?

    You can simply nest stuffs incl. the Edit/ Pencil icon under your Toolbar. Example:

        <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                                    xmlns:app="http://schemas.android.com/apk/res-auto"
                                                    android:id="@+id/appBar1"
                                                    android:layout_width="match_parent"
                                                    android:layout_height="wrap_content"
                                                    android:theme="@style/AppTheme.AppBarOverlay">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolBar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay">
    
                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@android:color/transparent">
    
                    <TextView
                        android:id="@+id/textViewTitle"
                        style="@style/AppToolbarTitle"
                        tools:text="group name"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textColor="@android:color/white"
                        android:visibility="invisible"/>
    
                    <ImageView
                        android:id="@+id/imageLogo"
                        android:layout_width="wrap_content"
                        android:layout_height="@dimen/height_toolbar_logo"
                        android:scaleType="fitStart"
                        android:layout_gravity="right"
                        android:src="@drawable/ic_edit"
                        android:visibility="visible"/>
                </FrameLayout>
            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.AppBarLayout>
    </android.support.design.widget.CoordinatorLayout>
    
    0 讨论(0)
  • 2020-12-14 13:44

    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

    1. Create top_view(which is visible in toolbar) & extended_view(which is visible in collapsing layout).
    2. Create custom class which is common to top_view & extended_view.
    3. Add Coordinatelayout behaviour to extended view.
    4. Update both views visibility,position & size based on AppBar 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.!

    0 讨论(0)
  • 2020-12-14 13:46

    In XML layout:-

    <android.support.design.widget.CoordinatorLayout 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"
        android:fitsSystemWindows="true"
        >
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/app_bar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            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/backdrop"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:fitsSystemWindows="true"
                        android:src="@drawable/ic_user"
                        app:layout_collapseMode="parallax" />
    
                <ImageView
                    android:id="@+id/img_edit"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="16dp"
                    android:src="@android:drawable/ic_menu_edit"
                    android:layout_gravity="bottom|end"
                    android:layout_marginBottom="20dp"
                    app:layout_collapseMode="none"
                     />
    
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"
                    app:title="Group"
                    app:popupTheme="@style/AppTheme.PopupOverlay" >
    
                </android.support.v7.widget.Toolbar>
    
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>
    
        <include layout="@layout/content_scrolling" />
    
        </android.support.design.widget.CoordinatorLayout>
    

    Menu item 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="com.example.ScrollingActivity">
    
    
        <item
            android:id="@+id/action_search"
            android:orderInCategory="100"
            android:title="@string/action_settings"
            android:icon="@android:drawable/ic_menu_search"
            app:showAsAction="ifRoom" />
    </menu>
    

    In activity:-

    public class ScrollingActivity extends AppCompatActivity {
    
    private AppBarLayout app_bar;
    private boolean appBarExpanded;
    private Menu itemMenu;
    private CollapsingToolbarLayout toolbar_layout;
    private ImageView img_edit;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrolling);
        Toolbar toolbar =  findViewById(R.id.toolbar);
        app_bar =  findViewById(R.id.app_bar);
        toolbar_layout =  findViewById(R.id.toolbar_layout);
        img_edit =  findViewById(R.id.img_edit);
        setSupportActionBar(toolbar);
    
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
    
        app_bar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                //  Vertical offset == 0 indicates appBar is fully expanded.
                if (Math.abs(verticalOffset) > 200) {
                    appBarExpanded = false;
                    img_edit.setVisibility(View.GONE);
                    invalidateOptionsMenu();
                } else {
                    img_edit.setVisibility(View.VISIBLE);
                    appBarExpanded = true;
                    invalidateOptionsMenu();
                }
            }
        });
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_scrolling,menu);
        itemMenu = menu;
        return true;
    }
    
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (itemMenu != null
                && (!appBarExpanded || itemMenu.size() != 1)) {
            //collapsed
            itemMenu.add("Edit")
                    .setIcon(android.R.drawable.ic_menu_edit)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        } else {
            //expanded
    
        }
        return super.onPrepareOptionsMenu(itemMenu);
    }
    

    }

    I have not added subtitle with the toolbar. If you need subtitle you have to use some custom view class or library.

    0 讨论(0)
提交回复
热议问题