Android中ScrollView和标题栏渐变

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值