前言:
无心打开GooglePlay app来着,而后发现首页用了揭示效果,连起来用着感受还不错.
不清楚什么是揭示效果(Reveal Effect)的效果能够看我前面一篇文章:Material Design Reveal effect(揭示效果) 你可能见过可是叫不出名字的小效果
没法使用Google的小伙伴能够看我更前面的文章:提升(Android)开发效率的工具与网站java
demo地址: https://github.com/didikee/Demos
android
墙内的小伙伴能够试试 APKPure,一个墙内可使用,资源是GooglePlay的,缺点:下载慢,优势:能下....(无言以对...)
git
<LinearLayout android:id="@+id/activity_google_play_tab_reveal" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.didikee.demos.ui.act.viewActivity.GooglePlayTabRevealActivity" > <FrameLayout android:layout_width="match_parent" android:layout_height="140dp"> <FrameLayout android:id="@+id/below" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/act_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout> <com.didikee.demos.ui.tab.ExtTabLayout android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="bottom" app:tabGravity="fill" app:tabIndicatorHeight="1dp" app:tabMode="fixed" app:tabSelectedTextColor="@color/colorAccent" app:tabTextColor="@color/white"/> </FrameLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/bisque" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </LinearLayout>
重点是FrameLayout和它内部的子View.github
<FrameLayout android:id="@+id/below" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/act_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
子view负责执行动画,FrameLayout负责在子view执行完动画后变成子view执行动画的颜色,这样就能达到一直无限切换的假象
这个模式和GooglePlay保持了一致,你能够打开uiautomatorviewer看看Google的布局.api
这里有个要说明的细节,可能细心的同窗会发现,执行动画的起始位置和你手指点击的位置有关,这里的实现的以手指抬起的坐标为执行动画的起点.
GooglePlay的tab不知道是什么写的,我我的感受不是TabLayout,由于tabLayout默认点击是会有涟漪效果的,可是GooglePlay的tab点击了却没有,我也不想纠结它是用什么作的,我比较偏好TabLayout,因此我就用TabLayout去实现.app
1. 继承 ViewGroup
2. 继承 View
3. 拷贝源码,而后改改...(~ o ~)~zZ
今天,用第三种................dom
拷贝Tablayout源码到本身的工程(不要学我....)ide
TabLayout的组成:工具
TabLayout布局
TabView //每一个item元素view
SlidingTabStrip //每一个item下有一条线,也是一个view
个人目标是 TabView,在tabView Selected 的时候将(即调用 mTab.select();
)坐标也一块儿传出去.因而我添加一个接口.
//--------------add listener public interface LocationListener{ void location(float x,float y,int tabHeight); } private MyExtTabLayout.LocationListener locationListener; public void setLocationListener(MyExtTabLayout.LocationListener locationListener) { this.locationListener = locationListener; } //------------add listener end
在tab选中时传出坐标:
@Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction()==MotionEvent.ACTION_UP){ x=event.getRawX(); y=event.getRawY(); } return super.onTouchEvent(event); } @Override public boolean performClick() { final boolean value = super.performClick(); if (mTab != null) { if (locationListener!=null)locationListener.location(x,y,getHeight()); mTab.select(); return true; } else { return value; } }
有了坐标就能够执行动画了,动画比较简单.和以前的一篇没多大区别,只是此次我改了执行动画的起始坐标,变成了动态的了.
完整代码:
private ViewPager viewPager; private SimpleFragmentPagerAdapter pagerAdapter1; private ExtTabLayout tabLayout; private View viewAnimate; private View below; private float x; private float y; private int height; private int belowColor; private int systemStatusBarHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_google_play_tab_reveal); setBarStyle(); below = findViewById(R.id.below); viewAnimate = findViewById(R.id.act_view); systemStatusBarHeight = DisplayUtil.getSystemStatusBarHeight(this); pagerAdapter1 = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), new String[]{"tab1", "tab2", "tab3", "tab4"}); viewPager = (ViewPager) findViewById(R.id.viewpager); tabLayout = (ExtTabLayout) findViewById(R.id.sliding_tabs); tabLayout.setupWithViewPager(viewPager); tabLayout.setTabMode(ExtTabLayout.MODE_FIXED); viewPager.setAdapter(pagerAdapter1); belowColor = Color.parseColor(ColorUtil.random()); below.setBackgroundColor(belowColor); viewAnimate.setBackgroundColor(belowColor); tabLayout.setLocationListener(new ExtTabLayout.LocationListener() { @Override public void location(float x, float y, int tabHeight) { GooglePlayTabRevealActivity.this.x = x; GooglePlayTabRevealActivity.this.y = y; GooglePlayTabRevealActivity.this.height = tabHeight; } }); tabLayout.addOnTabSelectedListener(new ExtTabLayout.OnTabSelectedListener() { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onTabSelected(ExtTabLayout.Tab tab) { Log.e("test", "x: " + x + " y: " + y + " height: " + height); final int width = viewAnimate.getWidth(); final int height = viewAnimate.getHeight(); final double radio = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); float centerX = x; float centerY = y; Animator circularReveal = ViewAnimationUtils.createCircularReveal(viewAnimate, (int) centerX, (int) centerY, 0, (float) radio); circularReveal.setInterpolator(new AccelerateInterpolator()); circularReveal.setDuration(375); circularReveal.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { belowColor = Color.parseColor(ColorUtil.random()); viewAnimate.setBackgroundColor(belowColor); } @Override public void onAnimationEnd(Animator animation) { below.setBackgroundColor(belowColor); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); circularReveal.start(); } @Override public void onTabUnselected(ExtTabLayout.Tab tab) { } @Override public void onTabReselected(ExtTabLayout.Tab tab) { } }); } public void setBarStyle() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 设置状态栏透明 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } } public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter { private String tabTitles[]; public SimpleFragmentPagerAdapter(FragmentManager fm, String[] strings) { super(fm); tabTitles = strings; } @Override public Fragment getItem(int position) { return PageFragment.newInstance(position + 1); } @Override public int getCount() { return tabTitles.length; } @Override public CharSequence getPageTitle(int position) { return tabTitles[position]; } } @Override protected void onDestroy() { super.onDestroy(); viewAnimate.clearAnimation(); }
最后,demo在个人github上,地址是: https://github.com/didikee/Demos 喜欢的点个赞啦