您的位置:首页 > 移动开发 > 微信开发

高仿微信6.0Tab bar

2015-11-12 14:28 633 查看
微信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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: