滚动时如何修复折叠工具栏中的视图?
How to fix a view in collapsing toolbar while scrolling?
我想实现带有两个 EditText
的折叠工具栏,以供用户输入。我正在关注 this 答案。答案给出了将两个 EditText
添加到折叠工具栏的完美解决方案。但行为并不像预期的那样。
我的收获:
预期行为:
我的XML代码
<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="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_tool_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
app:expandedTitleTextAppearance="@style/Widget.AppCompat.ActionBar.TabText"
app:layout_scrollFlags="scroll|enterAlways"
app:statusBarScrim="?attr/colorAccent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="none"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="none"
app:elevation="0dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingTop="16dp"
android:paddingBottom="56dp"
android:paddingRight="16dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/fNameLayout"
android:layout_marginTop="10dp">
<EditText
android:id="@+id/ltitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Title"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/fNameLayout"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">
<EditText
android:id="@+id/ldesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Description"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="10dp">
<!--my widgets here-->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
我知道我可以使用 scrollFlag
进行此类样式设置。我已阅读 this post about scroll flags.但无法找到具体的使用方法。
我也想把EditText
的字号改成上面的GIF
。
但第一个问题是如何修复工具栏中的一个视图并在用户向上滚动时隐藏另一个视图。如果有人用合适的例子解释,那就太好了。
我确定 Todoist 正在以另一种方式进行操作,但仍然...
这是xml布局。主要思想是,应该固定的视图应该在 Toolbar
内,而您要隐藏的另一个视图应该在 CollapsingToolbarLayout
内,并且上边距合适,以防止重叠:
<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.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_tool_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="?attr/colorAccent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="32dp"
android:layout_marginTop="136dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TextInputEditText
android:id="@+id/ldesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Description"/>
</android.support.design.widget.TextInputLayout>
</FrameLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:layout_marginTop="48dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:textSize="30sp"
android:textColor="@android:color/white"
android:ems="10"/>
</android.support.design.widget.TextInputLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- your content here -->
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
然后,要实现相同的字体大小和上边距动画,我们可以实现 AppBarLayout.OnOffsetChangedListener
并根据滚动偏移量的变化为我们的属性设置动画。这里是 activity class:
public class MainActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener {
private static final float COLLAPSED_TEXT_SIZE_SP = 18f;
private static final float COLLAPSED_TOP_MARGIN_DP = 24f;
private static final float MARGIN_SCROLLER_MULTIPLIER = 4f;
private float expandedTextSize;
private float collapsedTextSize;
private int expandedTopMargin;
private int collapsedTopMargin;
private AppBarLayout mAppBarLayout;
private Toolbar mToolbar;
private TextInputEditText editText;
private TextInputLayout textInputLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mAppBarLayout = (AppBarLayout) findViewById(R.id.appbar);
editText = (TextInputEditText) findViewById(R.id.title);
textInputLayout = (TextInputLayout) findViewById(R.id.lNameLayout);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mAppBarLayout.addOnOffsetChangedListener(this);
expandedTextSize = editText.getTextSize();
collapsedTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, COLLAPSED_TEXT_SIZE_SP, getResources().getDisplayMetrics());
expandedTopMargin = ((ViewGroup.MarginLayoutParams) textInputLayout.getLayoutParams()).topMargin;
collapsedTopMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, COLLAPSED_TOP_MARGIN_DP, getResources().getDisplayMetrics());
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
int maxScroll = appBarLayout.getTotalScrollRange();
float percentage = (float) Math.abs(offset) / maxScroll;
float textSizeDiff = Math.abs(expandedTextSize - collapsedTextSize);
int marginDiff = Math.abs(expandedTopMargin - collapsedTopMargin);
//change text size along with scrolling
editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, expandedTextSize - textSizeDiff * percentage);
//change top view margin along with scrolling
((ViewGroup.MarginLayoutParams) textInputLayout.getLayoutParams()).topMargin = (int) (expandedTopMargin - marginDiff * Math.min(1, percentage * MARGIN_SCROLLER_MULTIPLIER));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
因此,对于展开状态,我使用了默认值,我们在 xml 中应用了默认值。对于折叠状态,我定义了简单的常量。随意满足您的需求。
注意, 当您向 Toolbar
添加后退按钮或菜单项时,您应该使用 left
和 right
第二个视图(您要隐藏的那个)的边距,因为第一个 EditText
是 Toolbar
的一部分,因此它的边距将根据你添加了什么。
结果:
编码愉快!
我想实现带有两个 EditText
的折叠工具栏,以供用户输入。我正在关注 this 答案。答案给出了将两个 EditText
添加到折叠工具栏的完美解决方案。但行为并不像预期的那样。
我的收获:
预期行为:
我的XML代码
<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="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_tool_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
app:expandedTitleTextAppearance="@style/Widget.AppCompat.ActionBar.TabText"
app:layout_scrollFlags="scroll|enterAlways"
app:statusBarScrim="?attr/colorAccent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="none"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="none"
app:elevation="0dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingTop="16dp"
android:paddingBottom="56dp"
android:paddingRight="16dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/fNameLayout"
android:layout_marginTop="10dp">
<EditText
android:id="@+id/ltitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Title"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/fNameLayout"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">
<EditText
android:id="@+id/ldesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Description"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="10dp">
<!--my widgets here-->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
我知道我可以使用 scrollFlag
进行此类样式设置。我已阅读 this post about scroll flags.但无法找到具体的使用方法。
我也想把EditText
的字号改成上面的GIF
。
但第一个问题是如何修复工具栏中的一个视图并在用户向上滚动时隐藏另一个视图。如果有人用合适的例子解释,那就太好了。
我确定 Todoist 正在以另一种方式进行操作,但仍然...
这是xml布局。主要思想是,应该固定的视图应该在 Toolbar
内,而您要隐藏的另一个视图应该在 CollapsingToolbarLayout
内,并且上边距合适,以防止重叠:
<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.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_tool_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="?attr/colorAccent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="32dp"
android:layout_marginTop="136dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TextInputEditText
android:id="@+id/ldesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Description"/>
</android.support.design.widget.TextInputLayout>
</FrameLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.design.widget.TextInputLayout
android:id="@+id/lNameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:layout_marginTop="48dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:textSize="30sp"
android:textColor="@android:color/white"
android:ems="10"/>
</android.support.design.widget.TextInputLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- your content here -->
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
然后,要实现相同的字体大小和上边距动画,我们可以实现 AppBarLayout.OnOffsetChangedListener
并根据滚动偏移量的变化为我们的属性设置动画。这里是 activity class:
public class MainActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener {
private static final float COLLAPSED_TEXT_SIZE_SP = 18f;
private static final float COLLAPSED_TOP_MARGIN_DP = 24f;
private static final float MARGIN_SCROLLER_MULTIPLIER = 4f;
private float expandedTextSize;
private float collapsedTextSize;
private int expandedTopMargin;
private int collapsedTopMargin;
private AppBarLayout mAppBarLayout;
private Toolbar mToolbar;
private TextInputEditText editText;
private TextInputLayout textInputLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mAppBarLayout = (AppBarLayout) findViewById(R.id.appbar);
editText = (TextInputEditText) findViewById(R.id.title);
textInputLayout = (TextInputLayout) findViewById(R.id.lNameLayout);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mAppBarLayout.addOnOffsetChangedListener(this);
expandedTextSize = editText.getTextSize();
collapsedTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, COLLAPSED_TEXT_SIZE_SP, getResources().getDisplayMetrics());
expandedTopMargin = ((ViewGroup.MarginLayoutParams) textInputLayout.getLayoutParams()).topMargin;
collapsedTopMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, COLLAPSED_TOP_MARGIN_DP, getResources().getDisplayMetrics());
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
int maxScroll = appBarLayout.getTotalScrollRange();
float percentage = (float) Math.abs(offset) / maxScroll;
float textSizeDiff = Math.abs(expandedTextSize - collapsedTextSize);
int marginDiff = Math.abs(expandedTopMargin - collapsedTopMargin);
//change text size along with scrolling
editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, expandedTextSize - textSizeDiff * percentage);
//change top view margin along with scrolling
((ViewGroup.MarginLayoutParams) textInputLayout.getLayoutParams()).topMargin = (int) (expandedTopMargin - marginDiff * Math.min(1, percentage * MARGIN_SCROLLER_MULTIPLIER));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
因此,对于展开状态,我使用了默认值,我们在 xml 中应用了默认值。对于折叠状态,我定义了简单的常量。随意满足您的需求。
注意, 当您向 Toolbar
添加后退按钮或菜单项时,您应该使用 left
和 right
第二个视图(您要隐藏的那个)的边距,因为第一个 EditText
是 Toolbar
的一部分,因此它的边距将根据你添加了什么。
结果:
编码愉快!