主要是提供一种思路,一般来书,类似效果无非就是在Canvas,Paint,Drawable等绘图类里搞来搞去。如果对绘图类比较熟悉的话,基本就没问题了,尤其游戏开发者。
我是记录一下,以后可以照抄了,具体见原帖:
http://blog.csdn.net/lmj623565791/article/details/41087219

 
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.Log; 
import android.util.TypedValue; 
import android.view.View; 
 
public class ChangeColorIconWithTextView extends View { 
 
	private Bitmap mBitmap; 
	private Canvas mCanvas; 
	private Paint mPaint; 
	/** 
	 * 选中的颜色 
	 */ 
	private int mColor = 0xFFFF0000; 
	/** 
	 * 透明度 0.0-1.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, 12, 
			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, 0x45C01A); 
				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(0xff555555); 
		// 得到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); 
	} 
 
	private void drawSourceText(Canvas canvas, int alpha) { 
		mTextPaint.setTextSize(mTextSize); 
		mTextPaint.setColor(0xff333333); 
		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); 
		} 
 
	} 
 
} 

自定义属性:
 
<?xml version="1.0" encoding="utf-8"?> 
<resources> 
 
    <attr name="icon" format="reference" /> 
    <attr name="color" format="color" /> 
    <attr name="text" format="string" /> 
    <attr name="text_size" format="dimension" /> 
 
    <declare-styleable name="ChangeColorIconView"> 
        <attr name="icon" /> 
        <attr name="color" /> 
        <attr name="text" /> 
        <attr name="text_size" /> 
    </declare-styleable> 
 
</resources> 



使用:
 
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.List; 
 
import android.annotation.SuppressLint; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.support.v4.view.ViewPager.OnPageChangeListener; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewConfiguration; 
import android.view.Window; 
 
@SuppressLint("NewApi") 
public class MainActivity extends FragmentActivity implements 
		OnPageChangeListener, OnClickListener 
{ 
	private ViewPager mViewPager; 
	private List<Fragment> mTabs = new ArrayList<Fragment>(); 
	private FragmentPagerAdapter mAdapter; 
 
	private String[] mTitles = new String[] { "First Fragment!", 
			"Second Fragment!", "Third Fragment!", "Fourth Fragment!" }; 
 
	private List<ChangeColorIconWithTextView> mTabIndicator = new ArrayList<ChangeColorIconWithTextView>(); 
 
	@Override 
	protected void onCreate(Bundle savedInstanceState) 
	{ 
		super.onCreate(savedInstanceState); 
		setContentView(R.layout.activity_main); 
 
		setOverflowShowingAlways(); 
		getActionBar().setDisplayShowHomeEnabled(false); 
		mViewPager = (ViewPager) findViewById(R.id.id_viewpager); 
 
		initDatas(); 
 
		mViewPager.setAdapter(mAdapter); 
		mViewPager.setOnPageChangeListener(this); 
	} 
 
	private void initDatas() 
	{ 
 
		for (String title : mTitles) 
		{ 
			TabFragment tabFragment = new TabFragment(); 
			Bundle args = new Bundle(); 
			args.putString("title", title); 
			tabFragment.setArguments(args); 
			mTabs.add(tabFragment); 
		} 
 
		mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) 
		{ 
 
			@Override 
			public int getCount() 
			{ 
				return mTabs.size(); 
			} 
 
			@Override 
			public Fragment getItem(int arg0) 
			{ 
				return mTabs.get(arg0); 
			} 
		}; 
 
		initTabIndicator(); 
 
	} 
 
	@Override 
	public boolean onCreateOptionsMenu(Menu menu) 
	{ 
		getMenuInflater().inflate(R.menu.main, menu); 
		return true; 
	} 
 
	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 onPageSelected(int arg0) 
	{ 
	} 
 
	@Override 
	public void onPageScrolled(int position, float positionOffset, 
			int positionOffsetPixels) 
	{ 
		// Log.e("TAG", "position = " + position + " , positionOffset = " 
		// + positionOffset); 
 
		if (positionOffset > 0) 
		{ 
			ChangeColorIconWithTextView left = mTabIndicator.get(position); 
			ChangeColorIconWithTextView right = mTabIndicator.get(position + 1); 
 
			left.setIconAlpha(1 - positionOffset); 
			right.setIconAlpha(positionOffset); 
		} 
 
	} 
 
	@Override 
	public void onPageScrollStateChanged(int state) 
	{ 
 
	} 
 
	@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); 
			break; 
		case R.id.id_indicator_four: 
			mTabIndicator.get(3).setIconAlpha(1.0f); 
			mViewPager.setCurrentItem(3, false); 
			break; 
 
		} 
 
	} 
 
	/** 
	 * 重置其他的Tab 
	 */ 
	private void resetOtherTabs() 
	{ 
		for (int i = 0; i < mTabIndicator.size(); i++) 
		{ 
			mTabIndicator.get(i).setIconAlpha(0); 
		} 
	} 
 
	@Override 
	public boolean onMenuOpened(int featureId, Menu menu) 
	{ 
		if (featureId == Window.FEATURE_ACTION_BAR && menu != null) 
		{ 
			if (menu.getClass().getSimpleName().equals("MenuBuilder")) 
			{ 
				try 
				{ 
					Method m = menu.getClass().getDeclaredMethod( 
							"setOptionalIconsVisible", Boolean.TYPE); 
					m.setAccessible(true); 
					m.invoke(menu, true); 
				} catch (Exception e) 
				{ 
				} 
			} 
		} 
		return super.onMenuOpened(featureId, menu); 
	} 
 
	private void setOverflowShowingAlways() 
	{ 
		try 
		{ 
			// true if a permanent menu key is present, false otherwise. 
			ViewConfiguration config = ViewConfiguration.get(this); 
			Field menuKeyField = ViewConfiguration.class 
					.getDeclaredField("sHasPermanentMenuKey"); 
			menuKeyField.setAccessible(true); 
			menuKeyField.setBoolean(config, false); 
		} catch (Exception e) 
		{ 
			e.printStackTrace(); 
		} 
	} 
 
} 


布局:
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.weixin6.ui" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
 
    <android.support.v4.view.ViewPager 
        android:id="@+id/id_viewpager" 
        android:layout_width="fill_parent" 
        android:layout_height="0dp" 
        android:layout_weight="1" > 
    </android.support.v4.view.ViewPager> 
 
    <LinearLayout 
        android:layout_width="fill_parent" 
        android:layout_height="60dp" 
        android:background="@drawable/tabbg" 
        android:orientation="horizontal" > 
 
        <com.zhy.weixin6.ui.ChangeColorIconWithTextView 
            android:id="@+id/id_indicator_one" 
            android:layout_width="0dp" 
            android:layout_height="fill_parent" 
            android:layout_weight="1" 
            android:padding="5dp" 
            zhy:icon="@drawable/ic_menu_start_conversation" 
            zhy:text="@string/tab_weixin" 
            zhy:text_size="12sp" /> 
 
        <com.zhy.weixin6.ui.ChangeColorIconWithTextView 
            android:id="@+id/id_indicator_two" 
            android:layout_width="0dp" 
            android:layout_height="fill_parent" 
            android:layout_weight="1" 
            android:padding="5dp" 
            zhy:icon="@drawable/ic_menu_friendslist" 
            zhy:text="@string/tab_contact" 
            zhy:text_size="12sp" /> 
 
        <com.zhy.weixin6.ui.ChangeColorIconWithTextView 
            android:id="@+id/id_indicator_three" 
            android:layout_width="0dp" 
            android:layout_height="fill_parent" 
            android:layout_weight="1" 
            android:padding="5dp" 
            zhy:icon="@drawable/ic_menu_emoticons" 
            zhy:text="@string/tab_find" 
            zhy:text_size="12sp" /> 
 
        <com.zhy.weixin6.ui.ChangeColorIconWithTextView 
            android:id="@+id/id_indicator_four" 
            android:layout_width="0dp" 
            android:layout_height="fill_parent" 
            android:layout_weight="1" 
            android:padding="5dp" 
            zhy:icon="@drawable/ic_menu_allfriends" 
            zhy:text="@string/tab_me" 
            zhy:text_size="12sp" /> 
    </LinearLayout> 
 
</LinearLayout> 


同样的效果:
http://www.open-open.com/lib/view/open1473666409185.html

一个优质的新闻客户端app
http://www.itlanbao.com/code/20151126/10000/100663.html
发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

把任意Drawable转换成基于progress填充的drawable详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。