如何在滚动时修复折叠工具栏中的视图? [英] How to fix a view in collapsing toolbar while scrolling?

查看:134
本文介绍了如何在滚动时修复折叠工具栏中的视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在其中实现折叠工具栏,其中包含两个 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 >

<! - 我的小工具 - >

< / LinearLayout>
< /android.support.v4.widget.NestedScrollView>



我知道我能做到这一点使用 scrollFlag 的样式类型。我已经阅读了这篇关于滚动标记的文章。但是不能找到如何使用它来实现此目的。

我还想更改 EditText 的字体大小,如上面的<$ c $所示C> GIF 。



但第一个问题是如何修复工具栏中的一个视图,并在用户向上滚动时隐藏另一个视图。如果有人用合适的例子解释,那将是很好的。

解决方案

我确信Todoist正在采取另一种方式,但仍然......



这是 xml布局。主要的想法是,当你要隐藏的另一个视图应该在工具栏里面。 > 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>

<! - 您的内容 - >

< /android.support.v4.widget.NestedScrollView>

< /android.support.design.widget.CoordinatorLayout>

然后,为了实现相同的字体大小和上边距动画,我们可以实现 AppBarLayout.OnOffsetChangedListener 并根据滚动偏移更改为我们的属性设置动画。这是活动类

 公共类MainActivity扩展AppCompatActivity 
实现AppBarLayout.OnOffsetChangedListener {

私有静态最终浮点数COLLAPSED_TEXT_SIZE_SP = 18f;

私有静态最终浮点数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;

私人AppBarLayout mAppBarLayout;
私人工具栏mToolbar;
private TextInputEditText editText;
private TextInputLayout textInputLayout;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mToolbar =(工具栏)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);
//更改文本大小以及滚动
editText.setTextSize(TypedValue.COMPLEX_UNIT_PX,expandedTextSize - textSizeDiff * percentage);
//更改顶视图边距以及滚动
((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){
完成();
返回true;
}
返回super.onOptionsItemSelected(item);
}
}

所以,这里为扩展状态我使用默认值我们在xml中应用的值。对于折叠状态,我已经定义了简单常量。根据您的需求随意使用它们。



注意, 当您添加后退按钮或菜单项时工具栏,你应该玩第二个视图的边距(您要隐藏的边距),因为第一个 EditText 工具栏的一部分,因此,它的边距将根据您添加的内容进行更改。



结果:





快乐的编码!


I want to implement collapsing toolbar with two EditText in it, for the purpose of user input. I'm following this answer. The answer gives perfect solution for adding two EditText into the collapsing toolbar. But the behavior is not as expected.

What I've achieved:

Expected Behavior:

My XML code

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

I know I can do this type of styling using scrollFlag. I've read this post about scroll flags.But can't find exactly how to use it for this purpose.
I also want to change the font size of the EditText as shown in the above GIF.

But first question is how to fix one view in toolbar and hide another as user scrolls up. It would be nice if someone explain with suitable example.

解决方案

I'm sure Todoist is doing it another way, but still...

Here is the xml layout. The main idea is that the view, that supposed to be pinned, should be inside Toolbar, when another view, which you want to hide, should be inside CollapsingToolbarLayout with a decent top margin, to prevent overlapping:

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

Then, to achieve the same font size and top margin animation, we can implement AppBarLayout.OnOffsetChangedListener and animate our properties according to scrolling offset changes. Here is the 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);
    }
} 

So, here for expanded state I've used default values, that we applied in our xml. For collapsed state I've defined simple constants. Feel free to fit them for your needs.

Note, when you add a back button or menu items to the Toolbar, you should play around with left and right margins of the second view (the one you want to hide), because the first EditText is a part of Toolbar, therefore its margins will be changed according to what you did add.

Result:

Happy coding!

这篇关于如何在滚动时修复折叠工具栏中的视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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