先来张图

 

菜单文件:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >

    <item
        android:id="@+id/action_search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/actionbar_search_icon"
        android:showAsAction="ifRoom|collapseActionView"
        android:title="@string/action_search"/>
 
    <item
        android:id="@+id/action_scan"
        android:icon="@drawable/ic_menu1"
        android:title="@string/menu_scan"/>
    <item
        android:id="@+id/action_group"
        android:icon="@drawable/ic_menu2"
        android:title="@string/menu_group"/>
    <item
        android:id="@+id/action_add_friend"
        android:icon="@drawable/ic_menu3"
        android:title="@string/menu_feedback"/>
    <item
        android:id="@+id/action_feedback"
        android:icon="@drawable/ic_menu4"
        android:title="@string/menu_addfriend"/>

</menu>

 

// 设置ActionBar Icon图标不显示
getActionBar().setDisplayShowHomeEnabled(false);
// 如果ActionBar右边的设置图标不显示,可以通过以下方法设置
private void setOverflowButtonAlways() {
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKey = ViewConfiguration.class
                    .getDeclaredField("sHasPermanentMenuKey");
        menuKey.setAccessible(true);
        menuKey.setBoolean(config, false);
    } catch (Exception e) {
            e.printStackTrace();
    }
}

菜单中icon图标默认是不显示的,像这样:

可以通过在Activity中覆盖以下方法设置:

@Override
public boolean onMenuOpened(int featureId, Menu menu) {
    if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
        if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
            try {
                Method method = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                method.setAccessible(true);
                method.invoke(menu, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    return super.onMenuOpened(featureId, menu);
}

效果如下:

 

以上是ActionBar。下面来看底部的几个按钮:

xml文件里面就是一个LinearLayout包裹了四个一样的自定义控件,为了方便,我这里只贴出一个,完整的请查看源码

<com.example.weixin.ChangeColorText
  android:id="@+id/id_indicator_one"
  android:padding="5dp"
  android:layout_width="0dp"
  android:layout_height
="match_parent"   android:layout_weight="1"   hzx:icon="@drawable/ic_menu_start_conversation"   hzx:text="@string/tab_contact"   hzx:textSize="12sp"   hzx:color="#ff45c01a" />

这个控件使用了四个自定义属性,attr文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="icon" format="reference"></attr>
    <attr name="color" format="color"></attr>
    <attr name="text" format="string"></attr>
    <attr name="textSize" format="dimension"></attr>

    <declare-styleable name="ChangeColorText">
        <attr name="icon" />
        <attr name="color"/>
        <attr name="text" />
        <attr name="textSize" />
    </declare-styleable>
</resources>

 

ChangeColorTex类如下:

 1 public class ChangeColorText extends View {
 2 
 3     int mColor = 0xFF45C01A;
 4     String mText = "微信";
 5     int mTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
 6             12, getResources().getDisplayMetrics());
 7 
 8     Canvas mCanvas;
 9     Bitmap mBitmap;
10     Paint mPaint;
11     Bitmap mIconBitma;
12 
13     float mAlpha;
14     Rect mIconRect;
15     Rect mTextBound;
16 
17     Paint mTextPaint;
18 
19     public ChangeColorText(Context context) {
20         super(context);
21     }

 

以上是一些变量,关键的是下面这个构造方法:

 1   /**获取自定义属性的值*/
 2   public ChangeColorText(Context context, AttributeSet attrs) {
 3         super(context, attrs);
 4 
 5         TypedArray a = context.obtainStyledAttributes(attrs,
 6                 R.styleable.ChangeColorText);
 7 
 8         // 获取各个自定义属性的值
 9         int n = a.getIndexCount();
10         for (int i = 0; i < n; i++) {
11             int attr = a.getIndex(i);
12             switch (attr) {
13             case R.styleable.ChangeColorText_icon:
14                 BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(attr);
15                 mIconBitma = drawable.getBitmap();
16                 break;
17             case R.styleable.ChangeColorText_color:
18                 mColor = a.getColor(attr, 0xFF45C01A);
19                 break;
20             case R.styleable.ChangeColorText_text:
21                 mText = a.getString(attr);
22                 break;
23 
24             case R.styleable.ChangeColorText_textSize:
25                 mTextSize = (int) a.getDimension(attr, TypedValue
26                         .applyDimension(TypedValue.COMPLEX_UNIT_SP, 12,
27                                 getResources().getDisplayMetrics()));
28                 break;
29             default:
30                 break;
31             }
32         }
33 
34         a.recycle(); // 这里一定要回收掉
35 
36         // 初始化一些变量
37         mTextBound = new Rect();
38         mTextPaint = new Paint();
39         mTextPaint.setTextSize(mTextSize);
40         mTextPaint.setColor(0xff555555);
41 
42         mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBound);
43     }

 

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 测量图标的宽高 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int iconWidth = Math.min(getMeasuredWidth() - getPaddingLeft()
                - getPaddingRight(), getMeasuredHeight() - getPaddingTop()
                - getPaddingBottom() - mTextBound.height());

        int left = getMeasuredWidth() / 2 - iconWidth / 2;
        int top = (getMeasuredHeight() - mTextBound.height()) / 2 - iconWidth
                / 2;
        mIconRect = new Rect(left, top, left + iconWidth, top + iconWidth);
    }
  @Override
    protected void onDraw(Canvas canvas) {
        // 绘制控件
        canvas.drawBitmap(mIconBitma, null, mIconRect,null);
        
        int alpha = (int) Math.ceil(255 * mAlpha);
        
        // 1、内存去准备mBitmap , setAlpha , 纯色 ,xfermode , 图标
        setUpTargetBitmap(alpha);
         
        // 2、绘制原文本
        drawSourceText(canvas,alpha);
        // 3、绘制变色的文本
        drawTargetText(canvas,alpha);
         
         
        canvas.drawBitmap(mBitmap, 0, 0,null);
    }
    /** 在内存中绘制可变色的Icon */
    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(mIconBitma, null, mIconRect,mPaint);
    }
    /**  绘制变色的文本*/
    private void drawTargetText(Canvas canvas, int alpha) {
        mTextPaint.setColor(mColor);
        mTextPaint.setAlpha(alpha);
        
        int x = getMeasuredWidth()/2 - mTextBound.width()/2;
        int y = mIconRect.bottom + mTextBound.height();
        canvas.drawText(mText,x , y, mTextPaint);
    }
    /**绘制原文本*/
    private void drawSourceText(Canvas canvas, int alpha) {
        mTextPaint.setColor(0xff333333);
        mTextPaint.setAlpha(255);
        int x = getMeasuredWidth()/2 - mTextBound.width()/2;
        int y = mIconRect.bottom + mTextBound.height();
        canvas.drawText(mText,x , y, mTextPaint);
    }

 

以下两个方法用来保存当屏幕横竖屏切换时当前View的状态:

    private static final String INSTANCE_STATUS = "instance_status";
    private static final String STATUS_ALPHA = "status_alpha";
    
    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(INSTANCE_STATUS, super.onSaveInstanceState());
        bundle.putFloat(STATUS_ALPHA, mAlpha);
        return bundle;
    }
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            mAlpha = bundle.getFloat(STATUS_ALPHA);
            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATUS));
            return;
        }
        super.onRestoreInstanceState(state);
    }

提供一个public方法用来改变View的颜色深度:

    public void setIconAlpha(float alpha){
        this.mAlpha = alpha;
        invalidateView();
    }
    /** 重绘 */
    private void invalidateView() {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            invalidate();
        }else {
            postInvalidate();
        }
    }

到这自定义View就写完了。

 

最后Activity里面设置mViewPager.setOnPageChangeListener(this);在OnPageChangeListener的onPageScrolled中

调用setIconAlpha(float alpha)方法:

  // 以下代码是切换Fragment中View的透明度,不需要可以注释掉
  @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (positionOffset > 0) { ChangeColorText left = mTabIndicators.get(position); ChangeColorText right = mTabIndicators.get(position + 1); left.setIconAlpha(1 - positionOffset); right.setIconAlpha(positionOffset); mTabs.get(position).getView().setAlpha(1 - positionOffset); mTabs.get(position + 1).getView().setAlpha(positionOffset); } }

 

感谢您的阅读

源码下载

 

posted on 2015-04-14 19:37  道无涯  阅读(1694)  评论(0编辑  收藏  举报