Android自定义ScrollView实现仿拉手团购详情页标题
我们在做商品详情页的时候,一般是有一个商品的标题的,那么商品详情一般都是比较长的,然后手机屏幕又比较小,这样往下拉的时候就看不到商品标题以及退出,分享,收藏按钮了,这样用户体验是不好的。相信大家都用过拉手团购,美团团购这些App,那我们先看下拉手团购的实现效果:
xiaoguo.gif当详情页的图片被往下拉到不见的时候,商品标题显示出来,一般的套路都是这样的,我们使用原生的ScrollView
是实现不了这种效果的,所以我们就需要来自定义一个ScrollView
来继承原生的ScrollView
,实现这种效果。
好,首先,我们需要监听ScrollView
的滑动事件,然后针对它滑动的距离来设置标题的显示情况,但是ScrollView
只给我们提供了这个方法:
protected void onScrollChanged(int x, int y, int oldx, int oldy)
然后这个方法显然是不能被外界调用的,所以我们就需要来写一个接口暴露出这个发方法,供外界调用:
public interface OnScrollViewListener{
void onScrollChanged(MyScrollView myScrollView,int l, int t, int oldl, int oldt);
}
然后新建一个MyScrollView
继承ScrollView
,然后实现它的三个构造方法:
public class MyScrollView extends ScrollView{
private OnScrollViewListener mScrollViewListener=null;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setScrollViewListener(OnScrollViewListener scrollViewListener) {
mScrollViewListener = scrollViewListener;
}
@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);
}
}
public interface OnScrollViewListener{
void onScrollChanged(MyScrollView myScrollView,int l, int t, int oldl, int oldt);
}
}
上面代码重写了onScrollChanged(int l, int t, int oldl, int oldt )
方法,当给它设置监听的时候,就回去接口里面的方法。
好了,自定义就差不多这么多了,然后我们写一个布局,为了方便,我就用图片来占位进行展示,布局代码如下:
<?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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.chogo.myscrollview.MainActivity">
<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="@color/gray"
android:textSize="20dp"
android:visibility="gone"/>
<ImageView
android:id="@+id/image_back"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@mipmap/icon_back_black"/>
<ImageView
android:id="@+id/image_favor"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/image_share"
android:layout_toStartOf="@+id/image_share"
android:src="@drawable/icon_uncollect_black"/>
<ImageView
android:id="@+id/image_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="@mipmap/icon_share_black"/>
</RelativeLayout>
<com.chogo.myscrollview.MyScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/layout_title">
<RelativeLayout
android:id="@+id/layout_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/img1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/image1"
android:layout_marginTop="10dp"
android:src="@mipmap/img2"/>
</RelativeLayout>
</com.chogo.myscrollview.MyScrollView>
</RelativeLayout>
要注意使用滚动布局的时候要试用自定义的这个MyScrollView
而不是原生的那个,然后需要注意的地方是:<h6>ScrollView
只允许有一个子布局,所以这些控件都要使用相对布局或者线性布局包起来,否则会报错闪退。</h6>
然后我们在代码中要实现刚才自定义布局的接口,然后重写onScrollChanged( )
方法。
首先,我们需要得到第一张图片的高度。在第一张图片向上滑动的过程中由滑动的高度y来实现标题的显示,具体的代码含义我都已经加了注释,相信都能看懂,那么说一下如何得到图片的高度,可以参考这个网址,提供了三种方式,我选择第三种方式:http://www.2cto.com/kf/201410/341592.html
MainActivity代码如下:
public class MainActivity extends AppCompatActivity implements MyScrollView.OnScrollViewListener{
private MyScrollView mScrollView;
private RelativeLayout mLayout;
private TextView mTextTitle;
private ImageView mImage;
private int mImageHeight;//图片高度
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScrollView= (MyScrollView) findViewById(R.id.scrollView);
mLayout= (RelativeLayout) findViewById(R.id.layout_title);
mTextTitle= (TextView) findViewById(R.id.tv_titlebar);
mImage= (ImageView) findViewById(R.id.image1);
initListener();
}
/**
* 得到图片的高度
*/
private void initListener() {
ViewTreeObserver viewTreeObserver = mImage.getViewTreeObserver();
//全局的布局改变监听器
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override public void onGlobalLayout() {
//避免重复监听 mImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//得到图片的高度
mImageHeight=mImage.getHeight();
//设置滚动事件监听
mScrollView.setScrollViewListener(MainActivity.this);
}
});
}
@Override
public void onScrollChanged(MyScrollView myScrollView, int x, int y, int oldl, int oldt) {
if(y<=0){
//设置标题不显示
mTextTitle.setVisibility(View.GONE);
//设置透明
mLayout.setBackgroundColor(Color.argb(0,0,0,0));
}else if(y>0 && y<mImageHeight){
//滚动距离大于0但是图片没有完全消失
float scale = (float) y/mImageHeight;//得到滚动的百分比
float alpha = 255*scale;//设置透明度
mTextTitle.setVisibility(View.VISIBLE);
mTextTitle.setText("美女相册");
mTextTitle.setTextColor(Color.argb(255,0,0,0));
mTextTitle.setBackgroundColor(Color.argb((int)alpha,255,255,255)); }else {//第一张图片完全消失
mTextTitle.setVisibility(View.VISIBLE);
mTextTitle.setText("美女相册");
mTextTitle.setTextColor(Color.argb(255,0,0,0));
//设置背景颜色为白色
mLayout.setBackgroundColor(Color.argb(255,255,255,255));
}
}}
然后看一下实现的效果:
t.gif好了,大致就是这样,你可以对它进行改造,实现更好的效果。
如果对你有用的话,可以点个喜欢哦,谢谢(手动比心)
我的CSDN博客地址:http://blog.csdn.net/lr809174917
附源码下载地址:http://download.csdn.net/detail/lr809174917/9714720