[英]CoordinatorLayout custom behavior at right of Toolbar with AppBarLayout
[英]CoordinatorLayout custom behavior with AppBarLayout
我試圖在設置頁面上實現與Telegram相似的行為,也就是說,有一個CircleImage,當向上滾動到Topbar標題的左邊時,當向下滾動到達擴展的AppBarLayout的中間時。
我的工作基於這個例子:
https://github.com/saulmm/CoordinatorBehaviorExample
但在這種情況下,原始編碼器會重新創建兩次Topbar。 我不想這樣做,頂部欄的默認行為是我需要的,我也想利用漢堡包菜單和開箱即用的選項菜單。
這是我的視圖層次結構:
DrawerLayout
|
|---CoordinatorLayout
|--AppBarLayout
| |-CollapsingToolbarLayout
| |-ImageView (backdrop image)
| |-Toolbar
|--NestedScrollView
|--ImageView (circleimage avatar)
正如您所看到的,我無法使工具欄布局成為我的CircleImage的兄弟,因此我無法在layoutDependsOn
方法layoutDependsOn
它們綁定在一起。 我嘗試綁定到AppBarLayout基於github repo上的代碼,但說實話,我無法理解原始代碼中發生的事情。
我的行為與掃羅的行為大致相同。 最大的區別是,我喜歡把一個不可見的視圖像一個Space
,我想圓圖像結束,然后使用該視圖的邊界,以確定如何移動和大小的圓形圖像。
public class CollapsingImageBehavior extends CoordinatorLayout.Behavior<View> {
private final static int X = 0;
private final static int Y = 1;
private final static int WIDTH = 2;
private final static int HEIGHT = 3;
private int mTargetId;
private int[] mView;
private int[] mTarget;
public CollapsingImageBehavior() {
}
public CollapsingImageBehavior(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CollapsingImageBehavior);
mTargetId = a.getResourceId(R.styleable.CollapsingImageBehavior_collapsedTarget, 0);
a.recycle();
}
if (mTargetId == 0) {
throw new IllegalStateException("collapsedTarget attribute not specified on view for behavior");
}
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
setup(parent, child);
AppBarLayout appBarLayout = (AppBarLayout) dependency;
int range = appBarLayout.getTotalScrollRange();
float factor = -appBarLayout.getY() / range;
int left = mView[X] + (int) (factor * (mTarget[X] - mView[X]));
int top = mView[Y] + (int) (factor * (mTarget[Y] - mView[Y]));
int width = mView[WIDTH] + (int) (factor * (mTarget[WIDTH] - mView[WIDTH]));
int height = mView[HEIGHT] + (int) (factor * (mTarget[HEIGHT] - mView[HEIGHT]));
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = width;
lp.height = height;
child.setLayoutParams(lp);
child.setX(left);
child.setY(top);
return true;
}
private void setup(CoordinatorLayout parent, View child) {
if (mView != null) return;
mView = new int[4];
mTarget = new int[4];
mView[X] = (int) child.getX();
mView[Y] = (int) child.getY();
mView[WIDTH] = child.getWidth();
mView[HEIGHT] = child.getHeight();
View target = parent.findViewById(mTargetId);
if (target == null) {
throw new IllegalStateException("target view not found");
}
mTarget[WIDTH] += target.getWidth();
mTarget[HEIGHT] += target.getHeight();
View view = target;
while (view != parent) {
mTarget[X] += (int) view.getX();
mTarget[Y] += (int) view.getY();
view = (View) view.getParent();
}
}
}
這是布局。 我發現一件重要的事情是圓形圖像視圖需要設置一個高程,以便它在折疊模式下布置在工具欄的頂部,否則它將在工具欄后面而不顯示。
<?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:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.krislarson.customcoordinatorlayoutbehavior.ScrollingActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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="280dp"
android:minHeight="108dp"
android:fitsSystemWindows="true"
app:title="Abby"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="center_horizontal"
app:expandedTitleMarginTop="140dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/sunset"
app:layout_collapseMode="parallax"
android:scaleType="centerCrop"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay">
<Space
android:id="@+id/circle_collapsed_target"
android:layout_width="40dp"
android:layout_height="40dp"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scrolling"/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/circle_image_view"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@drawable/abby"
android:layout_marginTop="220dp"
android:layout_gravity="top|center_horizontal"
android:elevation="8dp"
app:border_color="@android:color/black"
app:border_width="2dp"
app:collapsedTarget="@id/circle_collapsed_target"
app:layout_behavior="com.krislarson.customcoordinatorlayoutbehavior.CollapsingImageBehavior"/>
</android.support.design.widget.CoordinatorLayout>
您可以在https://github.com/klarson2/CustomCoordinatorLayoutBehavior上看到整個演示項目
一種可能性是,為您的自定義視圖ToolBar
和隱藏在紅點ToolBar
,如果它被擴展,並顯示一個ImageView
有紅點,而不是(當工具欄被折疊這是隱藏的)。
您可以在此答案中查看如何將自定義視圖添加到ToolBar
: https : //stackoverflow.com/a/27859966/5052976
執行此操作后,只需創建一個在展開ToolBar
時可見的ImageView
。
final CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsingToolbarLayout);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
//show toolbar dot and hide imageview dot
isShow = true;
} else if(isShow) {
//hide toolbar dot and show imageview dot
isShow = false;
}
}
});
不幸的是我現在無法測試,但我認為它應該工作;-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.