您的位置:首页 > 移动开发 > Android开发

Android中ScrollView和标题栏渐变

2017-06-20 10:41 363 查看
Android中像拉钩首页、QQ空间、淘宝详情页都有渐变的效果,看起来高逼格的样子,这里打算用ScrollView来实现类似效果,实现起来挺简单,不过也有挺多小问题出现。

[align=left]拉钩首页首页渐变效果:[/align]
[align=left][/align]



[align=left]
[/align]
[align=left]淘宝详情页渐变效果:[/align]
[align=left][/align]



[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left]实现后的效果:[/align]
[align=left][/align]



[align=left][/align]
[align=left][/align]

[align=left]这里实现参考了http://blog.csdn.net/qq_22393017/article/details/54602925中的思路,不过这位兄弟也有一些地方在我动手去做时遇到的问题。首先要实现标题栏和ScrollView有2种方式:[/align]
[align=left]
[/align]
[align=left]1、通过自定义View,让其包含ScrollView子控件;[/align]
[align=left]2、自定义一个ScrollView,重写onScrollChanged方法。[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]这里我也选择了第二种方法,重写onScrollChanged方法,继承ScrollView。[/align]
[align=left]
[/align]
[align=left]
[/align]

[align=left]思路[/align]
[align=left]
[/align]
[align=left]向上移动:标题栏由透明渐变成不透明,头图像由不透明渐变成透明;[/align]
[align=left]向下移动:标题栏由不透明渐变成透明,头图像由透明渐变不透明。[/align]
[align=left]
[/align]
[align=left]我们都知道透明度取值范围是0--255(也就是渐变取值范围),当向上或向下移动时给标题栏和头图像设置透明度值就可以了,这个透明度值根据向上或向下移动的百分比乘以255就ok了。[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]                                         高度(向上或向下移动的高度)[/align]
[align=left]percent(移动百分比) = -------------------------------------------------[/align]
[align=left]                                          总高度(头图标高度-标题栏高度)[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]上面公式一定要理解(就除法嘛),有了上面的思路了,每当移动就给标题栏和头图像设置透明度(percent*255)就ok了。思路就是这么简单,实现起来也是,不够当中遇到点小问题,后面也会说并且决解。[/align]

[align=left]
[/align]
[align=left]
[/align]
[align=left]重写onScrollChanged方法代码如下:[/align]
[align=left]
[/align]
[align=left]
[/align]
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);
}

}


[align=left]
[/align]
[align=left]
[/align]
[align=left]activity_main布局[/align]
[align=left]
[/align]
<?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>


[align=left]
[/align]
[align=left]top_layout布局[/align]
[align=left]
[/align]
<?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>


[align=left][/align]
[align=left]
[/align]
[align=left]MainActivity代码[/align]
[align=left]
[/align]
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);
}
}


[align=left]过程中遇到的问题:[/align]
[align=left]1、快速滑动透明度渐变问题(已经决解,如上);[/align]
[align=left]2、使用getBackground().setAlpha(alpha)方法设置布局背景没效果,不起作用(换成setBackgroundColor就可以决解)。[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]另外这里对icon没有做操作,想要icon也渐变,可以给icon背景设置透明度值就可以了,这是scrollview,就算是listview、gridview、recycleview都一样的道理,只要拿到垂直移动的Y值,都可以实现需要的效果
[/align]

[align=left][/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: