欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

高仿微信6.0底部切換標(biāo)簽設(shè)置Alpha漸變效果解析 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識(shí)

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!

您當(dāng)前位置>首頁(yè) » 新聞資訊 » 技術(shù)分享 >

高仿微信6.0底部切換標(biāo)簽設(shè)置Alpha漸變效果解析

發(fā)表時(shí)間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):56


本文參考:【張鴻洋的博客】http://blog.csdn.net/lmj623565791/article/details/41087219
先上關(guān)鍵的代碼

<span style="color:#333333;">public class ChangeColorIconWithTextView extends View
{

	private Bitmap mBitmap;
	private Canvas mCanvas;
	private Paint mPaint;
	/**
	 * 色彩
	 */
	private int mColor = 0xFF45C01A;
	/**
	 * 透明度 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, 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);

		// 獲取設(shè)置的擱筆
		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:
				</span><span style="color:#ff0000;">//這個(gè)辦法是改變?yōu)闃?biāo)準(zhǔn)尺寸的一個(gè)函數(shù),這里COMPLEX_UNIT_SP是單位,10是數(shù)值,也就是10sp</span><span style="color:#333333;">
				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);
		</span><span style="color:#ff0000;">// 獲得text繪制范圍,設(shè)給這個(gè)mTextBound值,ps這個(gè)mTextPaint僅僅是通俗的Paint,然則傳了mText值獲得rect返回給mTextBound</span><span style="color:#333333;">
		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;
		// 設(shè)置icon的繪制范圍
		mIconRect = new Rect(left, top, left + bitmapWidth, top + bitmapWidth);

	}

	@Override
	protected void onDraw(Canvas canvas)
	{

		</span><span style="color:#ff0000;">//Round是四舍五入的。。。Ceil是向上取整。。float是向下取整</span><span style="color:#333333;">
		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);

	}
	
	</span><span style="color:#cc0000;">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);</span>
<span style="color:#cc0000;">		mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
		mPaint.setAlpha(255);
		mCanvas.drawBitmap(mIconBitmap, null, mIconRect, mPaint);
	}</span><span style="color:#333333;">

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

	}

}</span>

膳綾擎標(biāo)紅的處所是實(shí)現(xiàn)自定義控件實(shí)現(xiàn)漸變切換的關(guān)鍵代碼

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

這個(gè)辦法的

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

先繪制了須要漸變顯示的背景色彩,畫布mCanvas繪制了一個(gè)rect區(qū)域,這個(gè)區(qū)域設(shè)置了色彩,alpha值
然后

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

這里摘抄一段網(wǎng)上的解釋講解:
Adnroid上的簡(jiǎn)單圖像合成類——PorterDuffXfermode

圖像合成,是將兩幅退昂放在一路的動(dòng)作,它使得我們可以或許同時(shí)看到兩幅圖像的特點(diǎn)。
我們可以起首在Canvas對(duì)象上繪制一個(gè)位圖對(duì)象,然后再雷同的Canvas對(duì)象上繪制第二個(gè)位圖對(duì)象的方法來實(shí)現(xiàn)合成。不過這里在繪制第二幅圖像的時(shí)刻,須要在Paint對(duì)象上指定一個(gè)過渡模式(Xfermode)。
可用作過渡模式的類集合都持續(xù)自Xfermode基類,而個(gè)中包含一個(gè)成為PorterDuffXfermode的類。PorterDuffXfermode因Thomas Porter和Tom Duff而得名,他們于1984年在ACM SIGGRAPH計(jì)算機(jī)圖形學(xué)出版物上揭橥了題為“Compositing digital images”(合成數(shù)字圖像)的文┞仿,具體介紹了一系列不合的規(guī)矩,用于彼此重疊的繪制圖像。
在Android的PorterDuff.Mode類中列舉了他們制訂的規(guī)矩:
android.graphics.PorterDuff.Mode.SRC:只繪制源圖像
android.graphics.PorterDuff.Mode.DST:只繪制目標(biāo)圖像
android.graphics.PorterDuff.Mode.DST_OVER:在源圖像的頂部繪制目標(biāo)圖像
android.graphics.PorterDuff.Mode.DST_IN:只在源圖像和目標(biāo)圖像訂交的處所繪制目標(biāo)圖像
android.graphics.PorterDuff.Mode.DST_OUT:只在源圖像和目標(biāo)圖像不訂交的處所繪制目標(biāo)圖像
android.graphics.PorterDuff.Mode.DST_ATOP:在源圖像和目標(biāo)圖像訂交的處所繪制目標(biāo)圖像,在不訂交的處所繪制源圖像
android.graphics.PorterDuff.Mode.SRC_OVER:在目標(biāo)圖像的頂部繪制源圖像
android.graphics.PorterDuff.Mode.SRC_IN:只在源圖像和目標(biāo)圖像訂交的處所繪制源圖像
android.graphics.PorterDuff.Mode.SRC_OUT:只在源圖像和目標(biāo)圖像不訂交的處所繪制源圖像
android.graphics.PorterDuff.Mode.SRC_ATOP:在源圖像和目標(biāo)圖像訂交的處所繪制源圖像,在不訂交的處所繪制目標(biāo)圖像
android.graphics.PorterDuff.Mode.XOR:在源圖像和目標(biāo)圖像重疊之外的任何處所繪制他們,而在不重疊的處所不繪制任何內(nèi)容
android.graphics.PorterDuff.Mode.LIGHTEN:獲得每個(gè)地位上兩幅圖像中最亮的像素并顯示
android.graphics.PorterDuff.Mode.DARKEN:獲得每個(gè)地位上兩幅圖像中最暗的像素并顯示
android.graphics.PorterDuff.Mode.MULTIPLY:將每個(gè)地位的兩個(gè)像素相乘,除以255,然后應(yīng)用該值創(chuàng)建一個(gè)新的像素進(jìn)行顯示。結(jié)不雅色彩=頂部色彩*底部色彩/255
android.graphics.PorterDuff.Mode.SCREEN:反轉(zhuǎn)每個(gè)色彩,履行雷同的操作(將他們相乘并除以255),然后再次反轉(zhuǎn)。結(jié)不雅色彩=255-(((255-頂部色彩)*(255-底部色彩))/255)
信賴經(jīng)由過程膳綾擎的解釋可以明白為什么底部標(biāo)簽就是一張沒有色彩的圖片確能實(shí)現(xiàn)似乎有兩張圖在切換的效不雅了,本來是圖片合成。。。。。。
然后

mPaint.setAlpha(255);
		mCanvas.drawBitmap(mIconBitmap, null, mIconRect, mPaint);

從新設(shè)置了alpha值最大年夜,不通明,然則色彩沒設(shè)置,會(huì)導(dǎo)致美工給我們切的擱筆的線框也顯示我們?cè)O(shè)置的色彩值
然后再把圖片畫上去


好了,這個(gè)自定義的漸變切換標(biāo)簽寫好了,不過大年夜牛就是年沂錄,demo寫的都這么嚴(yán)謹(jǐn),比如說新手不會(huì)留意的

<span style="color:#333333;">if </span><span style="color:#ff0000;">(Looper.getMainLooper() == Looper.myLooper())</span><span style="color:#333333;">
		{
			invalidate();
		} else
		{
			postInvalidate();
		}</span>

想要懂得見鏈接:http://leochin.com/android-looper-mainlooper/  ;
還有

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

這個(gè)就能看出高手低手的差別了
最后關(guān)鍵的處所是經(jīng)由過程OnPageChangeListener接口里的onPageScrolled辦法實(shí)現(xiàn)漸變效不雅了

<span style="color:#333333;">@Override
	public void onPageScrolled</span><span style="color:#cc0000;">(int position, float positionOffset,
			int positionOffsetPixels)</span><span style="color:#333333;">
	{
		// 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);
		}

	}</span>
</pre><p></p><p><span style="font-family:Arial; color:#333333"><span style="font-size:14px; line-height:26px">positionOffset這個(gè)參數(shù)是一個(gè)左滑大年夜0到1最后置0的值,右滑大年夜1到0的值,經(jīng)由過程log數(shù)據(jù)可以分析出來,恰是因?yàn)檫@個(gè)特點(diǎn),所以可以很便利實(shí)現(xiàn)自定義view的重繪</span></span></p><p><span style="font-family:Arial; color:#333333"><span style="font-size:14px; line-height:26px">再附網(wǎng)上的一段代碼</span></span></p><p></p><pre name="code" class="java"> @Override
 71         public void onPageScrolled(int arg0, float arg1, int arg2) {
 72             if (isScrolling) {
 73                 if (lastValue > arg2) {
 74                     // 遞減,向右側(cè)滑動(dòng)
 75                     right = true;
 76                     left = false;
 77                 } else if (lastValue < arg2) {
 78                     // 遞減,向右側(cè)滑動(dòng)
 79                     right = false;
 80                     left = true;
 81                 } else if (lastValue =http://www.sjsjw.com/100/000272MYM011743/= arg2) {
 82                     right = left = false;
 83                 }
 84             }
 85             Log.i("meityitianViewPager",
 86                     "meityitianViewPager onPageScrolled  last :arg2  ,"
 87                             + lastValue + ":" + arg2);
 88             lastValue = arg2;
 89         }

因?yàn)樯啪c擎講解的都是對(duì)網(wǎng)上大年夜牛博客進(jìn)行進(jìn)修的,如不雅有搪突之處見諒,有疑問留言

相關(guān)案例查看更多