欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 微信6.1 tab欄圖標和字體顏色漸變的實現

 更新時間:2016年12月28日 10:23:11   作者:鐘光燕  
本文主要對微信6.1 tab 欄顏色漸變效果的實現全過程進行分析介紹,具有很好的參考價值,下面跟著小編一起來看下吧

相信大家都見到了微信圖標顏色漸變的過程,是不是感覺很牛?不得不說微信團隊確實是很厲害的團隊,不管是從設計還是開發(fā)人員。

今天我?guī)Т蠹襾砜纯?,微?tab 欄圖標和字體顏色漸變的過程。先上圖吧!今天學了一招制作 gif 動態(tài)圖的快捷方法。剛好用的上,以前一直想寫點什么東西,

苦于一直不知道怎么生成動態(tài)圖,現在終于學會了,哈哈,讓我偷偷的樂一會。額,還是上圖吧。。。

好了,效果圖也看到了,那么我也就不多啰嗦了,直接進入主題,看代碼

[java] view plain copy
package moon.wechat.view; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.TypedValue; 
import android.view.View; 
/** 
 * Created by moon.zhong on 2015/2/4. 
 */ 
public class TabItem extends View { 
  /*字體大小*/ 
  private int mTextSize ; 
  /*字體選中的顏色*/ 
  private int mTextColorSelect ; 
  /*字體未選擇的時候的顏色*/ 
  private int mTextColorNormal; 
  /*繪制未選中時字體的畫筆*/ 
  private Paint mTextPaintNormal; 
  /*繪制已選中時字體的畫筆*/ 
  private Paint mTextPaintSelect; 
  /*每個 item 的寬和高,包括字體和圖標一起*/ 
  private int mViewHeight, mViewWidth; 
  /*字體的內容*/ 
  private String mTextValue ; 
  /*已選中時的圖標*/ 
  private Bitmap mIconNormal; 
  /*未選中時的圖標*/ 
  private Bitmap mIconSelect; 
  /*用于記錄字體大小*/ 
  private Rect mBoundText; 
  /*已選中是圖標的畫筆*/ 
  private Paint mIconPaintSelect; 
  /*為選中時圖標的畫筆*/ 
  private Paint mIconPaintNormal; 
  public TabItem(Context context) { 
    this(context, null); 
  } 
  public TabItem(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
  } 
  public TabItem(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initView(); 
    initText(); 
  } 
  /*初始化一些東西*/ 
  private void initView() { 
    mBoundText = new Rect(); 
  } 
  /*初始化畫筆,并設置出是內容*/ 
  private void initText() { 
    mTextPaintNormal = new Paint(); 
    mTextPaintNormal.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, getResources().getDisplayMetrics())); 
    mTextPaintNormal.setColor(mTextColorNormal); 
    mTextPaintNormal.setAntiAlias(true); 
    mTextPaintNormal.setAlpha(0xff); 
    mTextPaintSelect = new Paint(); 
    mTextPaintSelect.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, getResources().getDisplayMetrics())); 
    mTextPaintSelect.setColor(mTextColorSelect); 
    mTextPaintSelect.setAntiAlias(true); 
    mTextPaintSelect.setAlpha(0); 
    mIconPaintSelect = new Paint(Paint.ANTI_ALIAS_FLAG) ; 
    mIconPaintSelect.setAlpha(0); 
    mIconPaintNormal = new Paint(Paint.ANTI_ALIAS_FLAG) ; 
    mIconPaintNormal.setAlpha(0xff); 
  } 
  /*測量字體的大小*/ 
  private void measureText() { 
    mTextPaintNormal.getTextBounds(mTextValue, 0, mTextValue.length(), mBoundText); 
  } 
  /*測量字體和圖標的大小,并設置自身的寬和高*/ 
  @Override 
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 
    int width = 0, height = 0; 
    measureText(); 
    int contentWidth = Math.max(mBoundText.width(), mIconNormal.getWidth()); 
    int desiredWidth = getPaddingLeft() + getPaddingRight() + contentWidth; 
    switch (widthMode) { 
      case MeasureSpec.AT_MOST: 
        width = Math.min(widthSize, desiredWidth); 
        break; 
      case MeasureSpec.EXACTLY: 
        width = widthSize; 
        break; 
      case MeasureSpec.UNSPECIFIED: 
        width = desiredWidth; 
        break; 
    } 
    int contentHeight = mBoundText.height() + mIconNormal.getHeight(); 
    int desiredHeight = getPaddingTop() + getPaddingBottom() + contentHeight; 
    switch (heightMode) { 
      case MeasureSpec.AT_MOST: 
        height = Math.min(heightSize, desiredHeight); 
        break; 
      case MeasureSpec.EXACTLY: 
        height = heightSize; 
        break; 
      case MeasureSpec.UNSPECIFIED: 
        height = contentHeight; 
        break; 
    } 
    setMeasuredDimension(width, height); 
    mViewWidth = getMeasuredWidth() ; 
    mViewHeight = getMeasuredHeight() ; 
  } 
  @Override 
  protected void onDraw(Canvas canvas) { 
    drawBitmap(canvas) ; 
    drawText(canvas) ; 
  } 
  /*話圖標,先畫為選中的圖標,在畫已選中的圖標*/ 
  private void drawBitmap(Canvas canvas) { 
    int left = (mViewWidth - mIconNormal.getWidth())/2 ; 
    int top = (mViewHeight - mIconNormal.getHeight() - mBoundText.height()) /2 ; 
    canvas.drawBitmap(mIconNormal, left, top ,mIconPaintNormal); 
    canvas.drawBitmap(mIconSelect, left, top , mIconPaintSelect); 
  } 
  /*畫字體*/ 
  private void drawText(Canvas canvas) { 
    float x = (mViewWidth - mBoundText.width())/2.0f ; 
    float y = (mViewHeight + mIconNormal.getHeight() + mBoundText.height()) /2.0F ; 
    canvas.drawText(mTextValue,x,y, mTextPaintNormal); 
    canvas.drawText(mTextValue,x,y, mTextPaintSelect); 
  } 
  public void setTextSize(int textSize) { 
    this.mTextSize = textSize; 
    mTextPaintNormal.setTextSize(textSize); 
    mTextPaintSelect.setTextSize(textSize); 
  } 
  public void setTextColorSelect(int mTextColorSelect) { 
    this.mTextColorSelect = mTextColorSelect; 
    mTextPaintSelect.setColor(mTextColorSelect); 
    mTextPaintSelect.setAlpha(0); 
  } 
  public void setTextColorNormal(int mTextColorNormal) { 
    this.mTextColorNormal = mTextColorNormal; 
    mTextPaintNormal.setColor(mTextColorNormal); 
    mTextPaintNormal.setAlpha(0xff); 
  } 
  public void setTextValue(String TextValue) { 
    this.mTextValue = TextValue; 
  } 
  public void setIconText(int[] iconSelId,String TextValue) { 
    this.mIconSelect = BitmapFactory.decodeResource(getResources(), iconSelId[0]); 
    this.mIconNormal = BitmapFactory.decodeResource(getResources(), iconSelId[1]); 
    this.mTextValue = TextValue; 
  } 
  /*通過 alpha 來設置 每個畫筆的透明度,從而實現現實的效果*/ 
  public void setTabAlpha(float alpha){ 
    int paintAlpha = (int)(alpha*255) ; 
    mIconPaintSelect.setAlpha(paintAlpha); 
    mIconPaintNormal.setAlpha(255-paintAlpha); 
    mTextPaintSelect.setAlpha(paintAlpha); 
    mTextPaintNormal.setAlpha(255-paintAlpha); 
    invalidate(); 
  } 
} 

分析: 以上代碼,功能實現 tab 的每個 item 的內容,在微信的項目中也就是,一個圖標加一個字體,

關鍵代碼就在public void setTabAlpha(float alpha) 這個方法,此方法是 viewPager 切換 item 時,不斷改變偏移量來調用,從而不斷改變

每個畫筆的透明度,實現圖標和顏色的漸變;是不是很簡單?到這里其實我們顏色漸變的代碼就已經實現了。接下來的內容可以忽略

這樣我們只需要在 MainActivity 的 xml 中定義一個線性布局,然后放如四個我們自定義的 View 進去,就可以了。但是這樣你就滿足了嗎?

我先來給你們看看我的MainActivity的代碼;

[java] view plain copy
package moon.wechat; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import java.util.HashMap; 
import java.util.Map; 
import moon.wechat.view.TabView; 
public class MainActivity extends ActionBarActivity { 
  private String[] mTitle = {"微信", "通訊錄", "發(fā)現", "我"}; 
  private int[] mIconSelect = {R.drawable.al_, R.drawable.al8, R.drawable.alb, R.drawable.ald}; 
  private int[] mIconNormal = {R.drawable.ala, R.drawable.al9, R.drawable.alc, R.drawable.ale}; 
  private ViewPager mViewPager ; 
  private TabView mTabView ; 
  private Map<Integer,Fragment> mFragmentMap ; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    mFragmentMap = new HashMap<>() ; 
    mViewPager = (ViewPager)findViewById(R.id.id_view_pager) ; 
    mViewPager.setOffscreenPageLimit(4); 
    mViewPager.setAdapter(new PageAdapter(getSupportFragmentManager())); 
    mTabView = (TabView)findViewById(R.id.id_tab) ; 
    mTabView.setViewPager(mViewPager); 
  } 
  private Fragment getFragment(int position){ 
    Fragment fragment = mFragmentMap.get(position) ; 
    if(fragment == null){ 
      switch (position){ 
        case 0: 
          fragment = new WeChatFragment() ; 
          break ; 
        case 1: 
          fragment = new WeContactFragment(); 
          break ; 
        case 2: 
          fragment = new WeDiscoverFragment(); 
          break; 
        case 3: 
          fragment = new GameFragment() ; 
//          fragment = new WeMineFragment(); 
          break; 
      } 
      mFragmentMap.put(position,fragment) ; 
    } 
    return fragment ; 
  } 
  class PageAdapter extends FragmentPagerAdapter implements TabView.OnItemIconTextSelectListener{ 
    public PageAdapter(FragmentManager fm) { 
      super(fm); 
    } 
    @Override 
    public Fragment getItem(int position) { 
      return getFragment(position); 
    } 
    @Override 
    public int[] onIconSelect(int position) { 
      int icon[] = new int[2] ; 
      icon[0] = mIconSelect[position] ; 
      icon[1] = mIconNormal[position] ; 
      return icon; 
    } 
    @Override 
    public String onTextSelect(int position) { 
      return mTitle[position]; 
    } 
    @Override 
    public int getCount() { 
      return mTitle.length; 
    } 
  } 
} 

是不是很簡單,而 xml 更簡單

[html] view plain copy
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:zgy="http://schemas.android.com/apk/res-auto" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:background="@android:color/white" 
  android:orientation="vertical"> 
  <android.support.v4.view.ViewPager 
    android:id="@+id/id_view_pager" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    > 
    </android.support.v4.view.ViewPager> 
  <moon.wechat.view.TabView 
    android:id="@+id/id_tab" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:background="#eeeeee" 
    zgy:text_size="12sp" 
    zgy:text_normal_color="#ff777777" 
    zgy:text_select_color="#ff45c01a" 
    zgy:item_padding="7dp"> 
   </moon.wechat.view.TabView> 
</LinearLayout> 

可以看到沒有定義我們剛剛自定義的 TabItem,而是使用的 TabView,那 TabView 到底是啥東西?相信大家都想到了,TabView 其實就是我們自定義的線性布局,

[java] view plain copy
package moon.wechat.view; 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.support.v4.view.PagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.util.TypedValue; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.LinearLayout; 
import java.util.ArrayList; 
import java.util.List; 
import moon.wechat.R; 
/** 
 * Created by moon.zhong on 2015/2/4. 
 */ 
public class TabView extends LinearLayout implements View.OnClickListener { 
  private ViewPager mViewPager; 
  private ViewPager.OnPageChangeListener mOnPageChangeListener; 
  private PagerAdapter mPagerAdapter; 
  private int mChildSize; 
  private List<TabItem> mTabItems; 
  private OnItemIconTextSelectListener mListener; 
  private int mTextSize = 12; 
  private int mTextColorSelect = 0xff45c01a; 
  private int mTextColorNormal = 0xff777777; 
  private int mPadding = 10; 
  public TabView(Context context) { 
    this(context, null); 
  } 
  public TabView(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
  } 
  public TabView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    TypedArray typedArray = getResources().obtainAttributes(attrs, R.styleable.TabView); 
    int N = typedArray.getIndexCount(); 
    for (int i = 0; i < N; i++) { 
      switch (typedArray.getIndex(i)) { 
        case R.styleable.TabView_text_size: 
          mTextSize = (int) typedArray.getDimension(i, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 
              mTextSize, getResources().getDisplayMetrics())); 
          break; 
        case R.styleable.TabView_text_normal_color: 
          mTextColorNormal = typedArray.getColor(i, mTextColorNormal); 
          break; 
        case R.styleable.TabView_text_select_color: 
          mTextColorSelect = typedArray.getColor(i, mTextColorSelect); 
          break; 
        case R.styleable.TabView_item_padding: 
          mPadding = (int) typedArray.getDimension(i, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
              mPadding, getResources().getDisplayMetrics())); 
          break; 
      } 
    } 
    typedArray.recycle(); 
    mTabItems = new ArrayList<>(); 
  } 
  public void setViewPager(final ViewPager mViewPager) { 
    if (mViewPager == null) { 
      return; 
    } 
    this.mViewPager = mViewPager; 
    this.mPagerAdapter = mViewPager.getAdapter(); 
    if (this.mPagerAdapter == null) { 
      throw new RuntimeException("親,在您設置TabView的ViewPager時,請先設置ViewPager的PagerAdapter"); 
    } 
    this.mChildSize = this.mPagerAdapter.getCount(); 
    this.mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
//        Log.v("zgy","=============position="+position+",====positionOffset="+positionOffset) ; 
        View leftView; 
        View rightView; 
        if (positionOffset > 0) { 
          leftView = mViewPager.getChildAt(position); 
          rightView = mViewPager.getChildAt(position + 1); 
          leftView.setAlpha(1 - positionOffset); 
          rightView.setAlpha(positionOffset); 
          mTabItems.get(position).setTabAlpha(1 - positionOffset); 
          mTabItems.get(position + 1).setTabAlpha(positionOffset); 
        } else { 
          mViewPager.getChildAt(position).setAlpha(1); 
          mTabItems.get(position).setTabAlpha(1 - positionOffset); 
        } 
        if (mOnPageChangeListener != null) { 
mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 
        } 
      } 
      @Override 
      public void onPageSelected(int position) { 
        if (mOnPageChangeListener != null) { 
mOnPageChangeListener.onPageSelected(position); 
        } 
      } 
      @Override 
      public void onPageScrollStateChanged(int state) { 
        if (mOnPageChangeListener != null) { 
mOnPageChangeListener.onPageScrollStateChanged(state); 
        } 
      } 
    }); 
    if (mPagerAdapter instanceof OnItemIconTextSelectListener) { 
      mListener = (OnItemIconTextSelectListener) mPagerAdapter; 
    }else { 
      throw new RuntimeException("請讓你的pageAdapter實現OnItemIconTextSelectListener接口"); 
    } 
    initItem(); 
  } 
  public void setOnPageChangeListener(ViewPager.OnPageChangeListener mOnPageChangeListener) { 
    this.mOnPageChangeListener = mOnPageChangeListener; 
  } 
  private void initItem() { 
    for (int i = 0; i < mChildSize; i++) { 
      TabItem tabItem = new TabItem(getContext()); 
      LayoutParams params = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1); 
      tabItem.setPadding(mPadding, mPadding, mPadding, mPadding); 
      tabItem.setIconText(mListener.onIconSelect(i), mListener.onTextSelect(i)); 
      tabItem.setTextSize(mTextSize); 
      tabItem.setTextColorNormal(mTextColorNormal); 
      tabItem.setTextColorSelect(mTextColorSelect); 
      tabItem.setLayoutParams(params); 
      tabItem.setTag(i); 
      tabItem.setOnClickListener(this); 
      mTabItems.add(tabItem); 
      addView(tabItem); 
    } 
  } 
  @Override 
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
  } 
  @Override 
  public void onClick(View v) { 
    int position = (Integer) v.getTag(); 
    if (mViewPager.getCurrentItem() == position) { 
      return; 
    } 
    for (TabItem tabItem : mTabItems) { 
      tabItem.setTabAlpha(0); 
    } 
    mTabItems.get(position).setTabAlpha(1); 
    mViewPager.setCurrentItem(position, false); 
  } 
  public interface OnItemIconTextSelectListener { 
    int[] onIconSelect(int position); 
    String onTextSelect(int position); 
  } 
} 

注釋有點少,額,不是少,是壓根就沒有,其實,這個類的代碼不需要注釋,我相信大家都能看懂,我就講下他的作用吧,

  1. 添加 item
  2. 監(jiān)聽 ViewPager 的滾動事件,從而設置相應 item 之間的顏色漸變,
  3. 設置相應 ViewPage 的透明度
  4. 為 TabItem 設置監(jiān)聽事件,

其實上面很多功能本來是在 MainActivity 中實現的,為了減少 Activity 內部的代碼量,抽取出來,到達低耦合,高內聚的效果。

Ok,以上就是 微信6.1 tab 欄顏色漸變效果的實現全過程。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關文章

  • 微信舉報解除和微信解除限制的6個方法

    微信舉報解除和微信解除限制的6個方法

    本文主要介紹微信被舉報怎么解除?微信解除限制,這里整理了6種方法,有需要的小伙伴可以參考下
    2016-09-09
  • Android編程Widget創(chuàng)建與使用方法簡明教程

    Android編程Widget創(chuàng)建與使用方法簡明教程

    這篇文章主要介紹了Android編程Widget創(chuàng)建與使用方法,結合實例形式分析了Widget的功能、使用方法與相關注意事項,需要的朋友可以參考下
    2016-10-10
  • 三款Android炫酷Loading動畫組件推薦

    三款Android炫酷Loading動畫組件推薦

    這篇文章主要介紹了三款Android炫酷Loading動畫組件推薦,本文介紹了CircleProgress、android-shapeLoadingView、WaitingDots等三款Loading組件,并給出了運行效果圖,需要的朋友可以參考下
    2015-05-05
  • 基于TransactionTooLargeException異常分析

    基于TransactionTooLargeException異常分析

    下面小編就為大家分享一篇基于TransactionTooLargeException異常分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • Android升級gradle 后引入aar包報錯解決

    Android升級gradle 后引入aar包報錯解決

    這篇文章主要為大家介紹了Android升級gradle 后引入aar包報錯解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Android開發(fā)Jetpack組件Lifecycle使用篇

    Android開發(fā)Jetpack組件Lifecycle使用篇

    這一篇文章來介紹Android?Jetpack架構組件的Lifecycle;?Lifecycle用于幫助開發(fā)者管理Activity和Fragment?的生命周期,?由于Lifecycle是LiveData和ViewModel的基礎;所以需要先學習它
    2022-08-08
  • Android自定義帶動畫效果的圓形ProgressBar

    Android自定義帶動畫效果的圓形ProgressBar

    這篇文章主要為大家詳細介紹了Android自定義帶動畫效果的圓形ProgressBar,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Android使用Intent傳大數據簡單實現詳解

    Android使用Intent傳大數據簡單實現詳解

    這篇文章主要為大家介紹了Android使用Intent傳大數據簡單實現詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 詳解Android中Handler的實現原理

    詳解Android中Handler的實現原理

    這篇文章主要為大家詳細介紹了Android中Handler的實現原理,本文深入分析 Android 的消息處理機制,了解 Handler 的工作原理,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Android自定義軟鍵盤的步驟記錄

    Android自定義軟鍵盤的步驟記錄

    Android軟鍵盤這塊從我入職到現在,是一個一直糾纏我的問題,這篇文章主要給大家介紹了關于Android自定義軟鍵盤的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08

最新評論