Android 滚动隐藏标题栏 和FAB按钮实现
主页面:
package com.loaderman.samplecollect.hideonscroll; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Button; import com.loaderman.samplecollect.R; public class MainHideScrollyActivity extends AppCompatActivity implements View.OnClickListener { private Button partOneButton; private Button partTwoButton; private Button partThreeButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_hide); initToolbar(); partOneButton = (Button) findViewById(R.id.partOneButton); partTwoButton = (Button) findViewById(R.id.partTwoButton); partThreeButton = (Button) findViewById(R.id.partThreeButton); partOneButton.setOnClickListener(this); partTwoButton.setOnClickListener(this); partThreeButton.setOnClickListener(this); } private void initToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); setTitle(getString(R.string.app_name)); } @Override public void onClick(View v) { if(v.equals(partOneButton)) { startActivity(PartOneActivity.class); } else if(v.equals(partTwoButton)) { startActivity(PartTwoActivity.class); } else if(v.equals(partThreeButton)){ startActivity(PartThreeActivity.class); } } private void startActivity(Class<?> activityClass) { Intent myIntent = new Intent(this, activityClass); startActivity(myIntent); } }
RecyclerView滑动监听
package com.loaderman.samplecollect.hideonscroll; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; /* * This class is a ScrollListener for RecyclerView that allows to show/hide * views when list is scrolled. It assumes that you have added a header * to your list. @see pl.michalz.hideonscrollexample.RecyclerAdapter * */ public abstract class HidingScrollListener extends RecyclerView.OnScrollListener { private static final int HIDE_THRESHOLD = 20; private int mScrolledDistance = 0; private boolean mControlsVisible = true; @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int firstVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); if (firstVisibleItem == 0) { if(!mControlsVisible) { onShow(); mControlsVisible = true; } } else { if (mScrolledDistance > HIDE_THRESHOLD && mControlsVisible) { onHide(); mControlsVisible = false; mScrolledDistance = 0; } else if (mScrolledDistance < -HIDE_THRESHOLD && !mControlsVisible) { onShow(); mControlsVisible = true; mScrolledDistance = 0; } } if((mControlsVisible && dy>0) || (!mControlsVisible && dy<0)) { mScrolledDistance += dy; } } public abstract void onHide(); public abstract void onShow(); }
工具类
package com.loaderman.samplecollect.hideonscroll; import android.content.Context; import android.content.res.TypedArray; import com.loaderman.samplecollect.R; public class Utils { public static int getToolbarHeight(Context context) { final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes( new int[]{R.attr.actionBarSize}); int toolbarHeight = (int) styledAttributes.getDimension(0, 0); styledAttributes.recycle(); return toolbarHeight; } public static int getTabsHeight(Context context) { return (int) context.getResources().getDimension(R.dimen.tabsHeight); } }
FAB按钮滑动行为
package com.loaderman.samplecollect.hideonscroll; import android.content.Context; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.FloatingActionButton; import android.util.AttributeSet; import android.view.View; public class ScrollingFABBehavior extends FloatingActionButton.Behavior { private int toolbarHeight; public ScrollingFABBehavior(Context context, AttributeSet attrs) { super(); this.toolbarHeight = Utils.getToolbarHeight(context); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) { return super.layoutDependsOn(parent, fab, dependency) || (dependency instanceof AppBarLayout); } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) { boolean returnValue = super.onDependentViewChanged(parent, fab, dependency); if (dependency instanceof AppBarLayout) { CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); int fabBottomMargin = lp.bottomMargin; int distanceToScroll = fab.getHeight() + fabBottomMargin; float ratio = (float)dependency.getY()/(float)toolbarHeight; fab.setTranslationY(-distanceToScroll * ratio); } return returnValue; } }
RecyclerAdapter
package com.loaderman.samplecollect.hideonscroll; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.loaderman.samplecollect.R; import java.util.List; /* * RecyclerView Adapter that allows to add a header view. * */ public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int TYPE_HEADER = 2; private static final int TYPE_ITEM = 1; private List<String> mItemList; public RecyclerAdapter(List<String> itemList) { mItemList = itemList; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Context context = parent.getContext(); if (viewType == TYPE_ITEM) { final View view = LayoutInflater.from(context).inflate(R.layout.recycler_item, parent, false); return RecyclerItemViewHolder.newInstance(view); } else if (viewType == TYPE_HEADER) { final View view = LayoutInflater.from(context).inflate(R.layout.recycler_header, parent, false); return new RecyclerHeaderViewHolder(view); } throw new RuntimeException("There is no type that matches the type " + viewType + " + make sure your using types correctly"); } @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if (!isPositionHeader(position)) { RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder; String itemText = mItemList.get(position - 1); // header holder.setItemText(itemText); } } public int getBasicItemCount() { return mItemList == null ? 0 : mItemList.size(); } @Override public int getItemViewType(int position) { if (isPositionHeader(position)) { return TYPE_HEADER; } return TYPE_ITEM; } @Override public int getItemCount() { return getBasicItemCount() + 1; // header } private boolean isPositionHeader(int position) { return position == 0; } }
package com.loaderman.samplecollect.hideonscroll; import android.support.v7.widget.RecyclerView; import android.view.View; public class RecyclerHeaderViewHolder extends RecyclerView.ViewHolder { public RecyclerHeaderViewHolder(View itemView) { super(itemView); } }
package com.loaderman.samplecollect.hideonscroll; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.TextView; import com.loaderman.samplecollect.R; public class RecyclerItemViewHolder extends RecyclerView.ViewHolder { private final TextView mItemTextView; public RecyclerItemViewHolder(final View parent, TextView itemTextView) { super(parent); mItemTextView = itemTextView; } public static RecyclerItemViewHolder newInstance(View parent) { TextView itemTextView = (TextView) parent.findViewById(R.id.itemTextView); return new RecyclerItemViewHolder(parent, itemTextView); } public void setItemText(CharSequence text) { mItemTextView.setText(text); } }
页面一
package com.loaderman.samplecollect.hideonscroll; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageButton; import com.loaderman.samplecollect.R; import java.util.ArrayList; import java.util.List; public class PartOneActivity extends AppCompatActivity { private Toolbar mToolbar; private ImageButton mFabButton; @Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.AppThemeRed); super.onCreate(savedInstanceState); setContentView(R.layout.activity_part_one); initToolbar(); mFabButton = (ImageButton) findViewById(R.id.fabButton); initRecyclerView(); } private void initToolbar() { mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); setTitle(getString(R.string.app_name)); mToolbar.setTitleTextColor(getResources().getColor(android.R.color.white)); } private void initRecyclerView() { RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); RecyclerAdapter recyclerAdapter = new RecyclerAdapter(createItemList()); recyclerView.setAdapter(recyclerAdapter); recyclerView.addOnScrollListener(new HidingScrollListener() { @Override public void onHide() { hideViews(); } @Override public void onShow() { showViews(); } }); } private void hideViews() { mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2)); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabButton.getLayoutParams(); int fabBottomMargin = lp.bottomMargin; mFabButton.animate().translationY(mFabButton.getHeight()+fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start(); } private void showViews() { mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)); mFabButton.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start(); } private List<String> createItemList() { List<String> itemList = new ArrayList<>(); for(int i=0;i<20;i++) { itemList.add("Item "+i); } return itemList; } }
页面二
package com.loaderman.samplecollect.hideonscroll; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.RelativeLayout; import android.widget.Toast; import com.loaderman.samplecollect.R; import java.util.ArrayList; import java.util.List; public class PartTwoActivity extends AppCompatActivity { private RelativeLayout mToolbar; private ImageButton mFabButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(R.style.AppThemeGreen); setContentView(R.layout.activity_part_two); mToolbar = findViewById(R.id.rl_title_bar); mFabButton = (ImageButton) findViewById(R.id.fabButton); initRecyclerView(); } private void initRecyclerView() { RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); RecyclerAdapter recyclerAdapter = new RecyclerAdapter(createItemList()); recyclerView.setAdapter(recyclerAdapter); recyclerView.addOnScrollListener(new HidingScrollListener() { @Override public void onHide() { hideViews(); } @Override public void onShow() { showViews(); } }); mFabButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(PartTwoActivity.this,"点击了", Toast.LENGTH_SHORT).show(); } }); } private void hideViews() { mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2)); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabButton.getLayoutParams(); int fabBottomMargin = lp.bottomMargin; mFabButton.animate().translationY(mFabButton.getHeight()+fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start(); } private void showViews() { mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)); mFabButton.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start(); } private List<String> createItemList() { List<String> itemList = new ArrayList<>(); for(int i=0;i<20;i++) { itemList.add("Item "+i); } return itemList; } }
页面三
package com.loaderman.samplecollect.hideonscroll; import android.os.Bundle; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import com.loaderman.samplecollect.R; import java.util.ArrayList; import java.util.List; public class PartThreeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.AppThemeBlue); super.onCreate(savedInstanceState); setContentView(R.layout.activity_part_three); initToolbar(); initViewPagerAndTabs(); } private void initToolbar() { Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); setTitle(getString(R.string.app_name)); mToolbar.setTitleTextColor(getResources().getColor(android.R.color.white)); } private void initViewPagerAndTabs() { ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); pagerAdapter.addFragment(PartThreeFragment.createInstance(20), getString(R.string.tab_1)); pagerAdapter.addFragment(PartThreeFragment.createInstance(4), getString(R.string.tab_2)); viewPager.setAdapter(pagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout); tabLayout.setupWithViewPager(viewPager); } static class PagerAdapter extends FragmentPagerAdapter { private final List<Fragment> fragmentList = new ArrayList<>(); private final List<String> fragmentTitleList = new ArrayList<>(); public PagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); } public void addFragment(Fragment fragment, String title) { fragmentList.add(fragment); fragmentTitleList.add(title); } @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return fragmentList.size(); } @Override public CharSequence getPageTitle(int position) { return fragmentTitleList.get(position); } } }
package com.loaderman.samplecollect.hideonscroll; import android.os.Bundle; import android.support.annotation.Nullable; 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; import com.loaderman.samplecollect.R; import java.util.ArrayList; import java.util.List; public class PartThreeFragment extends Fragment { public final static String ITEMS_COUNT_KEY = "PartThreeFragment$ItemsCount"; public static PartThreeFragment createInstance(int itemsCount) { PartThreeFragment partThreeFragment = new PartThreeFragment(); Bundle bundle = new Bundle(); bundle.putInt(ITEMS_COUNT_KEY, itemsCount); partThreeFragment.setArguments(bundle); return partThreeFragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { RecyclerView recyclerView = (RecyclerView) inflater.inflate( R.layout.fragment_part_three, container, false); setupRecyclerView(recyclerView); return recyclerView; } private void setupRecyclerView(RecyclerView recyclerView) { recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); RecyclerAdapter recyclerAdapter = new RecyclerAdapter(createItemList()); recyclerView.setAdapter(recyclerAdapter); } private List<String> createItemList() { List<String> itemList = new ArrayList<>(); Bundle bundle = getArguments(); if(bundle!=null) { int itemsCount = bundle.getInt(ITEMS_COUNT_KEY); for (int i = 0; i < itemsCount; i++) { itemList.add("Item " + i); } } return itemList; } }
主页面布局activty_main_hide.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="center"> <Button android:id="@+id/partOneButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/part_one"/> <Button android:id="@+id/partTwoButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/part_two"/> <Button android:id="@+id/partThreeButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/part_three"/> </LinearLayout> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary"/> </FrameLayout>
activity_part_one.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary"/> <ImageButton android:id="@+id/fabButton" android:layout_width="56dp" android:layout_height="56dp" android:layout_gravity="bottom|right" android:layout_marginBottom="16dp" android:layout_marginRight="16dp" android:background="@drawable/fab_bcg" android:src="@drawable/ic_favorite_outline_white_24dp" android:contentDescription="@string/fab_description"/> </FrameLayout>
activity_part_two.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary"/> <ImageButton android:id="@+id/fabButton" android:layout_width="56dp" android:layout_height="56dp" android:layout_gravity="bottom|right" android:layout_marginBottom="16dp" android:layout_marginRight="16dp" android:background="@drawable/fab_bcg" android:src="@drawable/ic_favorite_outline_white_24dp" android:contentDescription="@string/fab_description"/> </FrameLayout>
activity_part_three.xml
<?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" android:id="@+id/coordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appBarLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" /> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabTextColor="@android:color/white" app:tabSelectedTextColor="@android:color/white" app:tabIndicatorColor="@android:color/white" app:tabIndicatorHeight="3dp"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.FloatingActionButton android:id="@+id/fabButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_favorite_outline_white_24dp" app:borderWidth="0dp" app:layout_behavior="com.loaderman.samplecollect.hideonscroll.ScrollingFABBehavior"/> </android.support.design.widget.CoordinatorLayout>
recycler_item,xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="8dp" card_view:cardCornerRadius="4dp"> <TextView android:id="@+id/itemTextView" android:layout_width="match_parent" android:layout_height="?attr/listPreferredItemHeight" android:gravity="center_vertical" android:padding="8dp" style="@style/Base.TextAppearance.AppCompat.Body2"/> </android.support.v7.widget.CardView>
recycler_header.xml
<?xml version="1.0" encoding="utf-8"?> <View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"/>
效果图:
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!