前言:
無心打開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 喜歡的點個贊啦