首页 > 代码库 > 微信之底部栏滑动变色

微信之底部栏滑动变色

微信,代表着国内软件的顶级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天,希望对你们有点帮助。







微信之底部栏滑动变色