Whatsapp 喜欢折叠工具栏 [英] Whatsapp like Collapsing Toolbar

查看:45
本文介绍了Whatsapp 喜欢折叠工具栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我想实现像可折叠工具栏一样的 Whatsapp 主页.也就是说,在向下滚动列表时,工具栏应该向上并且选项卡应该固定在顶部.我怎样才能做到这一点?

这是我的应用栏布局

In my app, I would like to implement Whatsapp home page like collapsible toolbar. That is, while scrolling down the list, the toolbar should go up and the tabs should pin at the top. How can I achieve this?

Here is my appbar layout

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/appbarLayout"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/collapsibleToolBarLayout"
        android:fitsSystemWindows="true"
        app:titleEnabled="false"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">                 

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@color/white"
            app:tabTextColor="@color/product_page_btn_grey"
            app:tabSelectedTextColor="@color/upcomer_background_red"
            app:tabIndicatorColor="@color/upcomer_background_red"
            android:layout_gravity="bottom"
            app:layout_scrollFlags="scroll|enterAlways"
            app:tabContentStart="72dp" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.9"
            android:background="@color/upcomer_background_red"
            app:popupTheme="@style/AppTheme.PopupOverlay" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/title_image_view"
                android:contentDescription="@null"
                android:layout_gravity="start|center_vertical"
                android:visibility="gone"
                android:src="@drawable/title"/>
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/title_layout"
                android:visibility="gone">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:id="@+id/toolbarText"
                    style="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/send_button"
                    android:layout_marginRight="10dp"
                    android:layout_marginEnd="10dp"
                    android:text="@string/send_text"
                    android:textColor="@color/white"
                    android:textSize="18sp"
                    android:textStyle="bold"
                    android:visibility="gone"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentEnd="true"/>

            </RelativeLayout>
    
        </android.support.v7.widget.Toolbar>

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

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

Now the TabLayout is not visible and the Toolbar stays there even though the list in the ViewPager below is scrolled. Kindly help.

解决方案

In order to achieve this functionality a CollapsingToolbarLayout is actually not needed, you can just collapse the Toolbar that is set as the ActionBar.

Here is sample code using a Toolbar for the ActionBar that will collapse, and a TabLayout with a ViewPager.

First ensure that the style used for MainActivity is one that does not have an ActionBar, e.g.:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <!-- ....... -->
</style>

MainActivity.java, that has the FragmentPagerAdapter and sets up the tabs:

public class MainActivity extends AppCompatActivity {

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Get the ViewPager and set it's PagerAdapter so that it can display items
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        PagerAdapter pagerAdapter =
                new PagerAdapter(getSupportFragmentManager(), MainActivity.this);
        viewPager.setAdapter(pagerAdapter);

        // Give the TabLayout the ViewPager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);

        // Iterate over all tabs and set the custom view
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(pagerAdapter.getTabView(i));
        }

    }


    @Override
    public void onResume() {
        super.onResume();
    }
    @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) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    class PagerAdapter extends FragmentPagerAdapter {

        String tabTitles[] = new String[] { "Tab One", "Tab Two", "Tab Three" };
        Context context;

        public PagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        @Override
        public int getCount() {
            return tabTitles.length;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return new BlankFragment();
                case 1:
                    return new BlankFragment();
                case 2:
                    return new BlankFragment();
            }

            return null;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Generate title based on item position
            return tabTitles[position];
        }

        public View getTabView(int position) {
            View tab = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null);
            TextView tv = (TextView) tab.findViewById(R.id.custom_text);
            tv.setText(tabTitles[position]);
            return tab;
        }

    }
}

activity_main.xml

The important parts:

  • Use a CoordinatorLayout
  • Use app:layout_scrollFlags="scroll|enterAlways|snap" in the Toolbar properties
  • Use app:layout_behavior="@string/appbar_scrolling_view_behavior" in the ViewPager properties

Here is the activity_main.xml file:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_layout"
    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/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="6dp">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:elevation="0dp"
        app:layout_scrollFlags="scroll|enterAlways|snap"
        />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        app:tabMode="fixed"
        android:layout_below="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:elevation="0dp"
        app:tabTextColor="#d3d3d3"
        app:tabSelectedTextColor="#ffffff"
        app:tabIndicatorColor="#ff00ff"
        android:minHeight="?attr/actionBarSize"
        />

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_below="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />

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

custom_tab.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/custom_text"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="?attr/selectableItemBackground"
        android:gravity="center"
        android:textSize="16dip"
        android:textColor="#ffffff"
        android:singleLine="true"
        />
</LinearLayout>

BlankFragment.java, this simply adds enough items to make it scroll:

import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;;

public class BlankFragment extends Fragment {

    public BlankFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_blank, container, false);

        RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
        rv.setHasFixedSize(true);
        MyAdapter adapter = new MyAdapter(new String[]{"test one", "test two", "test three", "test four", "test five" , "test six" , "test seven", "test eight" , "test nine"});
        rv.setAdapter(adapter);

        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        rv.setLayoutManager(llm);

        return rootView;
    }

}

fragment_blank.xml, it's important to use a RecyclerView, or any other View that supports nested scrolling, such as a NestedScrollView

(side note: you can call setNestedScrollingEnabled(true) on api-21 and up to make it work with a ListView):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.SearchView
        android:id="@+id/sv_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Search!"
        android:singleLine="true"
        android:inputType="textNoSuggestions"
        android:layout_gravity="start"
        android:layout_marginRight="18dp"
        android:ems="10" >
    </android.support.v7.widget.SearchView>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_recycler_view"
        android:layout_below="@+id/sv_search"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>

MyAdapter.java, the RecyclerView Adapter:

import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public CardView mCardView;
        public TextView mTextView;
        public MyViewHolder(View v) {
            super(v);

            mCardView = (CardView) v.findViewById(R.id.card_view);
            mTextView = (TextView) v.findViewById(R.id.tv_text);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_item, parent, false);
        // set the view's size, margins, paddings and layout parameters
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mTextView.setText(mDataset[position]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

card_item.xml, the circle image and the "blah blah blah" String are both static content, only the tv_text TextView is updated from the data source for this simple example:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="68dp" >

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_margin="10dp"
        android:layout_height="62dp"
        card_view:cardCornerRadius="4dp"
        card_view:elevation="14dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <ImageView
            android:id="@+id/iv_image"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:src="@drawable/abc_btn_radio_material">
        </ImageView>

        <TextView
            android:id="@+id/tv_text"

            android:layout_toRightOf ="@+id/iv_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center" >
        </TextView>

            <TextView
                android:id="@+id/tv_blah"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="blah blah blah......"
                android:layout_below="@+id/tv_text"
                android:layout_toRightOf="@+id/iv_image"
                android:layout_toEndOf="@+id/iv_image">
            </TextView>

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

</RelativeLayout>

build.gradle dependencies:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
    compile 'com.android.support:cardview-v7:23.0.1'
    compile 'com.android.support:recyclerview-v7:23.0.1'
}

Result:

这篇关于Whatsapp 喜欢折叠工具栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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