高仿微信6.0Tab bar

微信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
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值