Android,android官網
,代表著國內軟體的頂級app,當然它的一些好的效果,
我們可以模仿學習。下面是模仿底部欄隨著頁面的滑動
而產生文字和圖片的顏色以及透明度變化的效果。
如下:
首先我們來分析問題,滑動的時候什麼改變了?我們得出兩點:
1.圖片顏色改變了
這種改變很奇妙,是通過透明度來達到這種效果的,裝的朋友可以認真玩玩。
灰色圖片的透明度增加,橙色圖片透明度就會減少。
2.文字顏色改變了
字型的改變的時候透明度沒有變,但是顏色值在灰色和橙色相互轉換,這對於沒有
詳細學過顏色概念的朋友,可能有點難實現,不過懂得原理後,一切都很簡單。
先從布局開始吧。
(1)底部標籤Item如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center"> <LinearLayout android:id="@+id/m_tablayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> <com.galis.weixinstudy.TabIconView android:id="@+id/mTabIcon" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/mTabText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1"/> </LinearLayout> <View android:id="@+id/mTabTip" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/red_dot" android:layout_marginLeft="-2dp" android:layout_alignTop="@id/m_tablayout" android:layout_toRightOf="@id/m_tablayout" android:gravity="center" android:visibility="gone"/></RelativeLayout>
(2)Activity的布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white"> <com.galis.weixinstudy.UIViewPager android:id="@+id/home_view_page" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/darker_gray"/> <com.galis.weixinstudy.UITabBottom android:id="@+id/home_tab_bottom" android:layout_width="match_parent" android:layout_height="60dp"/></LinearLayout>
相對應的實體Bean類:
public final class UITabItem { View parent; TabIconView iconView;//圖片 TextView labelView;//標籤,如首頁,我 View tipView;//紅點提示之類的}
TabIconView是一個關鍵的圖片繪製類,setmAlpha方法接受透明度參數,來重新繪製自己
public class TabIconView extends ImageView { private int mAlpha; private Paint mPaint; private Bitmap clickedBitmap; private Bitmap unClickBitmap; public TabIconView(Context context) { super(context); mAlpha = 0; } public TabIconView(Context context, AttributeSet attrs) { super(context, attrs); mAlpha = 0; } public TabIconView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mAlpha = 0; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mPaint != null) { mPaint.setAlpha(255 - mAlpha);//設定透明度 canvas.drawBitmap(unClickBitmap, null, new Rect(0,0,unClickBitmap.getWidth(), unClickBitmap.getHeight()), mPaint); mPaint.setAlpha(mAlpha);//設定透明度 canvas.drawBitmap(clickedBitmap, null, new Rect(0, 0, clickedBitmap.getWidth(), clickedBitmap.getHeight()),mPaint); } } public void init(int clickedDrawableRid, int unclickedDrawableRid) { clickedBitmap = BitmapFactory.decodeResource(getResources(), clickedDrawableRid);//點擊的圖片 unClickBitmap = BitmapFactory.decodeResource(getResources(), unclickedDrawableRid);//未點擊的圖片 setLayoutParams(new LinearLayout.LayoutParams(clickedBitmap.getWidth(),clickedBitmap.getHeight())); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mAlpha = 0; } public void setmAlpha(int alpha) { mAlpha = alpha; invalidate();//重新調用OnDraw方法 }}
UITabBottom封裝對文字顏色值的操作,我們需要理解文字顏色的轉換,其實就是RGB的轉換.
舉個例子:0xFF123456
FF為透明度,12為Red值,34為Green值,56為Blue值
如果是6位顏色值,如0x123456,預設透明度是FF
怎麼擷取Red值呢?我們可以通過&運算子,來擷取想要的位的資訊
0x123456&0xff0000
可以得到0x120000,然後右位移16位得到Red的值。為什麼是16啊,
因為是16進位,轉成2進位的時候,1位相當於4位,4個0就是16了.
明白這點就行了,顏色的轉化我們可以通過RGB的運算來得到。
如下:
R1 = (colorClick & 0xff0000) >> 16;//未選中的Red值
G1 = (colorClick & 0xff00) >> 8;//未選中的Green值
B1 = (colorClick & 0xff);//未選中的Blue值
R2 = (colorUnclick & 0xff0000) >> 16;//選中的Red值
G2 = (colorUnclick & 0xff00) >> 8;//選中的Green值
B2 = (colorUnclick & 0xff);//選中的Blue值
Rm = R1 - R2;//Red差值
Gm = G1 - G2;//Green差值
Bm = B1 - B2;//Blue差值
當ViewPage滑動的時候,得到滑動距離占頁面寬度的百分比f,得到這個百分比f,
求出R,G,B的值,再將它們拼成一個顏色值就行了。
int R = (int) (R2 + f * Rm);
int G = (int) (G2 + f * Gm);
int B = (int) (B2 + f * Bm);
return 0xff << 24 | R << 16 | G << 8 | B;
詳細代碼如下:
public class UITabBottom extends LinearLayout implements View.OnClickListener { public static interface OnUITabChangeListener { public void onTabChange(int index); } private UITabItem tab0; private UITabItem tab1; private UITabItem tab2; private UITabItem tab3; private UIViewPager mViewPager; private OnUITabChangeListener changeListener; private int colorClick; private int colorUnclick; private int R1;//未選中的Red值 private int G1;//未選中的Green值 private int B1;//未選中的Blue值 private int R2;//選中的Red值 private int G2;//選中的Green值 private int B2;//選中的Blue值 private int Rm = R2 - R1;//Red的差值 private int Gm = G2 - G1;//Green的差值 private int Bm = B2 - B1;//Blue的差值 private int mIndex; public UITabBottom(Context context) { super(context); } public UITabBottom(Context context, AttributeSet attrs) { super(context, attrs); init(); } public UIViewPager getmViewPager() { return mViewPager; } public void setmViewPager(UIViewPager mViewPager) { this.mViewPager = mViewPager; } private UITabItem newChildItem(int i) { UITabItem tabItem = new UITabItem(); tabItem.parent = LayoutInflater.from(getContext()).inflate(R.layout.m_tabitem, null); tabItem.iconView = (TabIconView) tabItem.parent.findViewById(R.id.mTabIcon); tabItem.labelView = (TextView) tabItem.parent.findViewById(R.id.mTabText); tabItem.tipView = tabItem.parent.findViewById(R.id.mTabTip); tabItem.parent.setTag(i); tabItem.parent.setOnClickListener(this); return tabItem; } public void init() { colorClick = getResources().getColor(R.color.select); colorUnclick = getResources().getColor(R.color.unselect); int tabBottomHeight = ViewGroup.LayoutParams.MATCH_PARENT; ; setOrientation(LinearLayout.HORIZONTAL); //tab0 tab0 = newChildItem(0); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, tabBottomHeight); layoutParams.weight = 1; tab0.labelView.setText("首頁"); tab0.labelView.setTextColor(colorClick); tab0.iconView.init(R.drawable.tabbar_home_selected, R.drawable.tabbar_home); addView(tab0.parent, layoutParams); //tab1 tab1 = newChildItem(1); layoutParams = new LinearLayout.LayoutParams(0, tabBottomHeight); layoutParams.weight = 1; tab1.labelView.setText("訊息"); tab1.labelView.setTextColor(colorUnclick); tab1.iconView.init(R.drawable.tabbar_message_center_selected, R.drawable.tabbar_message_center); addView(tab1.parent, layoutParams); //tab2 tab2 = newChildItem(2); layoutParams = new LinearLayout.LayoutParams(0, tabBottomHeight); layoutParams.weight = 1; tab2.labelView.setText("發現"); tab2.labelView.setTextColor(colorUnclick); tab2.iconView.init(R.drawable.tabbar_discover_selected, R.drawable.tabbar_discover); addView(tab2.parent, layoutParams); //tab3 tab3 = newChildItem(3); layoutParams = new LinearLayout.LayoutParams(0, tabBottomHeight); layoutParams.weight = 1; tab3.labelView.setText("我"); tab3.labelView.setTextColor(colorUnclick); tab3.iconView.init(R.drawable.tabbar_profile_selected, R.drawable.tabbar_profile); addView(tab3.parent, layoutParams); R1 = (colorClick & 0xff0000) >> 16; G1 = (colorClick & 0xff00) >> 8; B1 = (colorClick & 0xff); R2 = (colorUnclick & 0xff0000) >> 16; G2 = (colorUnclick & 0xff00) >> 8; B2 = (colorUnclick & 0xff); Rm = R1 - R2; Gm = G1 - G2; Bm = B1 - B2; mIndex = 0; } private OnUITabChangeListener getChangeListener() { return changeListener; } public void setChangeListener(OnUITabChangeListener changeListener) { this.changeListener = changeListener; } public void setTabRedDot(int index,int state) { if(index==2) { tab2.tipView.setVisibility(state); } if(index==3) { tab3.tipView.setVisibility(state); } } public void selectTab(int index) { if (mIndex == index) { return; } mIndex = index; if (changeListener != null) { changeListener.onTabChange(mIndex); } //mIndex表示處於mIndex到mIndex+1頁面之間 switch (mIndex) { case 0: tab0.iconView.setmAlpha(255); tab1.iconView.setmAlpha(0); tab2.iconView.setmAlpha(0); tab3.iconView.setmAlpha(0); tab0.labelView.setTextColor(colorClick); tab1.labelView.setTextColor(colorUnclick); tab2.labelView.setTextColor(colorUnclick); tab3.labelView.setTextColor(colorUnclick); break; case 1: tab0.iconView.setmAlpha(0); tab1.iconView.setmAlpha(255); tab2.iconView.setmAlpha(0); tab3.iconView.setmAlpha(0); tab0.labelView.setTextColor(colorUnclick); tab1.labelView.setTextColor(colorClick); tab2.labelView.setTextColor(colorUnclick); tab3.labelView.setTextColor(colorUnclick); break; case 2: tab0.iconView.setmAlpha(0); tab1.iconView.setmAlpha(0); tab2.iconView.setmAlpha(255); tab3.iconView.setmAlpha(0); tab0.labelView.setTextColor(colorUnclick); tab1.labelView.setTextColor(colorUnclick); tab2.labelView.setTextColor(colorClick); tab3.labelView.setTextColor(colorUnclick); break; case 3: tab0.iconView.setmAlpha(0); tab1.iconView.setmAlpha(0); tab2.iconView.setmAlpha(0); tab3.iconView.setmAlpha(255); tab0.labelView.setTextColor(colorUnclick); tab1.labelView.setTextColor(colorUnclick); tab2.labelView.setTextColor(colorUnclick); tab3.labelView.setTextColor(colorClick); break; } } /** * 拼成顏色值 * @param f * @return */ private int getColorInt(float f) { int R = (int) (R2 + f * Rm); int G = (int) (G2 + f * Gm); int B = (int) (B2 + f * Bm); return 0xff << 24 | R << 16 | G << 8 | B; } /** * location為最左邊頁面的index,e.g.,fragment0到fragment1,傳入location=0 * f為滑動距離的百分比 * * @param location * @param f */ public void scroll(int location, float f) { int leftAlpha = (int) (255 * (1 - f)); int rightAlpha = (int) (255 * f); int leftColor = getColorInt(1 - f); int rightColor = getColorInt(f); switch (location) { case 0: tab0.iconView.setmAlpha(leftAlpha); tab1.iconView.setmAlpha(rightAlpha); tab0.labelView.setTextColor(leftColor); tab1.labelView.setTextColor(rightColor); break; case 1: tab1.iconView.setmAlpha(leftAlpha); tab2.iconView.setmAlpha(rightAlpha); tab1.labelView.setTextColor(leftColor); tab2.labelView.setTextColor(rightColor); break; case 2: tab2.iconView.setmAlpha(leftAlpha); tab3.iconView.setmAlpha(rightAlpha); tab2.labelView.setTextColor(leftColor); tab3.labelView.setTextColor(rightColor); break; } } @Override public void onClick(View v) { int i = ((Integer) v.getTag()).intValue(); mViewPager.setCurrentItem(i, false); selectTab(i); }}
主Activity的話,通過對ViewPager的滑動監聽,來擷取百分比,從而重新整理底部欄的狀態。
public class MainActivity extends FragmentActivity { private UITabBottom mUiTabBottom; private UIViewPager mUiViewPager; private ArrayList<Fragment> fragments = new ArrayList<Fragment>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFragments(); mUiTabBottom = (UITabBottom) findViewById(R.id.home_tab_bottom); mUiViewPager = (UIViewPager) findViewById(R.id.home_view_page); mUiTabBottom.setmViewPager(mUiViewPager); mUiViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int i) { return fragments.get(i); } @Override public int getCount() { return fragments.size(); } }); mUiViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int pageIndex, float v, int i2) { mUiTabBottom.scroll(pageIndex, v);<span style="font-size: 13.3333339691162px; font-family: Arial, Helvetica, sans-serif;">//重新整理底部欄</span> } @Override public void onPageSelected(int i) { mUiTabBottom.selectTab(i);//重新整理底部欄 } @Override public void onPageScrollStateChanged(int i) { } }); } private void initFragments() { for (int i = 0; i < 4; i++) { fragments.add(CustomFragment.newInstance(i)); } } public static class CustomFragment extends Fragment { private int position; private boolean isShown; public static CustomFragment newInstance(int pos) { CustomFragment fragment = new CustomFragment(); Bundle bundle = new Bundle(); bundle.putInt("pos", pos); fragment.setArguments(bundle); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.e("fragment" + position, "onCreateView"); super.onCreateView(inflater, container, savedInstanceState); View layout = inflater.inflate(R.layout.m_fragment, null); View progress = layout.findViewById(R.id.progressContainer); View content = layout.findViewById(R.id.listContainer); return layout; } }}
項目地址:https://github.com/galis/WeiXinStudy.git
整個邏輯就這樣完成了,搞了2天,希望對你們有點協助。