1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android滑动切换页面Tab文字颜色发生渐变效果

Android滑动切换页面Tab文字颜色发生渐变效果

时间:2022-08-20 20:00:23

相关推荐

Android滑动切换页面Tab文字颜色发生渐变效果

Android项目中用到Tab作为导航条切换页面的效果,我相信大家都用到过吧,但是在切换的时候,Tab下划线跟着手指滑动的比例而滑动,相关的两个Tab的文字的颜色根据手指的滑动,而发生颜色渐变的改变。

下面说一下原理:

整个实现的过程需要用到,viewpager+fragment+tab,另外tab下划线的滑动以及tab中文本的颜色的渐变,是根据viewpager的页面的滑动比例计算出来相对应的值,然后进行设置,下划线是设置margin—left来完成的,颜色的渐变是通过设置画笔的透明度来实现。

一、自定义TextView,根据页面滑动的比例,计算出文本的透明度,如果对自定义流程不太清楚,请向这里看过来:

Android自定义View流程:

package com.example.tab;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.os.Looper;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;/*** 自定义textview,可以根据透明度改变其颜色* Created by xiaoyunfei on 16/4/7.*/public class MyTextView extends View {/*** 文本,默认:微信*/private String mText = "微信";/*** 文本大小*/private int mTextSize = (int) TypedValue.applyDimension(PLEX_UNIT_SP, 10f, getResources().getDisplayMetrics());/*** 文本颜色*/private int mColor = 0xff45C01A;/*** 透明度*/private float mAlpha = 0f;/*** 显示文本区域的矩形*/private Rect mTextRect;private Paint mPaint;public MyTextView(Context context) {this(context, null);}public MyTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.change_color_icon_view, defStyleAttr, 0);int count = array.getIndexCount();for (int i = 0; i < count; i++) {int attr = array.getIndex(i);switch (attr) {case R.styleable.change_color_icon_view_color_://文本颜色mColor = array.getColor(attr, 0xff45C01A);break;case R.styleable.change_color_icon_view_text_://文本mText = array.getString(attr);break;case R.styleable.change_color_icon_view_textSize_://文本字号mTextSize = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(PLEX_UNIT_SP, 10f, getResources().getDisplayMetrics()));break;}}array.recycle();mPaint = new Paint();mTextRect = new Rect();mPaint.setTextSize(mTextSize);mPaint.setColor(mColor);mPaint.getTextBounds(mText, 0, mText.length(), mTextRect);}/*** 设置透明度** @param alpha*/public void setmAlpha(float alpha) {this.mAlpha = alpha;invalidateView();}private void invalidateView() {if (Looper.getMainLooper() == Looper.myLooper()) {//因为Android UI操作是非线程安全的,所以invalidate()不能再子线程中执行,需要配合handler使用invalidate();} else {//可以在子线程中使用,因为其封装了handlerpostInvalidate();}}@Overrideprotected void onDraw(Canvas canvas) {//alpha:255--->0:完全不透明--->完全透明int alpha = (int) Math.ceil(255 * mAlpha);drawDefaultText(canvas, alpha);drawTargetText(canvas, alpha);}/*** 写入目标文本** @param canvas* @param alpha*/private void drawTargetText(Canvas canvas, int alpha) {mPaint.setColor(mColor);mPaint.setAlpha(alpha);int width = getMeasuredWidth();int height = getMeasuredHeight();int x = width / 2 - mTextRect.width() / 2;int y = height / 2 + mTextRect.height() / 2;canvas.drawText(mText, x, y, mPaint);}/*** 写入默认文本** @param canvas* @param alpha*/private void drawDefaultText(Canvas canvas, int alpha) {mPaint.setColor(0xff555555);mPaint.setAlpha(255 - alpha);int width = getMeasuredWidth();int height = getMeasuredHeight();int x = width / 2 - mTextRect.width() / 2;int y = height / 2 + mTextRect.height() / 2;canvas.drawText(mText, x, y, mPaint);}}

下面我们来看一下,在activity中,如何实现根据viewpager的滑动,来实现tab的下划线的滑动、以及颜色透明度的设置:

package com.example.tab;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.view.ViewPager;import android.util.DisplayMetrics;import android.view.View;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;public class MainActivity extends FragmentActivity implements View.OnClickListener, ViewPager.OnPageChangeListener {private ViewPager mViewPager;private List<Fragment> mList = new ArrayList<Fragment>();private String[] tag = {"微信", "通讯录", "发现", "我"};private int currentIndex = 0;//上部tabprivate int[] mTextId = {R.id.text_1, R.id.text_2, R.id.text_3, R.id.text_4};private MyTextView[] mTextViews = new MyTextView[4];private View tabView;private LinearLayout.LayoutParams params;/*** tab下划线的宽度*/private int width;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();initTabLine();initData();}/*** 初始化tab下划线*/private void initTabLine() {params = (LinearLayout.LayoutParams) tabView.getLayoutParams();DisplayMetrics metrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);width = metrics.widthPixels / 4;params.width = width;tabView.setLayoutParams(params);}/*** 初始化数据*/private void initData() {for (int i = 0; i < 4; i++) {TabFragment fragment = new TabFragment();Bundle bundle = new Bundle();bundle.putString("content", tag[i]);fragment.setArguments(bundle);mList.add(fragment);}MyPageAdapter adapter = new MyPageAdapter(getSupportFragmentManager(), mList);mViewPager.setAdapter(adapter);}/*** 初始化控件*/private void initViews() {mViewPager = (ViewPager) findViewById(R.id.viewpager);for (int i = 0; i < mTextId.length; i++) {mTextViews[i] = (MyTextView) findViewById(mTextId[i]);mTextViews[i].setOnClickListener(this);}tabView = findViewById(R.id.tab_view);mViewPager.addOnPageChangeListener(this);mTextViews[0].setmAlpha(1.0f);}@Overridepublic void onClick(View v) {resetOtherTab();setClickTab(v.getId());// switch (v.getId()) {// case R.id.tab_1://setClickTab(0);//break;// case R.id.tab_2://setClickTab(1);//break;// case R.id.tab_3://setClickTab(2);//break;// case R.id.tab_4://setClickTab(3);//break;// }}/*** 设置当前的tab** @param id*/private void setClickTab(int id) {int i = -1;//根据id获取到指定的tab的下下标for (int j = 0; j < mTextId.length; j++) {if (mTextId[j] == id) {i = j;break;}}if (i == -1)return;params.leftMargin = width * i;tabView.setLayoutParams(params);setTab(i);}/*** 设置当前的tab** @param i*/private void setTab(int i) {mViewPager.setCurrentItem(i, false);mTextViews[i].setmAlpha(1.0f);currentIndex = i;}/*** 重新设置tab值默认值*/private void resetOtherTab() {for (int i = 0; i < mTextId.length; i++) {mTextViews[i].setmAlpha(0f);}}@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {//注:position大部分时间和左边的页面的下标一致;positionOffset以及positionOffsetPixels大部分时间和右边的页面占比保持一致// if (position == 0 && currentIndex == 0) {//0-->1// mTextViews[0].setmAlpha(1 - positionOffset);// mTextViews[1].setmAlpha(positionOffset);// params.leftMargin = (int) (width * positionOffset);// } else if (position == 0 && currentIndex == 1) {//1-->0// mTextViews[0].setmAlpha(1 - positionOffset);// mTextViews[1].setmAlpha(positionOffset);// params.leftMargin = (int) (-width * (1 - positionOffset) + width * currentIndex);// } else if (position == 1 && currentIndex == 1) {//1-->2// mTextViews[1].setmAlpha(1 - positionOffset);// mTextViews[2].setmAlpha(positionOffset);// params.leftMargin = (int) (width * positionOffset + width * currentIndex);// } else if (position == 1 && currentIndex == 2) {//2-->1// mTextViews[1].setmAlpha(1 - positionOffset);// mTextViews[2].setmAlpha(positionOffset);// params.leftMargin = (int) (-width * (1 - positionOffset) + width * currentIndex);// } else if (position == 2 && currentIndex == 2) {//2-->3// mTextViews[2].setmAlpha(1 - positionOffset);// mTextViews[3].setmAlpha(positionOffset);// params.leftMargin = (int) (width * positionOffset + width * currentIndex);// } else if (position == 2 && currentIndex == 3) {//3-->2// mTextViews[2].setmAlpha(1 - positionOffset);// mTextViews[3].setmAlpha(positionOffset);// params.leftMargin = (int) (-width * (1 - positionOffset) + width * currentIndex);// }//上面的代码可以抽成下面的一个方法pageScroll(position, positionOffset);}/*** viewpager滑动的时候设置顶部和底部tab的透明度以及顶部tab下划线的位置** @param position* @param positionOffset*/private void pageScroll(int position, float positionOffset) {if (position + 1 == mTextViews.length)//因为2-->3滑动的时候,在最后滚动结束的时候,position会突变成3(position大部分时候和左边的页面的下标一直),这样会造成下标越界return;mTextViews[position].setmAlpha(1 - positionOffset);mTextViews[position + 1].setmAlpha(positionOffset);if (position == currentIndex) {params.leftMargin = (int) (width * positionOffset + width * currentIndex);} else {params.leftMargin = (int) (-width * (1 - positionOffset) + width * currentIndex);}tabView.setLayoutParams(params);}@Overridepublic void onPageSelected(int position) {currentIndex = position;setTab(position);}@Overridepublic void onPageScrollStateChanged(int state) {}}

其中,实现的核心代码,在viewpager添加的监听的回调方法

onPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels)中,如果对

viewpager添加的这个监听,需要做一点解释:

有什么不理解的地方,可以参考我的另外一篇博客:

ViewPager的setOnPageChangeListener方法详解,这里对viewpager滑动的监听做了详细的说明。

例如:从1-->2滑动:

params.leftMargin = (int) (width * positionOffset + width * currentIndex);

从这个可以看出来,leftMargin的值等于当前的距左的值(width*currentIndex)加上滑动比例对应的宽度

(width*positionOffset)。

mTextViews[position].setmAlpha(1 - positionOffset);

mTextViews[position + 1].setmAlpha(positionOffset);

设置透明度。

项目下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。