例图:
分享需求: 根据我手指往下滑动距离,然后这个标题逐渐的变清晰 当我们ImageView滑动的距离超过这个高度以后,我们的渐变就结束了,变的非常清晰 滑动距离Y轴坐标为0是,我们标题就完成隐藏 Y轴和滑动息息相关,XlistView,实际也是继承式自定义控件,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:orientation="vertical"> <com.example.day_0516_mvp.ObservableScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/iv_detail" android:layout_width="match_parent" android:layout_height="200dp" android:src="@mipmap/abc" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="7dp" android:text="北京颜值担当我沈某人" android:textSize="23dp"/> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="5dp"> <TextView android:id="@+id/tv_decs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="英俊潇洒,风流倜傥" android:textSize="13dp"/> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/tv_bought" android:layout_toStartOf="@+id/tv_bought" android:text="已售"/> <TextView android:id="@+id/tv_bought" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="666"/> RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="13dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:src="@mipmap/mini_icon_sure"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="5dp" android:text="随时退" android:textSize="17dp"/> LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:orientation="horizontal"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:src="@mipmap/mini_icon_sure"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="5dp" android:text="随时退" android:textSize="17dp"/> LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:orientation="horizontal"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:src="@mipmap/mini_icon_sure"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="5dp" android:text="随时退" android:textSize="17dp"/> LinearLayout> LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商家信息" android:textSize="18.0sp"/> <TextView android:id="@+id/tv_title2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="北京燕山电影院" android:textSize="17dp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="5dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="2" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tv_address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="北京房山区燕山岗南路9号"/> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_weight="1" android:text="两件事你需要关注--第一,保持现有的;第二,持续发展。我们要保持这种风格,不靠噱头和花招。同时,要在不破坏现有水准的前提下,关注那些持续发展的、容易扩大规模的产品或趋势。--马克.扎克伯格 在Facebook公司成立10周年,马克.扎克伯格一方面强调了公司要脚踏实地保持现有领域的领先地位,一方面要关注新技术,新方向. 管理公司如此,学习知识亦是相同,一方面要把之前所学温故知新一遍,另一方也要关注Android最近发展流行的新技术,锐意进取; 本课程的目标就是为了在巩固同学们基础的同时进一步提高学生android专业的深度和宽度,使其成为一名合格的Android高级工程师,适应当今Android开发相当火热,但是高级Android开发人员却比较少的市场需求,达成学生高薪就业和缓解企业人才渴求的双重目标 本课程面向的是具备一定Android基础的人群,内容突出实战和知识的体系性,通过本课程的学习,使学生把之前积累的种种知识,温习一遍后,又加入了Android程序即时通讯,XMPP,讯飞语音开发,RxAndroid,retrofit,Fresco,GreedDao等当今Android的主流框架以及APK瘦身加固,多渠道打包,Java8,版本更新,断点续传,百分比适配等Android工程师必备知识点,最后带着学生阅读Android的library层核心类的源码,完成从量变进行质变, 鲤鱼跳龙门这一过程,脱胎换骨,成就大神之路。 准备好了吗!让我开启这场生动有趣又充满挑战的Android进阶旅程吧! 学习知识要善于思考,思考,再思考。 —— 爱因斯坦 本课程在教学过程中,重在引导学生思考,遇到问题怎么构思解决思路,多提问,提高学生解决实际问题的能力;培养学生自学能力,把教学中参考的demo,网址,以及项目的最终效果GIF图等分享给学生,再授课前先让学生研究预习,再进行讲解,正所谓授人以鱼不如授人以渔,使学生离开学校,也能适应日新月异的IT发展;锻炼学生语言沟通能力,使其在日后的面试过程中,能游刃有余的应对面试官的提问 在授课过程中,主要分为三部分:一是:分析使用新技术完成项目的实现思路,在开始敲代码前,先把代码实现的大致步骤,给学生解释清楚,这里主要用的是visio流程图,Raptor图和注释;二是:对新技术原理或者完成项目中某个特定需求用到的算法,进行剖析,最好以图文结合的形式,给学生讲解这些抽象的东西,通过文字详细描述概念,通过画图说明加深学生的理解和记忆;三是:总结回顾,使用思维导图,将一天学习的知识点进行梳理,因为本门课程,知识点较多,且难度较大,教授完课程,学生很难在大脑中长久记忆与灵活运用,此时再带着学生,根据核心技术点做为主干,扩展到实际运用中,以分支的形式体现,把使用这个技术点,容易产生什么问题,怎么解决,最后完成项目后能否进行优化,都复习一遍;最后是:检查学生口述能力,每天所学技术点,都要求学生做到流利的说上一遍,具体到这个技术,第一步怎么做,第二步怎么做,第三步进行时有什么问题,怎么解决,第四步完成效果,第五步效果完成,怎么进行优化,为以后面试的语言表达能力打下坚实的基础。"/> LinearLayout> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:src="@mipmap/ic_call"/> LinearLayout> LinearLayout> LinearLayout> LinearLayout> com.example.day_0516_mvp.ObservableScrollView> <RelativeLayout android:id="@+id/layout_title" android:layout_width="match_parent" android:layout_height="45dp" android:layout_gravity="top" android:padding="5dp"> <TextView android:id="@+id/tv_titlebar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="#ff666666" android:textSize="20dp" android:visibility="gone"/> RelativeLayout> RelativeLayout>
MainActivity主方法:
public class MainActivity extends AppCompatActivity implements ObservableScrollView.ScrollViewListener { /** * 经过我们的观察:发现这个标题,是随着顶部图片高度关系,颜色变浅变深 */ private ImageView mIvDetail; private ObservableScrollView mScrollView; private TextView mTvTitlebar; private RelativeLayout mLayoutTitle; private int mImageHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIvDetail = (ImageView) findViewById(R.id.iv_detail); mScrollView = (ObservableScrollView) findViewById(R.id.scrollView); mTvTitlebar = (TextView) findViewById(R.id.tv_titlebar); mLayoutTitle = (RelativeLayout) findViewById(R.id.layout_title); //获取顶部的图片高度 initListener(); //设置ScrollVIew的滚动监听,一般滑动时,最上面的标题显示,参数是ScrollViewListener,我们让Activity去实现 mScrollView.setScrollViewListener(this); } /** * C 获取顶部的图片高度,设置ScrollView的滚动监听时,要使用这个参数 */ private void initListener() { //获取控件的视图观察者,以便通过视图观察者得到控件的宽高参数 ViewTreeObserver viewTreeObserver = mIvDetail.getViewTreeObserver(); //使用视图观察者设置监听,以便获取所观察控件的高度 viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //卸磨杀驴,回调监听后,第一件事情就是移除该监听,减少内存的消耗,在API16中removeOnGlobalLayoutListener代替removeGlobalOnLayoutListener // mIvDetail.getViewTreeObserver().removeOnGlobalLayoutListener(this); //得到控件的高度 mImageHeight = mIvDetail.getHeight(); } }); } //自定义ObservableScrollView滑动监听器,是ObservableScrollView在把图片滑消失后,显示出标题的效果 @Override public void onScrollChanged(ObservableScrollView scrollView, int l, int t, int oldl, int oldt) { //对T轴进行判断,就两种形态:1.消失没有 2.随着滑动,颜色越来越深 System.out.println("t"+t); if (t <=0){ //设置标题隐藏 mTvTitlebar.setVisibility(View.GONE); //设置标题所在背景为透明 mLayoutTitle.setBackgroundColor(Color.argb(0,0,0,0)); } else if(t>0 && t<mImageHeight){ //让标题显示出来 mTvTitlebar.setVisibility(View.VISIBLE); //获取ScrollView向下滑动,图片消失部分的比例 float scale =(float) t / mImageHeight; //根据这个比例,让标题的颜色慢慢的由浅入深 float alpha = 255 * scale; //设置标题的内容及颜色 mTvTitlebar.setText("1506D颜值担当是谁???"); mTvTitlebar.setTextColor(Color.argb((int)alpha,0,0,0)); //设置标题布局颜色 mLayoutTitle.setBackgroundColor(Color.argb((int)alpha,255,255,255)); } } }
扩展式自定义View:
/** * function:扩展式自定义View,在ScrollView的基础上添加新的功能 * 1.类继承基础控件,实现三个覆写方法 * 2.自定义一个ScrollView滑动监听的接口 * 3.覆写ScrollView自带的一个滑动监听 * 4.提供方法,让外界可以设置ScrollView的监听对象 * 5.使用ObservableScroollview自定义控件 * * 做自定义控件思路: * 1.看效果,判断是哪种类型的自定义控件 * 2.如果是继承式自定义控件,那么我们就要判断这个效果是基于哪种基础控件之上 * */ public class ObservableScrollView extends ScrollView{ public ObservableScrollView(Context context) { this(context,null); } public ObservableScrollView(Context context, AttributeSet attrs) { this(context,attrs,0); } public ObservableScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public interface ScrollViewListener{ //ScrollView自动滑动监听,对其进行覆写 参数 : 1.监听的VIew对象 2,3 新的坐标 4,5 旧的坐标 void onScrollChanged(ObservableScrollView scrollView, int l, int t, int oldl, int oldt); } //自己的监听对象 private ScrollViewListener mScrollViewListener =null; //提供方法,让外界可以设置ScrollView的监听对象 public void setScrollViewListener(ScrollViewListener scrollViewListener){ mScrollViewListener=scrollViewListener; } //提供一个覆写的滑动监听方法,让外界可以设置ScrollView的监听对象 @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if(mScrollViewListener != null){ mScrollViewListener.onScrollChanged(this ,l,t,oldl,oldt); } } }