仿QQ空间标题栏显示隐藏

xiaoxiao2021-02-28  160

在QQ空间中我们经常会看到一种效果:标题栏或者状态栏在下拉或者上拉时的“渐变显示隐藏功能” ,今天我们就看看他是怎么实现的。

先看下效果图:

一:那么我们就先来说下“带Banner样式”的:

通过效果图了解到: 1.整体是个上下滑动的ScrollView 2.当ScrollView上滑时,标题栏随着向上滑动轮播图开始隐藏掉时,标题栏开始显示,随着轮播图逐渐隐藏标题栏逐渐显示,颜色逐渐变深,直到轮播图全部隐藏标题栏的颜色变为最深。 3.当ScrollView下拉时,标题栏开始逐渐隐藏,并且颜色逐渐变暗,直至轮播图完全显标题栏最后消失 所以:首先要获取轮播图的高度。      其次要自定义一个ScrollView ,当ScrollView上下滑动时,结合顶部轮播图的高度的变化 设置滚动监听对状态栏的显示隐藏做出操作。 ok,分析完了,直接上代码。 先自定义个ScrollView,看下整体的代码:GradationScrollView ,再解释

public class GradationScrollView extends ScrollView { public GradationScrollView(Context context) { super(context); } public GradationScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public GradationScrollView(Context context, AttributeSet attrs) { super(context, attrs); } private ScrollViewListener scrollViewListener = null; //滚动监听 public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } public interface ScrollViewListener { void onScrollChanged(GradationScrollView scrollView, int x, int y, int oldx, int oldy); } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } }

1.ScrollView中有一个方法:ScrollView改变时的方法:

onScrollChanged(int x, int y, int oldx, int oldy){}参数:X oldx 分别代表水平位移 ,X当前的横坐标,oldx 改变前的横坐标             Y oldY  代表当前左上角距离Scrollview顶点的距离 , Y当前的纵坐标,oldy 改变前的纵坐标

@Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } }

2.我们看到ScrollView中定义了一个滚动的监听:当ScrollView 发生改变时调用

private ScrollViewListener scrollViewListener = null; //滚动监听 public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } public interface ScrollViewListener { void onScrollChanged(GradationScrollView scrollView, int x, int y, int oldx, int oldy); }我们所用到的就是当ScrollView 改变时,y  与oldy  变化时对标题栏的状态做出改变。

之后我们再看下调用的类;BannerActivity,及xml文件

xml文件:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.hankkin.gradationtitlebar.BannerActivity"> <com.hankkin.gradationscroll.GradationScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="200dp" /> <com.hankkin.gradationscroll.MaterialIndicator android:id="@+id/indicator" style="@style/MaterialIndicator.Demo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:paddingBottom="16dp" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" /> <com.hankkin.gradationscroll.NoScrollListview android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.hankkin.gradationscroll.NoScrollListview> </LinearLayout> </com.hankkin.gradationscroll.GradationScrollView> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/transparent" android:gravity="center|bottom" android:paddingBottom="10dp" android:text="我是标题" android:textColor="@color/transparent" android:textSize="18sp" /> </RelativeLayout> 文件中我们主要关注的是有标注的部分

再看下Banner类:

public class BannerActivity extends AppCompatActivity implements GradationScrollView.ScrollViewListener { private GradationScrollView scrollView; private ListView listView; private TextView textView; private int imageHeight; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_NO_TITLE); StatusBarUtil.setImgTransparent(this);// setContentView(R.layout.activity_banner); scrollView = (GradationScrollView) findViewById(R.id.scrollview); listView = (ListView) findViewById(R.id.listview); textView = (TextView) findViewById(R.id.textview); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setFocusable(true); viewPager.setFocusableInTouchMode(true); viewPager.requestFocus(); MaterialIndicator indicator = (MaterialIndicator) findViewById(R.id.indicator); ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new MyPagerAdapter()); viewPager.addOnPageChangeListener(indicator); indicator.setAdapter(viewPager.getAdapter()); initListeners(); initData(); } /** * viewpager适配器 */ private class MyPagerAdapter extends PagerAdapter { public int[] drawables = {R.drawable.banner1,R.drawable.banner2,R.drawable.banner3,R.drawable.banner4}; @Override public int getCount() { return 4; } @Override public boolean isViewFromObject(View view, Object object) { return object == view; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView view = new ImageView(container.getContext()); view.setImageResource(drawables[position]); view.setScaleType(ImageView.ScaleType.FIT_XY); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(((View) object)); } } /** * 获取顶部图片高度后,设置滚动监听 */ private void initListeners() { ViewTreeObserver vto = viewPager.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { viewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this); imageHeight = viewPager.getHeight(); //设置滚动监听 scrollView.setScrollViewListener(BannerActivity.this); } }); } private void initData() { ArrayAdapter<String> adapter = new ArrayAdapter<String>(BannerActivity.this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.data)); listView.setAdapter(adapter); } /** * 滑动监听 * @param scrollView * @param x X oldx 分别代表水平位移 * @param y Y oldY 代表当前左上角距离Scrollview顶点的距离 * @param oldx * @param oldy */ @Override public void onScrollChanged(GradationScrollView scrollView, int x, int y, int oldx, int oldy) { // TODO Auto-generated method stub if (y <= 0) { //设置标题的背景颜色 0 透明度 (144,151,166)颜色:透明色 textView.setBackgroundColor(Color.argb((int) 0, 144,151,166)); } else if (y > 0 && y <= imageHeight) { //滑动距离小于banner图的高度时,设置背景和字体颜色颜色透明度渐变 float scale = (float) y / imageHeight; float alpha = (255 * scale); textView.setTextColor(Color.argb((int) alpha, 255,255,255)); //(255,255,255)颜色:白色 // textView.setBackgroundColor(Color.argb((int) alpha, 144,151,166)); textView.setBackgroundColor(Color.argb((int) alpha, 255,132,0)); } else { //滑动到banner下面设置普通颜色 // textView.setBackgroundColor(Color.argb((int) 255, 144,151,166)); textView.setBackgroundColor(Color.argb((int) 255, 255,132,0)); } } } 类中我们所关注的就就两个方法:

1.获取高度,并设置监听

/** * 获取顶部图片高度后,设置滚动监听 */ private void initListeners() { //getViewTreeObserver() 是用来帮助我们监听某些View的某些变化的。 //获得getViewTreeObserverd对象 ViewTreeObserver vto = viewPager.getViewTreeObserver(); // addOnGlobalLayoutListener用于监听布局之类的变化,比如某个空间消失了 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { imageHeight = viewPager.getHeight(); viewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this); //设置滚动监听 scrollView.setScrollViewListener(BannerActivity.this); } }); } 关于方法中getViewTreeObserver() 方法,及addOnGlobalLayoutListener监听请参考: http://blog.csdn.net/linghu_java/article/details/46544811

2.重写滑动监听的方法

/** * 滑动监听 * @param scrollView * @param x X oldx 分别代表水平位移 * @param y Y oldY 代表当前左上角距离Scrollview顶点的距离 * @param oldx * @param oldy */ @Override public void onScrollChanged(GradationScrollView scrollView, int x, int y, int oldx, int oldy) { // TODO Auto-generated method stub if (y <= 0) { //设置标题的背景颜色 0 透明度 (144,151,166)颜色:透明色 textView.setBackgroundColor(Color.argb((int) 0, 144,151,166)); } else if (y > 0 && y <= imageHeight) { //滑动距离小于banner图的高度时,设置背景和字体颜色颜色透明度渐变 float scale = (float) y / imageHeight; float alpha = (255 * scale); textView.setTextColor(Color.argb((int) alpha, 255,255,255)); //(255,255,255)颜色:白色 // textView.setBackgroundColor(Color.argb((int) alpha, 144,151,166)); textView.setBackgroundColor(Color.argb((int) alpha, 255,132,0)); } else { //滑动到banner下面设置普通颜色 // textView.setBackgroundColor(Color.argb((int) 255, 144,151,166)); textView.setBackgroundColor(Color.argb((int) 255, 255,132,0)); } } 以上方法通过 y 与 imageHeight  的关系 做出操作,方法中已作出注释。

以上就是我们实现效果图的关键步骤了,源码我还没上传至github,敬请期待。。。

转载请注明原文地址: https://www.6miu.com/read-35264.html

最新回复(0)