之前写过一篇仿微信底部渐变Tab的文章:Android 仿微信底部渐变Tab
是根据ImageView的tint属性来实现颜色渐变效果的,这里再来提供一个新思路,是根据图片的透明度来实现Tab渐变切换,步骤比起之前的方法要简单一些,而且效果会更好
好像是效果图?首先需要准备几张如下这样的照片,这都是我解压微信Apk文件得来的
叶应是叶分别对应的是一张透明色和一张绿色,将两张图片重叠在一起放置,在Fragmnet切换时来改变上下两张图片的透明度,从而实现颜色渐变
首先来定义Tab布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="3dp">
<ImageView
android:id="@+id/iv_select_icon"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/iv_normal_icon"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="3dp">
<TextView
android:id="@+id/tv_select_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_normal_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
</LinearLayout>
因为Tab文字也要实现颜色渐变,所以除了要两个ImageView外还要两个TextView
在values文件夹下新建一个attrs.xml文件需要用到的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--滑动颜色渐变Tab-->
<declare-styleable name="ShadeTabView">
<attr name="normalIcon" format="reference" />
<attr name="selectIcon" format="reference" />
<attr name="tab" format="string" />
<attr name="textSize" format="dimension" />
<attr name="normalTextColor" format="color" />
<attr name="selectTextColor" format="color" />
</declare-styleable>
</resources>
之后就是自定义View了,步骤与我之前的那篇文章类似
/**
* 作者: 叶应是叶
* 时间: 2017/3/4 20:47
* 描述: 渐变Tab
*/
public class ShadeTabView extends FrameLayout {
/**
* 一般状态下的图标
*/
private ImageView iv_normalIcon;
/**
* 选中状态下的图标
*/
private ImageView iv_selectIcon;
/**
* 一般状态下底部 TextView
*/
private TextView tv_normalLabel;
/**
* 选中状态下底部 TextView
*/
private TextView tv_selectLabel;
/**
* 选中状态下的文字颜色
*/
private int selectTextColor;
/**
* 底部文字默认大小(sp)
*/
private final int DEFAULT_TEXT_SIZE = 6;
/**
* 一般状态下底部文字默认颜色
*/
private final String DEFAULT_NORMAL_TEXT_COLOR = "#989898";
/**
* 选中状态下底部文字默认颜色
*/
private final String DEFAULT_SELECT_TEXT_COLOR = "#45C01A";
private float alpha;
public ShadeTabView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
//获取自定义属性值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadeTabView, 0, 0);
BitmapDrawable normalIcon = (BitmapDrawable) typedArray.getDrawable(R.styleable.ShadeTabView_normalIcon);
BitmapDrawable selectIcon = (BitmapDrawable) typedArray.getDrawable(R.styleable.ShadeTabView_selectIcon);
String tab = typedArray.getString(R.styleable.ShadeTabView_tab);
float textSize = typedArray.getDimension(R.styleable.ShadeTabView_textSize,
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, DEFAULT_TEXT_SIZE, getResources().getDisplayMetrics()));
int normalTextColor = typedArray.getColor(R.styleable.ShadeTabView_normalTextColor, Color.parseColor(DEFAULT_NORMAL_TEXT_COLOR));
selectTextColor = typedArray.getColor(R.styleable.ShadeTabView_selectTextColor, Color.parseColor(DEFAULT_SELECT_TEXT_COLOR));
//资源回收
typedArray.recycle();
//属性设置
iv_normalIcon.setImageDrawable(normalIcon);
iv_selectIcon.setImageDrawable(selectIcon);
tv_normalLabel.setText(tab);
tv_normalLabel.setTextSize(textSize);
tv_normalLabel.setTextColor(normalTextColor);
tv_selectLabel.setText(tab);
tv_selectLabel.setTextSize(textSize);
tv_selectLabel.setTextColor(selectTextColor);
setIconAlpha(1);
}
private void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_shade_tab, this);
iv_normalIcon = (ImageView) findViewById(R.id.iv_normal_icon);
iv_selectIcon = (ImageView) findViewById(R.id.iv_select_icon);
tv_normalLabel = (TextView) findViewById(R.id.tv_normal_label);
tv_selectLabel = (TextView) findViewById(R.id.tv_select_label);
}
/**
* 设置上下两层图片的透明度,alpha 值越小,图片的颜色越倾向于带有颜色的图层
*
* @param alpha 透明度
*/
public void setIconAlpha(float alpha) {
// setAlpha(float) 0.0f~1.0f 数值越大越不透明
iv_selectIcon.setAlpha(1 - alpha);
iv_normalIcon.setAlpha(alpha);
tv_normalLabel.setAlpha(alpha);
tv_selectLabel.setAlpha(1 - alpha);
this.alpha = alpha;
}
private static final String STATE_INSTANCE = "STATE_INSTANCE";
private static final String STATE_ALPHA = "STATE_ALPHA";
/**
* 保存状态
*
* @return Parcelable
*/
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
bundle.putFloat(STATE_ALPHA, alpha);
return bundle;
}
/**
* 恢复状态
*
* @param parcelable Parcelable
*/
@Override
protected void onRestoreInstanceState(Parcelable parcelable) {
Bundle bundle = (Bundle) parcelable;
super.onRestoreInstanceState(bundle.getParcelable(STATE_INSTANCE));
setIconAlpha(bundle.getFloat(STATE_ALPHA));
}
}
之后,到布局中使用ShadeTabView,并将其与ViewPager的滑动关联起来
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#393A3F"
app:title="@string/app_name"
app:titleTextColor="@android:color/white" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#abc" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#e7f7f4f4"
android:orientation="horizontal">
<com.czy.weixintab.ShadeTabView
android:id="@+id/stv_weiXin"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:normalIcon="@drawable/tab_weixin"
app:selectIcon="@drawable/tab_weixin_select"
app:tab="微信" />
<com.czy.weixintab.ShadeTabView
android:id="@+id/stv_address_book"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:normalIcon="@drawable/tab_address_list"
app:selectIcon="@drawable/tab_address_list_select"
app:tab="通讯录" />
<com.czy.weixintab.ShadeTabView
android:id="@+id/stv_discover"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:normalIcon="@drawable/tab_discover"
app:selectIcon="@drawable/tab_discover_select"
app:tab="发现" />
<com.czy.weixintab.ShadeTabView
android:id="@+id/stv_me"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:normalIcon="@drawable/tab_me"
app:selectIcon="@drawable/tab_me_select"
app:tab="我" />
</LinearLayout>
</LinearLayout>
为ViewPager设置一个滑动监听器,根据ViewPager的滑动偏移量positionOffset来改变ShadeTabView中上下两张图片的透明度
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener, View.OnClickListener {
private List<Fragment> tabFragments;
private List<ShadeTabView> tabIndicators;
private ViewPager viewPager;
private FragmentPagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
viewPager.setAdapter(adapter);
}
private void initData() {
tabFragments = new ArrayList<>();
tabIndicators = new ArrayList<>();
TabFragment weiXinFragment = TabFragment.newInstance("微信");
TabFragment contactsFragment = TabFragment.newInstance("通讯录");
TabFragment discoverFragment = TabFragment.newInstance("发现");
TabFragment meFragment = TabFragment.newInstance("我");
tabFragments.add(weiXinFragment);
tabFragments.add(contactsFragment);
tabFragments.add(discoverFragment);
tabFragments.add(meFragment);
adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public int getCount() {
return tabFragments.size();
}
@Override
public Fragment getItem(int arg0) {
return tabFragments.get(arg0);
}
};
}
private void initView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.addOnPageChangeListener(this);
ShadeTabView stv_weiXin = (ShadeTabView) findViewById(R.id.stv_weiXin);
ShadeTabView stv_address_book = (ShadeTabView) findViewById(R.id.stv_address_book);
ShadeTabView stv_discover = (ShadeTabView) findViewById(R.id.stv_discover);
ShadeTabView stv_me = (ShadeTabView) findViewById(R.id.stv_me);
tabIndicators.add(stv_weiXin);
tabIndicators.add(stv_address_book);
tabIndicators.add(stv_discover);
tabIndicators.add(stv_me);
stv_weiXin.setOnClickListener(this);
stv_address_book.setOnClickListener(this);
stv_discover.setOnClickListener(this);
stv_me.setOnClickListener(this);
stv_weiXin.setIconAlpha(0);
}
/**
* 重置Tab状态
*/
private void resetTabsStatus() {
for (int i = 0; i < tabIndicators.size(); i++) {
tabIndicators.get(i).setIconAlpha(1);
}
}
/**
* 如果是直接点击图标来跳转页面的话,position值为0到3,positionOffset一直为0.0
* 如果是通过滑动来跳转页面的话
* 假如是从第一页滑动到第二页
* 在这个过程中,positionOffset从接近0逐渐增大到接近1.0,滑动完成后又恢复到0.0,而position只有在滑动完成后才从0变为1
* 假如是从第二页滑动到第一页
* 在这个过程中,positionOffset从接近1.0逐渐减小到0.0,而position一直是0
*
* @param position 当前页面索引
* @param positionOffset 偏移量
* @param positionOffsetPixels 偏移量
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffset > 0) {
ShadeTabView leftTab = tabIndicators.get(position);
ShadeTabView rightTab = tabIndicators.get(position + 1);
leftTab.setIconAlpha(positionOffset);
rightTab.setIconAlpha(1 - positionOffset);
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onClick(View v) {
resetTabsStatus();
switch (v.getId()) {
case R.id.stv_weiXin:
tabIndicators.get(0).setIconAlpha(0);
viewPager.setCurrentItem(0, false);
break;
case R.id.stv_address_book:
tabIndicators.get(1).setIconAlpha(0);
viewPager.setCurrentItem(1, false);
break;
case R.id.stv_discover:
tabIndicators.get(2).setIconAlpha(0);
viewPager.setCurrentItem(2, false);
break;
case R.id.stv_me:
tabIndicators.get(3).setIconAlpha(0);
viewPager.setCurrentItem(3, false);
break;
}
}
}
网友评论