How I implement new material gmail toolbar without nested scrollview?
Asked Answered
O

4

5

I want to implement new gmail like toolbar without nested scroll view, which is scroll able, but when scroll down background should be visible.

It will look like this: enter image description here

Odoric answered 2/3, 2019 at 8:16 Comment(2)
Did you find any solution ?Stoplight
Were you able to implement it? @koushikQatar
T
3

It's not a nested scrollview, Its recyclerView. If you want such a search bar, you can make it using CardView and Edittext or use Material searchbar library. You can place it locked at that position by using frameLayout or CoordinatorLayout.

Here is a sample Screen I made!.

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="#dadada"
        android:layout_height="match_parent">

        <android.support.v7.widget.CardView
            app:cardUseCompatPadding="true"
            android:layout_margin="8dp"
            app:cardCornerRadius="8dp"
            android:layout_width="match_parent"
            android:layout_height="64dp">

            <android.support.constraint.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ImageView
                    android:id="@+id/imageView2"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginStart="8dp"
                    android:src="@drawable/ic_menu_black_24dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <EditText
                    android:id="@+id/editText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginBottom="8dp"
                    android:background="@android:color/transparent"
                    android:hint="Search..."
                    android:minWidth="100dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toEndOf="@+id/imageView2"
                    app:layout_constraintTop_toTopOf="parent" />

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginTop="8dp"
                    android:layout_marginEnd="8dp"
                    android:layout_marginBottom="8dp"
                    android:src="@drawable/ic_search_black_24dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </android.support.constraint.ConstraintLayout>

        </android.support.v7.widget.CardView>

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </android.support.v7.widget.RecyclerView>

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

Here is the result.

enter image description here

Throes answered 18/3, 2019 at 7:31 Comment(2)
How to implement Searching in this?Qatar
Make your search feature a new activity, link to it... That is what Gmail did. With nice animations of course.Biocellate
W
2

You just need create custom one in your Activity layout like

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <android.support.design.widget.CoordinatorLayout
            android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <android.support.v7.widget.CardView
                android:layout_margin="16dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">


        <android.support.design.widget.AppBarLayout
                android:id="@+id/appbar"

                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_scrollFlags="scroll|enterAlways"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        </android.support.design.widget.AppBarLayout>
        </android.support.v7.widget.CardView>
    </android.support.design.widget.CoordinatorLayout>
    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

And change style of your activity to "NoActionBar". For me it help.

Whydah answered 18/3, 2019 at 6:59 Comment(0)
P
0

For anyone who is trying to implement this with a RecyclerView , just use item view types with different layouts. BaseAdapter that holds the main data:

public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.BaseViewHolder> 

 @Override
    @NonNull
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// this is the main adapter so by default
// it should display the main content.
// Notice the layout being inflated here
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_song_list, null);
        return createViewHolder(v);

    }
// BaseViewHolder is the ViewHolder of this adapter
    protected BaseViewHolder createViewHolder(View view) {
        return new BaseViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final BaseViewHolder holder, final int position) {
        // Do something here
    }

Now create an abstract adapter that extends the previous adapter:

public abstract class BaseHeaderAdapter extends BaseAdapter {

    protected static final int ITEM_HEADER = 0;
    protected static final int ITEM_LIST = 1;

   @NonNull
    @Override
    public BaseAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == ITEM_HEADER) {
// Notice the layout being inflated here
// This is a different layout
            View view = LayoutInflater.from(activity).inflate(R.layout.item_tab_header, parent, false);
            return createViewHolder(view);
        }
// This will return the default layout from the extended adapter
        return super.onCreateViewHolder(parent, viewType);
    }
// BaseAdapter and BaseViewHolder are extended
    @Override
    protected BaseAdapter.BaseViewHolder createViewHolder(View view) {
// Notice: BaseHeaderAdapter is the current adapter
// BaseViewHolder is the extended holder
        return new BaseHeaderAdapter.BaseViewHolder(view);
    }

 @Override
    public int getItemCount() {
        int superItemCount = super.getItemCount();
        return superItemCount == 0 ? 0 : superItemCount + 1;
    }

    @Override
    public int getItemViewType(int position) {
        return position == 0 ? ITEM_HEADER : ITEM_LIST;
    }
// This adapter's ViewHolder
public class BaseHeaderViewHolder extends BaseAdapter.BaseViewHolder {
...
}

}

Now the adapter that displays everything:

public class MyAdapter extends BaseHeaderAdapter
.....
@Override
    protected BaseAdapter.BaseViewHolder createViewHolder(View view) {
        return new MyAdapter.BaseViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final BaseAdapter.BaseViewHolder holder, int position) {
        if (holder.getItemViewType() == ITEM_HEADER) {
// do some stuff
            holder.mHeaderTitle.setText("Header");
        } else {
            super.onBindViewHolder(holder, position - 1);
        }
    }
// The ViewHolder extends the BaseHeaderAdapter.BaseHeaderViewHolder

Final result 2Final result 1

Puritan answered 9/11, 2020 at 7:47 Comment(0)
B
0

You can also solve this with an AppBarLayout and a custom CoordinatorLayout.Behavior. First, setup the layout in this way:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior=".view.SearchBarBehaviour">

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            .../>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        app:elevation="0dp">

        <!-- the searchbar with a layout_margin and transparent background etc -->
        <include layout="@layout/searchbar" />

    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Note the custom behavior set to the SwipeRefreshLayout. It looks like that:

class SearchBarBehaviour(
    context: Context,
    attrs: AttributeSet
) : CoordinatorLayout.Behavior<View>(context, attrs) {

    private var previousY: Float = 0f

    override fun layoutDependsOn(
        parent: CoordinatorLayout, 
        child: View, dependency: View
    ): Boolean = dependency is AppBarLayout

    override fun onDependentViewChanged(
        parent: CoordinatorLayout, 
        child: View, 
        dependency: View
    ): Boolean {
        val currentY = dependency.y
        // When the AppBarLayout scrolls, scroll the RecyclerView for the same distance
        (child as SwipeRefreshLayout)
            .getChildAt(0)
            .scrollBy(0, (previousY - currentY).toInt())

        previousY = currentY
        return false
    }
}

This obviously also works without a SwipeRefreshLayout if you attach the behavior directly to a RecyclerView/NestedScrollView/... and adjust the line in the custom behaviour to scroll the child itself.

This solves the RecyclerView resizing issue of the default ScrollingViewBehavior which causes the RecyclerView to pop up its items when scrolling down.

Beastings answered 17/2, 2021 at 21:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.