首页 > 代码库 > 微信之底部栏滑动变色
微信之底部栏滑动变色
微信,代表着国内软件的顶级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); } @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; } } }
整个逻辑就这样完成了,搞了2天,希望对你们有点帮助。
微信之底部栏滑动变色