高仿微信6.0Tab bar

来源:互联网 发布:守序中立 知乎 编辑:程序博客网 时间:2024/05/17 02:08

微信6.0版本的底部Tab Bar,切换图标变色的效果还不错,之前看过鸿洋大神的Android高仿微信6.0主界面,很是佩服。

不过我发现,真正微信6.0的切换图标变色的效果应该还不是鸿洋大神的那种方法,我们先看一下我做的效果图。


在这个Discover发现图标这里,那个指针部分是从灰色变成透明,而不是从灰色变成绿色。

所以从这里我可以判断微信6.0的这种切换图标效果应该不是用Paint的Xfermodes实现的,

Paint的Xfermodes是首先绘制一个绿色矩形的src,然后再在上面绘制dst图标,

设置Xfermodes为DST_IN,这样就会把src和dst相交的部分一起绘制出来,

也就是说上层的dst的图标被绘制出来了,同时底层的绿色矩形和图标相交的部分被绘制出来,

最后的结果就是图标的非透明部分都会变成绿色。

所以如果按照这种方法,Discover图标的指针部分就应该是从灰色变成绿色,而不是从灰色变成透明。


在这里我们换一个思路,能实现这种效果,其实思路也很简单,我都能写出来,各位看官肯定也不在话下。

就是这种图标转换的效果,其实就是两张形状一样的图片,但是颜色风格不同,叠在一起,

上层的图标设置自己的alpha透明度属性,下层的图标对应的把透明度设置成1 - alpha,

就可以做到两张图片渐变切换的效果。


话不多说,开始码代码:

先定义自定义View的属性,

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="top_icon" format="reference" />    <attr name="bottom_icon" format="reference" />    <declare-styleable name="GradientIconView">        <attr name="top_icon" />        <attr name="bottom_icon" />    </declare-styleable>    <attr name="text" format="string" />    <attr name="text_size" format="dimension" />    <attr name="top_text_color" format="color" />    <attr name="bottom_text_color" format="color" />    <declare-styleable name="GradientTextView">        <attr name="text" />        <attr name="text_size" />        <attr name="top_text_color" />        <attr name="bottom_text_color" />    </declare-styleable></resources>
然后根据自定义属性,写代码实现它。

package com.david.wechatsample.gradientuilibrary;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.FrameLayout;import android.widget.ImageView;/** * Created by David Wong on 2015/10/20. */public class GradientIconView extends FrameLayout {    private ImageView mTopIconView;    private ImageView mBottomIconView;    private static final String INSTANCE_STATE = "instance_state";    private static final String STATE_ALPHA = "state_alpha";    private float mAlpha = 0f;    public GradientIconView(Context context) {        this(context, null, 0);    }    public GradientIconView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public GradientIconView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initView(context);        // 获取设置的图标        TypedArray a = context.obtainStyledAttributes(attrs,                R.styleable.GradientIconView);        BitmapDrawable drawable;        int n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            if (attr == R.styleable.GradientIconView_top_icon) {                drawable = (BitmapDrawable) a.getDrawable(attr);                setTopIconView(drawable);            } else if (attr == R.styleable.GradientIconView_bottom_icon) {                drawable = (BitmapDrawable) a.getDrawable(attr);                setBottomIconView(drawable);            }        }        a.recycle();        setIconAlpha(mAlpha);    }    private void initView(Context context) {        LayoutInflater.from(context).inflate(R.layout.gradient_icon_layout, this, true);        mTopIconView = (ImageView) findViewById(R.id.top_icon_view);        mBottomIconView = (ImageView) findViewById(R.id.bottom_icon_view);    }    public void setIconAlpha(float alpha) {        mTopIconView.setAlpha(alpha);        mBottomIconView.setAlpha(1 - alpha);        this.mAlpha = alpha;    }    public void setTopIconView(Drawable drawable) {        mTopIconView.setBackgroundDrawable(drawable);    }    public void setBottomIconView(Drawable drawable) {        mBottomIconView.setBackgroundDrawable(drawable);    }    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());        bundle.putFloat(STATE_ALPHA, mAlpha);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (state instanceof Bundle) {            Bundle bundle = (Bundle) state;            mAlpha = bundle.getFloat(STATE_ALPHA);            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));        } else {            super.onRestoreInstanceState(state);        }    }}

代码中对应的layout文件如下,

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ImageView        android:id="@+id/bottom_icon_view"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <ImageView        android:id="@+id/top_icon_view"        android:layout_width="match_parent"        android:layout_height="match_parent" /></FrameLayout>
在这里GradientIconView就写完了,代码没有多少行,很简单。

其实这里渐变效果的TextView也是同样的原理,实现代码和GradientIconView几乎差不多,这里就不贴代码了。

最后应该在主界面来测试代码效果了,激动人心啊!

package com.david.wechatsample.wechatsample;import android.net.Uri;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.view.View;import com.david.wechatsample.fragment.AboutMeFragment;import com.david.wechatsample.fragment.ChatsFragment;import com.david.wechatsample.fragment.ContactsFragment;import com.david.wechatsample.fragment.DiscoverFragment;import com.david.wechatsample.fragment.OnFragmentInteractionListener;import com.david.wechatsample.gradientuilibrary.GradientIconView;import com.david.wechatsample.gradientuilibrary.GradientTextView;import java.util.ArrayList;import java.util.List;public class MainActivity extends FragmentActivity implements View.OnClickListener, ViewPager.OnPageChangeListener, OnFragmentInteractionListener {    private ViewPager mViewPager;    private List<Fragment> mTabs = new ArrayList<Fragment>();    private FragmentPagerAdapter mAdapter;    private List<GradientIconView> mTabIconIndicator = new ArrayList<GradientIconView>();    private List<GradientTextView> mTabTextIndicator = new ArrayList<GradientTextView>();    private GradientIconView mChatsIconView;    private GradientIconView mContactsIconView;    private GradientIconView mDiscoverIconView;    private GradientIconView mAboutMeIconView;    private GradientTextView mTvChats;    private GradientTextView mTvContacts;    private GradientTextView mTvDiscover;    private GradientTextView mTvAboutMe;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        mViewPager = (ViewPager) findViewById(R.id.id_viewpager);        mChatsIconView = (GradientIconView) findViewById(R.id.id_iconfont_chat);        mChatsIconView.setOnClickListener(this);        mTabIconIndicator.add(mChatsIconView);        mChatsIconView.setIconAlpha(1.0f);        mContactsIconView = (GradientIconView) findViewById(R.id.id_iconfont_friend);        mContactsIconView.setOnClickListener(this);        mTabIconIndicator.add(mContactsIconView);        mDiscoverIconView = (GradientIconView) findViewById(R.id.id_iconfont_faxian);        mDiscoverIconView.setOnClickListener(this);        mTabIconIndicator.add(mDiscoverIconView);        mAboutMeIconView = (GradientIconView) findViewById(R.id.id_iconfont_me);        mAboutMeIconView.setOnClickListener(this);        mTabIconIndicator.add(mAboutMeIconView);        mTvChats = (GradientTextView) findViewById(R.id.id_chats_tv);        mTvChats.setOnClickListener(this);        mTabTextIndicator.add(mTvChats);        mTvChats.setTextViewAlpha(1.0f);        mTvContacts = (GradientTextView) findViewById(R.id.id_contacts_tv);        mTvContacts.setOnClickListener(this);        mTabTextIndicator.add(mTvContacts);        mTvDiscover = (GradientTextView) findViewById(R.id.id_discover_tv);        mTvDiscover.setOnClickListener(this);        mTabTextIndicator.add(mTvDiscover);        mTvAboutMe = (GradientTextView) findViewById(R.id.id_about_me_tv);        mTvAboutMe.setOnClickListener(this);        mTabTextIndicator.add(mTvAboutMe);        initFragments();    }    private void initFragments() {        mTabs.add(ChatsFragment.newInstance("", ""));        mTabs.add(ContactsFragment.newInstance("", ""));        mTabs.add(DiscoverFragment.newInstance("", ""));        mTabs.add(AboutMeFragment.newInstance("", ""));        mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {            @Override            public int getCount() {                return mTabs.size();            }            @Override            public Fragment getItem(int arg0) {                return mTabs.get(arg0);            }        };        mViewPager.setAdapter(mAdapter);        mViewPager.setOnPageChangeListener(this);    }    /**     * 重置其他的Tab     */    private void resetOtherTabs() {        resetOtherTabIcons();        resetOtherTabText();    }    /**     * 重置其他的Tab icon     */    private void resetOtherTabIcons() {        for (int i = 0; i < mTabIconIndicator.size(); i++) {            mTabIconIndicator.get(i).setIconAlpha(0);        }    }    /**     * 重置其他的Tab text     */    private void resetOtherTabText() {        for (int i = 0; i < mTabTextIndicator.size(); i++) {            mTabTextIndicator.get(i).setTextViewAlpha(0);        }    }    @Override    public void onClick(View v) {        resetOtherTabs();        switch (v.getId()) {            case R.id.id_iconfont_chat:            case R.id.id_chats_tv:                mTabIconIndicator.get(0).setIconAlpha(1.0f);                mTabTextIndicator.get(0).setTextViewAlpha(1.0f);                mViewPager.setCurrentItem(0, false);                break;            case R.id.id_iconfont_friend:            case R.id.id_contacts_tv:                mTabIconIndicator.get(1).setIconAlpha(1.0f);                mTabTextIndicator.get(1).setTextViewAlpha(1.0f);                mViewPager.setCurrentItem(1, false);                break;            case R.id.id_iconfont_faxian:            case R.id.id_discover_tv:                mTabIconIndicator.get(2).setIconAlpha(1.0f);                mTabTextIndicator.get(2).setTextViewAlpha(1.0f);                mViewPager.setCurrentItem(2, false);                break;            case R.id.id_iconfont_me:            case R.id.id_about_me_tv:                mTabIconIndicator.get(3).setIconAlpha(1.0f);                mTabTextIndicator.get(3).setTextViewAlpha(1.0f);                mViewPager.setCurrentItem(3, false);                break;        }    }    @Override    public void onFragmentInteraction(Uri uri) {    }    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        if (positionOffset > 0) {            GradientIconView iconLeft = mTabIconIndicator.get(position);            GradientIconView iconRight = mTabIconIndicator.get(position + 1);            GradientTextView textLeft = mTabTextIndicator.get(position);            GradientTextView textRight = mTabTextIndicator.get(position + 1);            iconLeft.setIconAlpha(1 - positionOffset);            textLeft.setTextViewAlpha(1 - positionOffset);            iconRight.setIconAlpha(positionOffset);            textRight.setTextViewAlpha(positionOffset);        }    }    @Override    public void onPageSelected(int position) {    }    @Override    public void onPageScrollStateChanged(int state) {    }}

写在最后,控件已上传至jcenter,在AndroidStudio引用如下:

dependencies {    compile 'com.david.gradientuilib:gradientuilibrary:1.0.1'}

开源地址

https://github.com/wangdong20/AndroidGradientUI


3 0