效果圖如下
主布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".demo4.Demo4Activity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/no_scroll_behavior">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dimen_180"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@mipmap/banner_4" />
<View
android:id="@+id/bg_img"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen_50"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin">
<include layout="@layout/layout_demo5_toolbar" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/layout_demo5_content" />
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
Activity主要方法都有注釋
private void initView() {
StatusBarUtil.setTranslucentForImageView(mActivity, 50, null);
//防止toolbar頂入狀態(tài)欄
CollapsingToolbarLayout.LayoutParams lp2 = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams();
lp2.topMargin = PhoneUtil.getStatusBarHeight(mActivity);
toolbar.setLayoutParams(lp2);
myAppBarLayoutBehavoir = (NoScrollBehavior)
((CoordinatorLayout.LayoutParams) appBar.getLayoutParams()).getBehavior();
}
private void initListener() {
appBar.addOnOffsetChangedListener(this);
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//拿到當(dāng)前fragment
currentFragment = (Demo5ItemFragment) list_fragment.get(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void initTab() {
//初始化tab
list_title = new ArrayList<>();
list_title.add("軍事");
list_title.add("娛樂(lè)");
list_title.add("萌寵");
list_title.add("生活");
list_id = new ArrayList<>();
list_id.add(1);
list_id.add(2);
list_id.add(3);
list_id.add(4);
list_fragment = new ArrayList<>();
for (int i = 0; i < list_id.size(); i++) {
Demo5ItemFragment orderItemFragment = Demo5ItemFragment.newInstance(list_id.get(i));
list_fragment.add(orderItemFragment);
}
currentFragment = (Demo5ItemFragment) list_fragment.get(0);
indicatorAdapter = new TabPageIndicatorAdapter(getSupportFragmentManager(), list_fragment, list_title);
viewpager.setAdapter(indicatorAdapter);
tabLayout.setupWithViewPager(viewpager);
}
@Override
public void onDestroy() {
super.onDestroy();
appBar.removeOnOffsetChangedListener(this);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//頂部漸變 標(biāo)題欄處理
float percent = Float.valueOf(Math.abs(verticalOffset)) / Float.valueOf(appBarLayout.getTotalScrollRange());
int alpha = (int) (255 * percent);
titleLayout.setBackgroundColor(Color.argb(alpha, 26, 128, 210));
tvTitle.setAlpha(alpha);
bgImg.setBackgroundColor(Color.argb(alpha, 26, 128, 210));
if (percent < 0.5) {
rlBack.setBackgroundResource(R.drawable.oval_shadow);
} else {
rlBack.setBackground(null);
}
//滑動(dòng)事件處理
if (percent == 0) {
//當(dāng)完全展開(kāi)時(shí) appbar可滑動(dòng) 禁止refresh(可根據(jù)需求不禁止刷新)
myAppBarLayoutBehavoir.setNoScroll(false);
currentFragment.setRefreshState(false);
} else if (percent == 1) {
//當(dāng)完全折疊時(shí) appbar不可滑動(dòng)使tab吸頂 允許refresh
currentFragment.setRefreshState(true);
myAppBarLayoutBehavoir.setNoScroll(true);
} else {
//滑動(dòng)中 appbar可滑動(dòng) 禁止refresh(建議禁止刷新,否則會(huì)appbar影響滑動(dòng)流暢)
myAppBarLayoutBehavoir.setNoScroll(false);
currentFragment.setRefreshState(false);
}
}
@Override
public void onBackPressed() {
//返回監(jiān)聽(tīng) 當(dāng)appBar處于不可滑動(dòng)(即完全折疊)時(shí)件蚕,先釋放appBar
if (myAppBarLayoutBehavoir.isNoScroll()) {
myAppBarLayoutBehavoir.setNoScroll(false);
appBar.setExpanded(true, true);
} else {
super.onBackPressed();
}
}
@OnClick(R.id.rl_back)
public void onViewClicked() {
//返回監(jiān)聽(tīng) 當(dāng)appBar處于不可滑動(dòng)(即完全折疊)時(shí)孙技,先釋放appBar
if (myAppBarLayoutBehavoir.isNoScroll()) {
myAppBarLayoutBehavoir.setNoScroll(false);
appBar.setExpanded(true, true);
} else {
mSwipeBackHelper.backward();
}
}
自定義behavior
/**
* created by dalang at 2018/10/23
* 自定義behavior 用于解決CoordinatorLayout布局將imgView頂入狀態(tài)欄后 下面的content顯示不全的問(wèn)題
* 代替系統(tǒng)的@string/appbar_scrolling_view_behavior
*/
public class FixScrollingFooterBehavior extends AppBarLayout.ScrollingViewBehavior {
private AppBarLayout appBarLayout;
public FixScrollingFooterBehavior() {
super();
}
public FixScrollingFooterBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
if (appBarLayout == null) {
appBarLayout = (AppBarLayout) dependency;
}
final boolean result = super.onDependentViewChanged(parent, child, dependency);
final int bottomPadding = calculateBottomPadding(appBarLayout);
final boolean paddingChanged = bottomPadding != child.getPaddingBottom();
if (paddingChanged) {
child.setPadding(
child.getPaddingLeft(),
child.getPaddingTop(),
child.getPaddingRight(),
bottomPadding);
child.requestLayout();
}
return paddingChanged || result;
}
private int calculateBottomPadding(AppBarLayout dependency) {
final int totalScrollRange = dependency.getTotalScrollRange();
return totalScrollRange + dependency.getTop();
}
}
/**
* created by dalang at 2018/10/23
* 自定義behavior 用于控制appbar的滑動(dòng)
* 當(dāng)tabLayout吸頂后 使下滑不觸發(fā)appBar的滑動(dòng) 使下拉刷新更順暢
*/
public class NoScrollBehavior extends AppBarLayout.Behavior{
public boolean noScroll;
public NoScrollBehavior() {
}
public NoScrollBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean isNoScroll() {
return noScroll;
}
public void setNoScroll(boolean noScroll) {
this.noScroll = noScroll;
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
if (noScroll) {
return false;
} else {
return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
}
}
}
(一)高斯模糊實(shí)現(xiàn)毛玻璃效果丶共享元素動(dòng)畫(huà) 丶地址選擇器
(二)仿京東頂部伸縮漸變丶自定義viewpager指示器丶viewpager3D回廊丶recyclerview瀑布流
(三)RxJava2常用操作符merge、flatmap排作、zip--結(jié)合MVP架構(gòu)講解
(四)仿支付寶首頁(yè)頂部伸縮滑動(dòng)/中間層下拉刷新
(六)仿QQ首頁(yè)drawer/側(cè)滑刪除/浮動(dòng)imgaeView/角標(biāo)拖拽
(七)仿微信發(fā)布朋友圈拖拽刪除
將持續(xù)更新.. 不喜勿噴牵啦,僅個(gè)人分享,希望能幫助到你
源碼地址:Github傳送門(mén)