自定义控件--让背景颜色随ViewPager的滑动而渐变

转载请注明出处,谢谢~

今天要说一个简单但不好想的效果实现。代码绝对简单,实现绝对easy,就是你可能想不到而已。

不多说,上效果图。第一个效果是仿最美应用的滑动颜色变化,第二个是我项目中要用的效果,实现后我就贴出来了,开源嘛。

下面分别说说这两个实现的原理和想法。

首先我们看纯色的第一张gif,纯色的渐变还是容易一些的。

1.实现一个ViewPager,因为我们要实现的是,随着手指的移动,viewpager的背景色改变,所以暂时的想法是,不需要自定义viewpager。

2.给背景设置一个纯色的color。

3.viewpager的滑动,如何获取,如何处理

4.如何让颜色渐变,怎么获取渐变值

下面我们一个一个的解决。

1.使用viewpager貌似是很简单的,这里不复述了,代码我贴上:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
    android:id="@+id/ll"
    android:orientation="vertical" >

    <TextView
        android:padding="10dp"
        android:layout_width="match_parent"
        android:gravity="center_horizontal"
        android:layout_height="wrap_content"
        android:textColor="#ff000000"
        android:text="这是title" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>
</LinearLayout>
@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		llLayout = (LinearLayout) findViewById(R.id.ll);
		viewpager = (ViewPager) findViewById(R.id.viewpager);
		fragment = new ImageFragment();
		fragment2 = new ImageFragment();
		fragment3 = new ImageFragment();
		fragment4 = new ImageFragment();
		views.add(fragment2);
		views.add(fragment3);
		views.add(fragment4);
		views.add(fragment);
		viewpager.setAdapter(new MyAdapter(getSupportFragmentManager()));
		viewpager.setCurrentItem(0);
		viewpager.setOnPageChangeListener(new PageChangeLisener());
	}
private class MyAdapter extends FragmentPagerAdapter{

		private List<Fragment> list_views;

		public MyAdapter(FragmentManager fm) {
			super(fm);
			list_views = views;
		}

		@Override
		public Fragment getItem(int arg0) {
			return list_views.get(arg0);
		}

		@Override
		public int getCount() {
			return list_views.size();
		}

	}

以上是关于viewpager的一些代码,没有贴全,像是ImageFragment就特别简单,布局里就是一张图片而已。

下面第二个问题,背景色我们很容易搞定,setBackgroundColor就可以。

然后看第三个问题,并不是所有的滑动处理都要在onTouch里进行,像viewpager,我们完全可以看它的listener

class PageChangeLisener implements OnPageChangeListener {

		@Override
		public void onPageScrollStateChanged(int arg0) {
		}

		@SuppressLint("NewApi")
		@Override
		public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
			ArgbEvaluator evaluator = new ArgbEvaluator();
			if (position % 2 == 0) {
				llLayout.setBackgroundColor(0XFF8080FF);
				int evaluate = (Integer) evaluator.evaluate(positionOffset, 0XFF8080FF,0XFFFF8080);
				llLayout.setBackgroundColor(evaluate);
			}else {
				llLayout.setBackgroundColor(0XFFFF8080);
				int evaluate = (Integer) evaluator.evaluate(positionOffset, 0XFFFF8080,0XFF8080FF);
				llLayout.setBackgroundColor(evaluate);
			}
		}

		@Override
		public void onPageSelected(int arg0) {
		}
	}

这是整个颜色控制的核心,先说第三个问题,这里用onPageChangeListener来处理了viewpager的滑动,这里虽然拿不到坐标,但是可以拿到一些对我们来说,很有用的东西,看onPageScrolled方法的第二个参数,这里做实验发现,它向右滑动的时候,取值是[0,1),而向左滑动的时候,取值的(1,0],这完全就是为了让开发者做缩放平移等动画的小助手啊!

然后,注意了,我们考虑第四个问题,我不知道大家是否熟悉属性动画,我首先是在属性动画里写了一个对backgroundColor属性设置改变的一个动画:

@SuppressLint("NewApi")
	private void setBackRepeat(View view,String property,int from , int to){
		ValueAnimator animator = ObjectAnimator.ofInt(view,property,from,to);
		animator.setDuration(2000);
		animator.setRepeatMode(ValueAnimator.REVERSE);
		animator.setRepeatCount(ValueAnimator.INFINITE);
		animator.setEvaluator(new ArgbEvaluator());
		animator.start();

		animator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// TODO Auto-generated method stub
				System.out.println("value : "+Integer.toHexString((Integer)animation.getAnimatedValue()));
			}
		});
	}

然后我打印了动画执行时的颜色的变化,然后我发现他居然会渐变成为你想要的颜色,而不是刷的一下就变了,这下,开心了。

把这个属性动画里的颜色估值器拿出来,ArgbEvaluator,就是它!它的实现特别简单,大家可以点进去看看源码,然后用这个估值器我们来做估值。

首先说说这几个参数,

evaluator.evaluate(positionOffset, 0XFF8080FF,0XFFFF8080);

估值器new出来之后,进行估值,第一个参数是0-1的一个可变参数,0表示开始变化,1表示变化结束,第二个参数是开始的颜色值,第三个参数是结束的颜色值。而这个方法就会一直返回一个在0-1之间过度的颜色值,直到颜色变化完为止。

这样我们就完全可以试想上述效果了!

接着,我们来实现第二个效果!就是在背景色渐变的基础上,再加上滑动渐变!

我们仔细看第二个效果,发现viewpager后面的背景色,原本就是从左上角到右下角渐变的,然后滑动过程中,颜色继续随手指渐变,滑动结束后,左上角和右下角的颜色互换了位置,中间还是渐变色。是不是比第一个效果瞬间又提升了bigger!我们再来实现一下它!

考虑问题:

1.背景色渐变的实现方式?

2.viewpager是否需要自定义?

3.滑动事件的获取?

4.渐变的处理?

我们逐个解决。

第一个,背景渐变,大家熟知的shape,对,一开始我也想到了它,而且想到了属性动画,对backgroundResource的设置,但是很遗憾,背景色没有渐变效果,所以放弃。然后背景色的实现,我简单的自定义了一个view,让这个view做viewpager的背景,来随手指渐变。

第二个,viewpager没有自定义,因为viewpager上没有特别复杂的效果,没有特别绚丽的切换(你完全可以自己加上,github有开源的),所以我没有自定义。

第三个,滑动事件的处理仍然延用了上一个效果的listenr,完全无法舍弃第二个参数offset这个从0-1的小baby啊!

第四个,单纯的颜色估值器无法满足我们的需求,但结合上我们自定义的view就能实现双渐变效果了!

public class MyLinearLayout extends View {

	private LinearGradient gradinet;
	private Paint paint;
	private int width;
	private int height;
	private int start = 0XFFFF8080;
	private int end = 0XFF8080FF;

	public MyLinearLayout(Context context) {
		super(context);
		getDisplay(context);
	}

	public MyLinearLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		getDisplay(context);
	}

	private void getDisplay(Context context) {
		WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
		width = wm.getDefaultDisplay().getWidth();
		height = wm.getDefaultDisplay().getHeight();
	}

	public void setGradient(int start,int end){
		this.start = start;
		this.end = end;
		gradinet = new LinearGradient(0, 0, width, height, start, end, Shader.TileMode.MIRROR);
		invalidate();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		System.out.println("!!!!!!!!!!!!!!!!");
		if (paint == null) {
			paint = new Paint();
		}
		if (gradinet == null) {
			gradinet = new LinearGradient(0, 0, width, height, start, end, Shader.TileMode.MIRROR);
		}
		paint.setShader(gradinet);
		canvas.drawRect(0, 0, width	, height, paint);
	}

}

核心!!就是这么个简单但重要的自定义控件,里面用LinearGradient实现了渐变,在加上估值器,一个双渐变效果就这么出来了!

开源!!这个项目的代码我提交到github上,我衷心并且恳切的希望能有人把viewpager的切换效果也加入到这个项目中,向我发出合并申请。谢谢。

还得提一句,一直想写一系列关于Android动画的博客,但是一直抽不出太多时间(短时间无法写完),demo我已经写完了,所以关于这部分以后博客肯定会有,莫急莫急。

控件github下载地址

时间: 2024-11-05 14:37:33

自定义控件--让背景颜色随ViewPager的滑动而渐变的相关文章

ViewPager 循环滑动+伸缩渐变过度动画实现多图片浏览

     效果图如上. 首先先实现循环: public class MyAdapter extends PagerAdapter { /** * 装ImageView数组 */ private ImageView[] mImageViews; /** * 图片资源id */ private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>(); private int[] imgIdAr

android ViewPager左右滑动实现导航栏的背景随页面滑动而滑动

实现viewPager和导航栏进行结合的效果图:废话不说直接上图看效果:      随着左右的滑动背景的黄色也随着滑动,代码如下: 布局  weibo_2.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width=

ViewDragHelper实现QQ5.0侧滑并处理与ViewPager的滑动冲突

QQ5.0的侧滑效果有多种实现方式, 如http://blog.csdn.net/lmj623565791/article/details/39257409   就是利用HorizontalScrollView实现的,简单实用; 如http://blog.csdn.net/manoel/article/details/39013095/   通过改造SlidingMenu实现,没有改变原有SlidingMenu功能,屏幕边缘侧滑也可以.... 相对来说ViewDragHelper实现方式最为复杂

Android自定义控件---导航栏SlideTab(Fragment+ViewPager)

一.前言 好久没有更新过博客了,趁今天有空分享一个导航栏的自定义控件.有关此控件的demo相信在网上已经烂大街了,一搜一大把. 我现在只着重分享一些我认为比较难理解的知识点.整个控件的难点大概有三个 1.游标的绘制. 2.ViewPager监听器的理解. 3.游标的移动. 本文将注重这三个方面重点分析. 先上Demo的最终效果 二.Demo结构图和知识点 样例Module,有四个java文件和两个xml文件 总结一下此控件的主要知识点 1.ViewGroup绘制流程. 2.ViewPager的用

(转)ViewDragHelper实现QQ5.0侧滑并处理与ViewPager的滑动冲突

最近在做项目,涉及到类似QQ的页面的滑动.但是却遇到了侧滑和ViewPager冲突的问题,头疼了很长时间,最后在网上发现了这篇博客,转载过来供自己学习参考(写这篇博客的原创作者,因为我发现这篇博客的地方也是别人转载的,所以具体是有哪位大牛完成的我也不得而知.转载文章不能标出原创作者和出处,请见谅) QQ5.0的侧滑效果有多种实现方式, 如http://blog.csdn.net/lmj623565791/article/details/39257409 就是利用HorizontalScrollV

TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 使用TabLayout搭配ViewPager实现可滑动的顶部选项卡效果. 效果图 代码分析 1.演示常规的设置. 2.考虑到Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 所以暂时将webview.loadUrl()放到onCreateView中执行. 使用步骤 一.项目组织结构图 注意事项: 1.  导入类文件后需要change包名以及重新i

android:修改PagerTabStrip中的背景颜色,标题字体的样式、颜色和图标以及指示条的颜色

1.修改PagerTabStrip中的背景颜色 我们在布局中直接设置background属性即可: <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="fill_parent" android:layout_height="fill_parent" > <android.support.v4.view.PagerTabS

VC 对话框背景颜色、控件颜色(三种方法)

系统环境:Windows 7软件环境:Visual C++ 2008 SP1本次目的:为对话框设置背景颜色.控件颜色 既然MFC对话框不好开发,那么现在我们来开始美化我们的对话框.为对话框设置背景颜色.控件颜色等等. 对话框背景颜色: 网上流传有四种方法(可能还不止),在VC++2008SP1测试后,发现只有三种可以使用了,其中第一种被废弃了.以下是四种方法: 方法一 (失效):调用CWinApp类的成员函数SetDialogBkColor来实现.       其中函数的第一个参数指定了背景颜色

Android ViewPager+Fragment滑动选项卡,tab点击选项卡

有一段时间一直再研究这个,自Android 3.0以后,很少开发者再用以前的TabWidget控件了.那种效果不是很好,也不能滑动.后来陆续出现了各种各样滑动选项卡,每种的出现都各有优势吧.但我还是推荐ViewPager+Fragment滑动选项卡,tab点击选项卡.因为横屏或者竖屏效果都还不错,针对这种效果,还有一种开源框架的出现.接下来会有所介绍. 转载请注明出处:http://blog.csdn.net/qq_16064871 本文demo下载:请点击 一.ViewPagerActivit