Android中ScrollView和标题栏渐变

来源:互联网 发布:中国进口贸易数据分析 编辑:程序博客网 时间:2024/05/22 05:21
Android中像拉钩首页、QQ空间、淘宝详情页都有渐变的效果,看起来高逼格的样子,这里打算用ScrollView来实现类似效果,实现起来挺简单,不过也有挺多小问题出现。

拉钩首页首页渐变效果:


淘宝详情页渐变效果:




实现后的效果:



这里实现参考了http://blog.csdn.net/qq_22393017/article/details/54602925中的思路,不过这位兄弟也有一些地方在我动手去做时遇到的问题。首先要实现标题栏和ScrollView有2种方式:

1、通过自定义View,让其包含ScrollView子控件;
2、自定义一个ScrollView,重写onScrollChanged方法。


这里我也选择了第二种方法,重写onScrollChanged方法,继承ScrollView。


思路

向上移动:标题栏由透明渐变成不透明,头图像由不透明渐变成透明;
向下移动:标题栏由不透明渐变成透明,头图像由透明渐变不透明。

我们都知道透明度取值范围是0--255(也就是渐变取值范围),当向上或向下移动时给标题栏和头图像设置透明度值就可以了,这个透明度值根据向上或向下移动的百分比乘以255就ok了。


                                         高度(向上或向下移动的高度)
percent(移动百分比) = -------------------------------------------------
                                          总高度(头图标高度-标题栏高度)


上面公式一定要理解(就除法嘛),有了上面的思路了,每当移动就给标题栏和头图像设置透明度(percent*255)就ok了。思路就是这么简单,实现起来也是,不够当中遇到点小问题,后面也会说并且决解。


重写onScrollChanged方法代码如下:


package com.bartest.view;import android.content.Context;import android.util.AttributeSet;import android.widget.ScrollView;/** * Created by tujingwu on 2017/6/16 * . */public class MyScrollView extends ScrollView {    //对外暴露的一个ScrollView监听的接口    public MyScrollViewListener myScrollViewListener = 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 setOnMyScrollListener(MyScrollViewListener myScrollViewListener) {        this.myScrollViewListener = myScrollViewListener;    }    //重写onScrollChanged的ScrollView监听    @Override    protected void onScrollChanged(int x, int y, int oldx, int oldy) {        super.onScrollChanged(x, y, oldx, oldy);        /**         * x:    当前横向滑动距离         * y:    当前纵向滑动距离         *oldx:  之前横向滑动距离         *oldy:  之前纵向滑动距离         */        if (myScrollViewListener != null) {            //这里判断向上或向下滑动是因为后面要使用到            if (oldy < y)//向上滑动                myScrollViewListener.onMyScrollView(y, oldy, true);            else if (oldy > y)//向下滑动                myScrollViewListener.onMyScrollView(y, oldy, false);        }    }    public interface MyScrollViewListener {        void onMyScrollView(int y, int oldy, boolean isUp);    }}



activity_main布局

<?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"    tools:context="com.bartest.MainActivity">    <com.bartest.view.MyScrollView        android:id="@+id/myScrollView"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical">            <ImageView                android:id="@+id/head_img"                android:layout_width="match_parent"                android:layout_height="@dimen/headHight"                android:layout_gravity="center"                android:scaleType="centerCrop"                android:src="@drawable/head" />            <TextView                android:layout_width="match_parent"                android:layout_height="match_parent"                android:gravity="center"                android:lineSpacingExtra="10dp"                android:text="@string/text"                android:textSize="20sp" />        </LinearLayout>    </com.bartest.view.MyScrollView>    <include layout="@layout/top_layout" /></RelativeLayout>


top_layout布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/titleLayout"    android:layout_width="match_parent"    android:layout_height="@dimen/titleHight"    android:gravity="center"    android:padding="10dp">    <ImageView        android:id="@+id/top_img2"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_marginRight="10dp"        android:layout_toLeftOf="@+id/top_img3"        android:src="@mipmap/img2"/>    <ImageView        android:id="@+id/top_img3"        android:layout_width="30dp"        android:layout_height="30dp"        android:layout_alignParentRight="true"        android:layout_centerInParent="true"        android:layout_marginRight="10dp"        android:src="@mipmap/img3" />    <ImageView        android:id="@+id/top_img1"        android:layout_width="30dp"        android:layout_height="30dp"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_alignTop="@+id/top_img2"        android:src="@mipmap/img1"/></RelativeLayout>



MainActivity代码

package com.bartest;import android.graphics.Color;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.ImageView;import android.widget.RelativeLayout;import com.bartest.utils.DensityUtil;import com.bartest.view.MyScrollView;public class MainActivity extends AppCompatActivity {    private ImageView mHeadImg;    private MyScrollView mMyScrollView;    private RelativeLayout titleLayout;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initScrollView();    }    private void initView() {        mHeadImg = (ImageView) findViewById(R.id.head_img);        mMyScrollView = (MyScrollView) findViewById(R.id.myScrollView);        titleLayout = (RelativeLayout) this.findViewById(R.id.titleLayout);    }    private void initScrollView() {        //获取标题和头部的高度        final float title_height = getResources().getDimension(R.dimen.titleHight);        final float head_height = getResources().getDimension(R.dimen.headHight);        //总高度(把dp转换成px,计算时单位肯定要一样)        final float totalHight = DensityUtil.px2dip(MainActivity.this, head_height - title_height);        //设置ScrollView监听        mMyScrollView.setOnMyScrollListener(new MyScrollView.MyScrollViewListener() {            @Override            public void onMyScrollView(int y, int oldy, boolean isUp) {                int yIf = DensityUtil.px2dip(MainActivity.this, Math.abs(y));                if (yIf <= totalHight) {                    //根据滑动设置渐变透明度                    setBgAlphaChange(yIf, totalHight);                } else if (yIf > totalHight && isUp) {//防止快速滑动导致透明度问题  向上                    //快速滑动就直接设置不透明                    setBgAlphaChange((int) totalHight, totalHight);                }            }        });    }    //设置背景透明度    private void setBgAlphaChange(int oldy, float totalHight) {        /**         * 渐变取值范围0--255         *                               高度(向上或向下移动的高度)         * 渐变百分比: percent =--------------------------------------------         *                           总高度(也就是head图片高度-标题栏高度)         */        float percent = (float) Math.abs(oldy) / Math.abs(totalHight);        int alpha = (int) (percent * 255);        titleLayout.setBackgroundColor(Color.argb(alpha, 255, 255, 255));        int imgAlpha = 255 - alpha;        mHeadImg.setAlpha(imgAlpha);    }}

过程中遇到的问题:
1、快速滑动透明度渐变问题(已经决解,如上);
2、使用getBackground().setAlpha(alpha)方法设置布局背景没效果,不起作用(换成setBackgroundColor就可以决解)。


另外这里对icon没有做操作,想要icon也渐变,可以给icon背景设置透明度值就可以了,这是scrollview,就算是listview、gridview、recycleview都一样的道理,只要拿到垂直移动的Y值,都可以实现需要的效果

阅读全文
0 0
原创粉丝点击