----------------------------------------------------------------------------------------------------------介绍:BottomMenuSlideGradientSwipe是一个仿微信6.0左右滑动渐变切换效果的demo,特分享与大家探讨邮箱:lijunhuayc@sina.com QQ:190951132 GitHub账户:lijunhuayc[目前上面只有一个自己写的自定义AlertDialog对话框,有兴趣的朋友可以看一下,当然肯定没得前段时间出来的那个专门的动画对话框好哈]群里很多网友多次讨论过新版微信6.0的滑动渐变导航[底部菜单渐变切换]的效果怎么做的,今儿个空了在网上搜了一下,几乎没搜到啥有用信息,唯独有一个说的是用高斯函数对图片进行渐变显隐藏[通过透明度],但这并不能达到效果。你是不是也想知道微信开发者是怎么实现的呢?那么请往下看……
针对于此问题,我特地自己来实现此效果。
先看效果图:
内容左右滑动我们可以用很成功的JazzyViewPager来实现,它自带多种动画,其中有一个方法animateFade()就是控制渐变的,但它受到一个属性mFadeEnabled的影响,所以初始化的时候要确保mFadeEnabled属性
的值为true首先介绍一下使用到的开源库:
master-JazzyViewPager主要就是用滑动渐变的viewpager
https://github.com/jfeinstein10/JazzyViewPager
NineOldAndroids-library超经典的一个动画库
https://github.com/JakeWharton/NineOldAndroids
----------------------------------------------------------------------------------------------------------
eclipse新建一个项目BottomMenuSlideGradientSwipe
1因为此实现需要修改一点点JazzyViewpager类的源码,所以这里引用方式是直接将master-JazzyViewPager下的所有资源文件和类文件拷贝到项目对应目录下
注意:jazzyviewpager的资源有好几个attrs.xmlcolor.xml strings.xml 这几个都别忘记了
2将NineOldAndroids-library的jar文件拷贝到libs目录下
3新建一个类MainActivity继承自Activity
先看看布局文件
----------------------------------------------------暂停了一下,唉,开始错了点小错误,现在搞定了。完美运行perfect---------哇咔咔咔咔-----------------------------------
先看布局文件:
activity_main.xml
android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" >
说明:将tabhost用于显示内容的framelayout隐藏掉,然后用一个viewpager来代替 [此处用的是开源的 JazzyViewPager ,它自带很多滑动动画]
main_tabwidget_layout.xml
说明:此布局文件是 tabwidget 的tab项的布局[我们tabwidget的tab用自定义布局实现,后面会详细说明]布局中有一个normalLayout 是tab未选中状态 ,一个selectedLayout是tab的选中状态
注意了:有人会问,为什么不用两张图来实现? 问的好,这就是这篇文章的关键点,详情请继续深入......
我们先修改一下啊JazzyViewpager.java 的源码
打开java文件,给jazzyviewpager类添加如下静态内部接口、属性和方法:
用static的原因我相信你看的懂,避免引用的时候去调用外部类的实例。public static interface SlideCallback { void callBack(int position, float positionOffset); } private SlideCallback slideCallback = null; public void setSlideCallBack(SlideCallback slideCallBack) { this.slideCallback = slideCallBack; }
SlideCallback 接口的作用是在pager滑动的过程中回调改变tab的渐变显示
接着找到 protected void animateFade(View left, View right, float positionOffset) 方法并修改一下
原来的:
protected void animateFade(View left, View right, float positionOffset) { if (left != null) { ViewHelper.setAlpha(left, 1 - positionOffset); } if (right != null) { ViewHelper.setAlpha(right, positionOffset); } }
修改后的:
protected void animateFade(View left, View right, float positionOffset, int position) { if (left != null) { ViewHelper.setAlpha(left, 1 - positionOffset); if (slideCallback != null) { slideCallback.callBack(position, 1 - positionOffset); } } if (right != null) { ViewHelper.setAlpha(right, positionOffset); if (slideCallback != null) { slideCallback.callBack(position + 1, positionOffset); } } }
animateFade方法的作用就是在页面切换的过程中使用 NineOldAndroids 库设置透明渐变,所以我们就在它渐变的地方调用我们的回调函数来改变界面tab的渐变
animateFade调用的地方只有一个 在onPageScrolled 方法中
将调用方式
animateFade(mLeft, mRight, effectOffset);
改为:animateFade(mLeft, mRight, effectOffset, position); 参数position即为onPageScrolled方法的position参数
JazzyViewpager修改完毕
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面开始界面activity的编写:
这里介绍一个工具库:x-utils-master 一个实现了android中 Ioc 开源库,里面主要有四个类 详细转--github
详情请点击我跳转到另一篇博客【xUtils的使用】
备用连接
----------------------------------------------
MainActivity:如下
完整代码如下:
package com.ycg.bottommenuslidegradientswipe; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.ActionBar; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.TabHost; import android.widget.TabHost.OnTabChangeListener; import android.widget.TextView; import com.jfeinstein.jazzyviewpager.JazzyViewPager; import com.jfeinstein.jazzyviewpager.JazzyViewPager.SlideCallback; import com.jfeinstein.jazzyviewpager.JazzyViewPager.TransitionEffect; import com.jfeinstein.jazzyviewpager.OutlineContainer; import com.lidroid.xutils.ViewUtils; import com.lidroid.xutils.view.annotation.ViewInject; import com.nineoldandroids.view.ViewHelper; public class MainActivity extends Activity { @ViewInject(R.id.jazzyPager) private JazzyViewPager jazzyPager; List
成员变量:
@ViewInject(R.id.jazzyPager)
private JazzyViewPager jazzyPager; 这里采用了注解来初始化view,[xUtils的功能,以后再也不用写findviewbyid了]List
> tabViews 是给pagerAdapter提供资源的 oncreate方法:
ViewUtils.inject(this);//必须在setContentView(R.layout.activity_main);之后就调用,否则可能会出现上面注解初始化失败,导致nullpointexcepter异常
接下来的
添加tab的时候,tabHost = (TabHost) findViewById(android.R.id.tabhost); tabHost.setup(); tabHost.addTab(tabHost.newTabSpec("0").setIndicator(createTab("主页", 0)).setContent(android.R.id.tabcontent)); tabHost.addTab(tabHost.newTabSpec("1").setIndicator(createTab("统计", 1)).setContent(android.R.id.tabcontent)); tabHost.addTab(tabHost.newTabSpec("2").setIndicator(createTab("消息", 2)).setContent(android.R.id.tabcontent)); tabHost.addTab(tabHost.newTabSpec("3").setIndicator(createTab("设置", 3)).setContent(android.R.id.tabcontent)); // 点击tabHost 来切换不同的消息 tabHost.setOnTabChangedListener(new OnTabChangeListener() { @Override public void onTabChanged(String tabId) { int index = Integer.parseInt(tabId); setTabSelectedState(index, 4); tabHost.getTabContentView().setVisibility(View.GONE);// 隐藏content } }); tabHost.setCurrentTab(0); initJazzyPager(TransitionEffect.Standard);
![]()
setContent有三个,我们用第一个【第三个没用过不知道,第二个是以前用activitygroup的时候用的现在不需要】,参数设置为前面xml中隐藏掉的fragmentlayout,它的id是用的系统提供的id,注意引用方式androud.R.id.tabcontent
这里有个方法setTabSelectedState(int,int) 的作用是设置tab的显示状态为选中状态[我们约定normalLayout未选中,selectedLayout选中][两者的显示/隐藏不通过setVisiblty来设置,而是通过setAlpha来控制吗,以便达到我们要的渐变效果]
注意:代码切换pager的时候如果传入了第二个参数的话,true代表有切换动画,false代表取消切换动画/** * 设置tab状态选中 * @param index */ private void setTabSelectedState(int index, int tabCount) { for (int i = 0; i < tabCount; i++) { if (i == index) { tabViews.get(i).get("normal").setAlpha(0f); tabViews.get(i).get("selected").setAlpha(1f); } else { tabViews.get(i).get("normal").setAlpha(1f); tabViews.get(i).get("selected").setAlpha(0f); } } jazzyPager.setCurrentItem(index, false);// false表示 代码切换 pager 的时候不带scroll动画 }
接下来在初始化tabhoust后调用一下设置currentTab为0
然后是初始化JazzyPager 默认是用标准动画,就是普通的左右滑动
重点在:
jazzyPager.setPageMargin(30); jazzyPager.setFadeEnabled(true); jazzyPager.setSlideCallBack(new SlideCallback() { @Override public void callBack(int position, float positionOffset) { Map
map = tabViews.get(position); ViewHelper.setAlpha(map.get("selected"), positionOffset); ViewHelper.setAlpha(map.get("normal"), 1 - positionOffset); } }); jazzyPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { tabHost.setCurrentTab(position); } @Override public void onPageScrolled(int paramInt1, float paramFloat, int paramInt2) { } @Override public void onPageScrollStateChanged(int paramInt) { } }); 重点来了:
还记得上面的修改的animateFade方法么
回调函数中通过jazzyviewpager的 animateFade方法内调用回调函数传递过来的position去获取tabView,然后设置对应的normalLayout和selectedLayout的alpha值即可
pagerAdapter内给每个页面构造了一个文本框,没啥说的,看看代码就懂了,这里就不说了
代码:
当页面滑动的过程中回到桌面后再进入APP,底部的tab会出现文章开头的第二幅图的样纸,有一个tab还是半隐的状态,onResume中加上上面的一行可以解决@Override protected void onResume() { super.onResume(); setTabSelectedState(tabHost.getCurrentTab(), 4); }
onCreateOptionsMenu 和onOptionsItemSelected 是切换JazzyViewPager页面的滑动动画的菜单。没啥好说的,看看就懂
-----------------------------------------------------------------------------------------------------------------------------------------------------------
就这么点代码实现了微信6.0的滑动渐变效果有木有啊?~~喀喀喀 ^_^ ~~~
源代码打包[点我下载]
我的资源列表
转载请注明出处:http://blog.csdn.net/lijunhuayc/article/details/40543237