Android仿微信底部按钮滑动变色

Android仿微信底部按钮滑动变色,这里只针对使用Fragment为Tab页的滑动操作,进行简单的变色讲解。

首先说下OnPageChangeListener这个监听

//这个监听有三个方法
public abstract void onPageScrollStateChanged (int state) 

public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) 

public abstract void onPageSelected (int position) 

//第一个方法onPageScrollStateChanged 中的参数state,有三个可取的值

public static final int SCROLL_STATE_DRAGGING
Constant Value: 1 (0x00000001) //手指按在ViewPager上滑动时

public static final int SCROLL_STATE_IDLE
Constant Value: 0 (0x00000000) //手指松开后,ViewPager自动滑动期间

public static final int SCROLL_STATE_SETTLING
Constant Value: 2 (0x00000002) //ViewPager进入了某个Page

//如果在onPageScrollStateChanged 中输出state的值,你会发现每次都是按顺序打印出“1---2---0”

//第二个方法onPageScrolled的三个参数

position://滑动时,屏幕左侧显示的第一个page

positionOffset://滑动比例,值的范围为[0, 1),手指往左滑动,该值递增,反之递减

positionOffsetPixels://滑动距离,和屏幕有关,手指往左滑动,该值递增,反之递减

//我们经常需要检查viewpager的滑动方向并作出一些操作,这时你只需要通过position和positionOffset两个值即可实现该功能。

//比如实现微信底部图标颜色渐变 向左滑动时

ChangeColorIconWithTextView left = mTabIndicator.get(position); //左侧显示的第一个page页面上底部图标和文字的初始化
ChangeColorIconWithTextView right = mTabIndicator.get(position + 1); //右侧显示的Page底部图标和文字的初始化

left.setIconAlpha(1 - positionOffset); //设置图标的透明度 此时positionOffset值递增 左侧图标的颜色变浅
right.setIconAlpha(positionOffset); //右侧图标的颜色逐渐变深

//第三个方法onPageSelected的三个参数

position://当前选择的page序号

//该方法被调用的时间比较特别,在上面的第一个方法中的“1---2----0”中的2执行之后,onPageSelected就执行,然后执行“1---2----0”中的0。就是手指松开屏幕之后,onPageSelected被执行。

上面提到了ChangeColorIconWithTextView 主要类

package com.mhealth.nursestation.app.pda.business.login.base.ui.fragmentutil;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Looper;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.mhealth.nursestation.app.pda.R;

/**
 * 此类用于修改颜色渐变
 */
public class ChangeColorIconWithTextView extends View {

  private Bitmap mBitmap;
  private Canvas mCanvas;
  private Paint mPaint;
  /**
   * 颜色
   */
  private int mColor = 0XFF07B7C4;
  /**
   * 透明度 0.0-1.0 初始化必须是0 不是0就废了
   */
  private float mAlpha = 0f;
  /**
   * 图标
   */
  private Bitmap mIconBitmap;
  /**
   * 限制绘制icon的范围
   */
  private Rect mIconRect;
  /**
   * icon底部文本
   */
  private String mText = "微信";
  private int mTextSize = (int) TypedValue.applyDimension(
      TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics());
  private Paint mTextPaint;
  private Rect mTextBound = new Rect();

  public ChangeColorIconWithTextView(Context context) {
    super(context);
  }

  /**
   * 初始化自定义属性值
   *
   * @param context
   * @param attrs
   */
  public ChangeColorIconWithTextView(Context context, AttributeSet attrs) {
    super(context, attrs);

    // 获取设置的图标
    TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.ChangeColorIconView);

    int n = a.getIndexCount();
    for (int i = 0; i < n; i++) {

      int attr = a.getIndex(i);
      switch (attr) {
      case R.styleable.ChangeColorIconView_icon:
        BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(attr);
        mIconBitmap = drawable.getBitmap();
        break;
      case R.styleable.ChangeColorIconView_color:
        mColor = a.getColor(attr, 0x07B7C4);
        break;
      case R.styleable.ChangeColorIconView_text:
        mText = a.getString(attr);
        break;
      case R.styleable.ChangeColorIconView_text_size:
        mTextSize = (int) a.getDimension(attr, TypedValue
            .applyDimension(TypedValue.COMPLEX_UNIT_SP, 10,
                getResources().getDisplayMetrics()));
        break;

      }
    }

    a.recycle();

    mTextPaint = new Paint();
    mTextPaint.setTextSize(mTextSize);
    mTextPaint.setColor(0xff07B7C4);
    mTextPaint.setAntiAlias(true);
    // 得到text绘制范围
    mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBound);

  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    // 得到绘制icon的宽
    int bitmapWidth = Math.min(getMeasuredWidth() - getPaddingLeft()
        - getPaddingRight(), getMeasuredHeight() - getPaddingTop()
        - getPaddingBottom() - mTextBound.height());

    int left = getMeasuredWidth() / 2 - bitmapWidth / 2;
    int top = (getMeasuredHeight() - mTextBound.height()) / 2 - bitmapWidth
        / 2;
    // 得到绘制icon的宽
    mIconRect = new Rect(left, top, left + bitmapWidth, top + bitmapWidth);

  }

  @Override
  protected void onDraw(Canvas canvas) {

    int alpha = (int) Math.ceil((255 * mAlpha));
    canvas.drawBitmap(mIconBitmap, null, mIconRect, null);
    setupTargetBitmap(alpha);
    drawSourceText(canvas, alpha);
    drawTargetText(canvas, alpha);
    canvas.drawBitmap(mBitmap, 0, 0, null);

  }

  private void setupTargetBitmap(int alpha) {
    mBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
        Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mPaint = new Paint();
    mPaint.setColor(mColor);
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setAlpha(alpha);
    mCanvas.drawRect(mIconRect, mPaint);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    mPaint.setAlpha(255);
    mCanvas.drawBitmap(mIconBitmap, null, mIconRect, mPaint);
  }

  /**
   * 透明度 255
   *
   * @param canvas
   * @param alpha
   */
  private void drawSourceText(Canvas canvas, int alpha) {
    mTextPaint.setTextSize(mTextSize);
    mTextPaint.setColor(0x00333333);
    mTextPaint.setAlpha(255 - alpha);
    canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2
        - mTextBound.width() / 2,
        mIconRect.bottom + mTextBound.height(), mTextPaint);
  }

  private void drawTargetText(Canvas canvas, int alpha) {
    mTextPaint.setColor(mColor);
    mTextPaint.setAlpha(alpha);
    canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2
        - mTextBound.width() / 2,
        mIconRect.bottom + mTextBound.height(), mTextPaint);

  }

  public void setIconAlpha(float alpha) {
    this.mAlpha = alpha;
    invalidateView();
  }

  private void invalidateView() {
    if (Looper.getMainLooper() == Looper.myLooper()) {
      invalidate();
    } else {
      postInvalidate();
    }
  }

  public void setIconColor(int color) {
    mColor = color;
  }

  public void setIcon(int resId) {
    this.mIconBitmap = BitmapFactory.decodeResource(getResources(), resId);
    if (mIconRect != null)
      invalidateView();
  }

  public void setIcon(Bitmap iconBitmap) {
    this.mIconBitmap = iconBitmap;
    if (mIconRect != null)
      invalidateView();
  }

  private static final String INSTANCE_STATE = "instance_state";
  private static final String STATE_ALPHA = "state_alpha";

  @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);
    }
  }
}

在Activity里面实现监听操作

@Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    if (positionOffset > 0) {
      ChangeColorIconWithTextView left = mTabIndicator.get(position);
      ChangeColorIconWithTextView right = mTabIndicator.get(position + 1);

      left.setIconAlpha(1 - positionOffset);
      right.setIconAlpha(positionOffset);
    }
  }

定义一个集合,将所有变色控件装载进去

private List<ChangeColorIconWithTextView> mTabIndicator = new ArrayList<ChangeColorIconWithTextView>();

private void initTabIndicator() {
    ChangeColorIconWithTextView one = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_one);
    ChangeColorIconWithTextView two = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_two);
    ChangeColorIconWithTextView three = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_three);
    ChangeColorIconWithTextView four = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_four);

    mTabIndicator.add(one);
    mTabIndicator.add(two);
    mTabIndicator.add(three);
    mTabIndicator.add(four);

    one.setOnClickListener(this);
    two.setOnClickListener(this);
    three.setOnClickListener(this);
    four.setOnClickListener(this);

    one.setIconAlpha(1.0f);
  }

点击监听

@Override
  public void onClick(View v) {

    resetOtherTabs();

    switch (v.getId()) {
    case R.id.id_indicator_one:
      mTabIndicator.get(0).setIconAlpha(1.0f);
      mViewPager.setCurrentItem(0, false);
      break;
    case R.id.id_indicator_two:
      mTabIndicator.get(1).setIconAlpha(1.0f);
      mViewPager.setCurrentItem(1, false);
      break;
    case R.id.id_indicator_three:
      mTabIndicator.get(2).setIconAlpha(1.0f);
      mViewPager.setCurrentItem(2, false);
      mAppContext.has_new_talk = false;

      break;
    case R.id.id_indicator_four:
      mTabIndicator.get(3).setIconAlpha(1.0f);
      mViewPager.setCurrentItem(3, false);
      break;

    }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android仿微信底部菜单栏功能显示未读消息数量

    底部菜单栏很重要,我看了一下很多应用软件都是用了底部菜单栏,这里使用了tabhost做了一种通用的(就是可以像微信那样显示未读消息数量的,虽然之前也做过但是layout下的xml写的太臃肿,这里去掉了很多不必要的层,个人看起来还是不错的,所以贴出来方便以后使用). 先看一下做出来之后的效果: 以后使用的时候就可以换成自己项目的图片和字体了,主框架不用变哈哈, 首先是要布局layout下xml文件 main.xml: <?xml version="1.0" encoding=&qu

  • android 中viewpager+fragment仿微信底部TAG完美渐变

    viewpager+fragment仿微信底部TAG完美渐变,在图片渐变的同时字的颜色也在变,注意,是渐变哦! 效果图: activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:zhy="http://schemas.android.com/apk/res/com.Sing.weixin" xmlns:tools="

  • Android开发之微信底部菜单栏实现的几种方法汇总

     实现方式 实现的方式有很多种 这里总结最常见的几种方式,以后再添加其他的. viewPager + RadioGroup viewPager + FragmentTabHost viewpager +TabLayout viewPager+RadioGroup 感觉这是最简单的一个了,我也就不贴代码 说说我理解的思路吧 通过给pager 和RadioGroup 添加监听,监听两个控件的变化 实现联动 当viewPager的显示pager改变就会触发监听 ,在监听中选中对应的RadioButto

  • Android仿微信底部实现Tab选项卡切换效果

    在网上看了比较多的关于Tab的教程,发现都很杂乱.比较多的用法是用TitlePagerTabStrip和ViewPaper.不过TitlePagerTabStrip有个很大的缺陷,Tab里面的内容刚进去是没有的,要滑一次才能加载出来.而且滑动的时候,Tab里面的内容位置不是固定的,滑倒最后会出现一片空白,非常不美观.虽然有其他的补救方法,但是非常的麻烦,所以我就按照自己的方法实现了一个,功能不错而且非常简单. 直接点击或者是滑动界面,都可以转到相应的页面. 效果图: 原理是用了三个按钮和View

  • Android仿微信底部按钮滑动变色

    Android仿微信底部按钮滑动变色,这里只针对使用Fragment为Tab页的滑动操作,进行简单的变色讲解. 首先说下OnPageChangeListener这个监听 //这个监听有三个方法 public abstract void onPageScrollStateChanged (int state) public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixe

  • Android 仿微信底部渐变Tab效果

    先来看一下效果图 除了第三个的发现Tab有所差别外,其他的基本还原了微信的底部Tab渐变效果 每个Tab都是一个自定义View,根据ImageView的tint属性来实现颜色渐变效果,tint属性的使用可以看我的上一篇文章 我将自定义View命名为ShadeView,包含四个自定义属性 意思分别为图标.背景色.底部文本.底部文本大小 <declare-styleable name="ShadeView"> <attr name="icon" for

  • Android仿微信底部菜单栏效果

    前言 在市面上,大多数的APP都需要通过底部菜单栏来将程序的功能进行分类整理,通常都是分为3-5个大模块,从而正确有效地引导用户去使用我们的APP.实现底部菜单栏的方法也有很多种. 1.仿微信底部菜单栏(ViewPager+ImagerView+TextView) ......(其他方式后续会补充) 效果预览 首先来个开胃菜,看看实现效果: 先贴出项目所需的资源文件,这些可随个人自由更改颜色和文字 colors.xml <color name="bg_line_light_gray&quo

  • Android仿微信5实现滑动导航条

    本文实例为大家分享了Android 仿微信5滑动导航效果,供大家参考,具体内容如下 ViewPageAdapter.java package com.rong; import java.util.ArrayList; import java.util.List; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; publi

  • Android仿微信对话列表滑动删除效果

    微信对话列表滑动删除效果很不错的,借鉴了github上SwipeListView(项目地址:https://github.com/likebamboo/SwipeListView),在其上进行了一些重构,最终实现了微信对话列表滑动删除效果. 实现原理  1.通过ListView的pointToPosition(int x, int y)来获取按下的position,然后通过android.view.ViewGroup.getChildAt(position)来得到滑动对象swipeView  2

  • Android仿微信实现下拉列表

    本文要实现微信6.1中点击顶部菜单栏的"+"号按钮时,会弹出一个列表框.这里用的了Activity实现,其实最好的方法可以用ActionBar,不过这货好像只支持3.0以后的版本.本文的接上文Android仿微信底部菜单栏+顶部菜单栏. 效果 一.仿微信下拉列表布局pop_dialog.xml <?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android

  • Android仿微信之界面导航篇(1)

    微信是现在比较流行的应用了,在各大安卓市场几乎都是名列前茅了. 说实话不得不羡慕腾讯庞大的用户群体,只要腾讯敢做,就会有很多人去用. 废话不多说,下面就开始说一下如何实现微信的第一次启动程序的用户导航,ViewPager相信大家都不陌生了,是google放出的一个安卓低版本的兼容包android-support-v4.jar,里面有很多类我们可以去使用.那这个导航就是使用这个类来辅助完成的,在每一个View里放置一个图片,当我们使用ViewPager滑动界面的时候,就会看到一张张图片,从而实现这

  • Android仿微信长按菜单效果

    本文实例为大家分享了Android仿微信长按菜单展示的具体代码,供大家参考,具体内容如下 FloatMenu A menu style pop-up window that mimics WeChat.仿微信的长按菜单. 效果如下 引入方法: Github地址:https://github.com/JavaNoober/FloatMenu dependencies { .... compile 'com.noober.floatmenu:common:1.0.2' } 使用说明 使用方法1: A

随机推荐