展开时 CollapsingToolbarLayout 底部的菜单项 [英] Menu item on bottom of CollapsingToolbarLayout when expanded

查看:25
本文介绍了展开时 CollapsingToolbarLayout 底部的菜单项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索了一段时间,如下图所示,但不幸的是我找不到任何类似的东西

edit menu item 在展开时移动到 CollapsingToolbarLayout 的底部

我尝试了很长的菜单项属性组合,但没有成功

这是我的尝试

我的屏幕xml

<android.support.design.widget.AppBarLayoutandroid:id="@+id/app_bar"android:layout_width="match_parent"android:layout_height="@dimen/app_bar_height"机器人:fitsSystemWindows =真"android:theme="@style/AppTheme.AppBarOverlay"><android.support.design.widget.CollapsingToolbarLayoutandroid:id="@+id/toolbar_layout"android:layout_width="match_parent"android:layout_height="match_parent"机器人:fitsSystemWindows =真"app:contentScrim="?attr/colorPrimary"app:layout_scrollFlags="scroll|exitUntilCollapsed"app:toolbarId="@+id/toolbar"><图像视图android:id="@+id/照片"android:scaleType="centerCrop"android:transitionName="@string/ambassador_photo"android:layout_width="match_parent"android:layout_height="match_parent"机器人:layout_gravity="中心"机器人:fitsSystemWindows =真"应用程序:layout_collapseMode="视差"android:contentDescription="@string/ambassador_photo"/><android.support.v7.widget.Toolbarandroid:id="@+id/工具栏"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"应用程序: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>

我的菜单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"工具:context=".ui.activities.AmbassadorActivity"><项目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"应用程序: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"应用程序:showAsAction="ifRoom"android:orderInCategory="100"android:icon="@drawable/ic_edit_white_24dp"/></菜单>

如何实现像WhatsApp组一样的菜单项行为?

感谢您的任何建议!

解决方案

来自

希望这对你有帮助.

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!

解决方案

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.!

这篇关于展开时 CollapsingToolbarLayout 底部的菜单项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆