高仿微信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的属性,
代码中对应的layout文件如下,
其实这里渐变效果的TextView也是同样的原理,实现代码和GradientIconView几乎差不多,这里就不贴代码了。
最后应该在主界面来测试代码效果了,激动人心啊!
写在最后,控件已上传至jcenter,在AndroidStudio引用如下:
dependencies {
compile 'com.david.gradientuilib:gradientuilibrary:1.0.1'
}
开源地址
https://github.com/wangdong20/AndroidGradientUI
不过我发现,真正微信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
相关文章推荐
- 微信企业号开发相关问题
- 微信JS分享实战代码
- C#开发微信门户及应用(1)--开始使用微信接口
- Testlink自动执行用例小程序
- overflow: hidden;在安卓微信页面失效问题
- 微信获取用户地理位置信息的原理与步骤
- 微信服务号开发-获取用户位置信息
- 微信获取用户地理位置信息的原理与步骤
- 分享 Java微信开发SDK
- Zabbix 实现微信短信告警
- 024.ArrayList中方法详解
- php 在web端来播放amr语音(如微信语音)
- 微信公众平台开发者模式(2)JAVA自动回复文本消息及多图文消息
- 微信上传图片
- 微信公众平台开发者模式(1)JAVA版接入
- java 微信平台开发80端口映射
- 通达OA 集成微信功能成为升级到2015的最大亮点(图文)
- 通达OA 集成微信功能成为升级到2015的最大亮点(图文)
- 微信去除EMOJI表情
- 微信公众号(一)