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

Android實(shí)現(xiàn)遮罩層(蒙板)效果

 更新時(shí)間:2018年10月29日 10:36:32   作者:白鷺飛  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)遮罩層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Android的遮罩效果就是把一張圖片蓋在另一張圖片的上面,通過控制任意一張圖片的顯示百分比實(shí)現(xiàn)遮罩效果。下面我使用兩張一樣的圖片來實(shí)現(xiàn)一個(gè)類似于 Android 的progressbar 的填充效果。使用遮罩效果來實(shí)現(xiàn)progressbar的效果的好處是,我們可以只改變圖片就可以更改progress的進(jìn)度填充效果,并且我們可以實(shí)現(xiàn)任意形式的填充效果,就比如橫豎填充,扇形逆/順時(shí)填充針等。

網(wǎng)上有很多介紹Android 遮罩效果的列子,但是都是橫豎的填充效果,下面我來實(shí)現(xiàn)一個(gè)扇形填充效果,如下圖:

我現(xiàn)在要做的就是用這兩種圖去實(shí)現(xiàn)一個(gè)progressbar效果.好了原來不解釋了直接上代碼吧:

一.Activity代碼

package com.gplus.mask.test;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
 
import com.gplus.mask.widget.MaskProgress;
import com.gplus.mask.widget.MaskProgress.AnimateListener;
 
 
public class GplusMask extends Activity{
 
 float progressFromCode = 150;
 float progressFromXml = 150;
 
 MaskProgress maskProgressFromeCode;
 MaskProgress maskProgressFromeXml;
 
 private boolean isAnimateFinish = true;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 
 RelativeLayout parent = (RelativeLayout) findViewById(R.id.parent);
 maskProgressFromeCode = new MaskProgress(this);
 initialProgress(maskProgressFromeCode);
 RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 
  RelativeLayout.LayoutParams.MATCH_PARENT);
 parent.addView(maskProgressFromeCode, rp);
 maskProgressFromeCode.initial();
 
 maskProgressFromeXml = (MaskProgress) findViewById(R.id.maskView);
 
 }
 
 private void initialProgress(MaskProgress maskProgress){
 //設(shè)置最大值
 maskProgress.setMax(300);
 //初始填充量為一半
 //初始化填充progress時(shí)的填充動(dòng)畫時(shí)間,越大越慢
 maskProgress.setTotaltime(3);
 //progress背景圖
 maskProgress.setBackgroundResId(R.drawable.untitled1);
 //progress填充內(nèi)容圖片
 maskProgress.setContentResId(R.drawable.untitled2);
 //Progress開始的填充的位置360和0為圓最右、90圓最下、180為圓最右、270為圓最上(順時(shí)針方向?yàn)檎?
 maskProgress.setStartAngle(0);
 maskProgress.setAnimateListener(animateListener);
 //初始化時(shí)必須在setMax設(shè)置之后再設(shè)置setProgress
 maskProgress.setProgress(175);
 }
 
 Handler handler = new Handler(){
 
 @Override
 public void handleMessage(Message msg) {
  super.handleMessage(msg);
 
  float newProgress = maskProgressFromeCode.getProgress() - 4;
  if(newProgress <= 0){//隨機(jī)繪制效果
  
  float max = (float) (Math.random() * 900 + 1000);
  float progress = (float) (max * Math.random());
  
  maskProgressFromeCode.setMax(max);
  maskProgressFromeCode.setProgress(progress);
  maskProgressFromeCode.setTotaltime((float) (Math.random()*10));
  maskProgressFromeCode.setStartAngle((float) (Math.random()*360));
  maskProgressFromeCode.initial();
  return;
  }
  maskProgressFromeCode.setProgress(newProgress);
  maskProgressFromeCode.updateProgress();
  
  handler.sendEmptyMessageDelayed(0, 50);
 }
 };
 
 AnimateListener animateListener = new AnimateListener() {
 
 @Override
 public void onAnimateFinish() {
  handler.sendEmptyMessageDelayed(0, 500);
 }
 };
}

二.activity布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res/com.gplus.mask.test"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >
 
  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="vertical" >
 
    <com.gplus.mask.widget.MaskProgress
      android:id="@+id/maskView"
      android:layout_width="200dp"
      android:layout_height="200dp"
      app:anim_time="20"
      app:max="180"
      app:progress="135"
      app:progress_background="@drawable/untitled1"
      app:progress_content="@drawable/untitled2"
      app:start_angle="0" 
      android:layout_centerInParent="true"/>
  </RelativeLayout>
 
  <RelativeLayout
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="vertical" />
 
</LinearLayout>

三.View的實(shí)現(xiàn)效果MaskProgress.java

package com.gplus.mask.widget;
 
 
 
 
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.PorterDuff.Mode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
 
/**
 * @author huangxin
 */
public class MaskProgress extends View{
 
 
 /** 每次setProgress時(shí)進(jìn)度條前進(jìn)或者回退到所設(shè)的值時(shí)都會(huì)有一段動(dòng)畫。
 * 該接口用于監(jiān)聽動(dòng)畫的完成,你應(yīng)該設(shè)置監(jiān)聽器監(jiān)聽到動(dòng)畫完成后,才再一次調(diào)用 
 * setProgress方法
 * */
 public static interface AnimateListener{
 public void onAnimateFinish();
 }
 
 private float totalTime = 5;//s
 
 
 private final static int REFRESH = 10;//mills
 
 private float step;
 
 private float max = 360;
 
 
 private float currentProgress;
 
 private float destProgress = 0;
 private float realProgress = 0;
 private float oldRealProgress = 0;
 private int backgroundResId;
 private int contentResId;
 
 private float startAngle = 270;
 
 private Bitmap bg;
 private Bitmap ct;
 
 private Paint paint;
 
 private int radius;
 
 private int beginX;
 private int beginY;
 
 private int centerX;
 private int centerY;
 
 private RectF rectF;
 
 private PorterDuffXfermode srcIn;
 
 private double rate;
 
 boolean initialing = false;
 
 AnimateListener animateListener;
 
 public MaskProgress(Context context) {
 this(context, null);
 }
 
 public MaskProgress(Context context, AttributeSet attrs) {
 this(context, attrs, R.attr.maskProgressStyle);
 }
 
 public MaskProgress(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 init(context, attrs, defStyle);
 }
 
 
 public void setAnimateListener(AnimateListener animateListener) {
 this.animateListener = animateListener;
 }
 
 public void setProgress(float destProgress) {
 if(destProgress > max)
  try {
  throw new Exception("progress can biger than max");
  } catch (Exception e) {
  e.printStackTrace();
  }
 
 this.destProgress = destProgress;
 oldRealProgress = realProgress;
 realProgress = (float) (destProgress * rate);
 }
 
 public float getProgress(){
 return destProgress;
 }
 
 public void setTotaltime(float totalTime) {
 this.totalTime = totalTime;
 step = 360 / (totalTime * 1000 / REFRESH);
 }
 
 public static int getRefresh() {
 return REFRESH;
 }
 
 public void setMax(float max) {
 this.max = max;
 rate = 360 / max;
 }
 
 public void setStartAngle(float startAngle) {
 this.startAngle = startAngle;
 }
 
 
 public void setBackgroundResId(int backgroundResId) {
 this.backgroundResId = backgroundResId;
 bg = BitmapFactory.decodeResource(getResources(), backgroundResId);
 }
 
 public void setContentResId(int contentResId) {
 this.contentResId = contentResId;
 ct = BitmapFactory.decodeResource(getResources(), contentResId);
 }
 
 public void updateProgress(){
 invalidate();
 }
 
 /** 初始化,第一次給MaskProgress設(shè)值時(shí),從沒有填充到,填充到給定的值時(shí)
 * 有一段動(dòng)畫
 * */
 public void initial(){
 initialing = true;
 new CirculateUpdateThread().start();
 }
 
 public float getMax() {
 return max;
 }
 
 private void init(Context context, AttributeSet attrs, int defStyle){
 
 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.maskProgressBar, defStyle, 0);
 
 if (typedArray != null) {
      try {
        setMax(typedArray.getFloat(R.styleable.maskProgressBar_max, max));
        setProgress(typedArray.getFloat(R.styleable.maskProgressBar_progress, destProgress));
        setTotaltime(typedArray.getFloat(R.styleable.maskProgressBar_anim_time, totalTime));
        setStartAngle(typedArray.getFloat(R.styleable.maskProgressBar_start_angle, startAngle));
        setContentResId(typedArray.getResourceId(R.styleable.maskProgressBar_progress_content, R.drawable.untitled2));
        setBackgroundResId(typedArray.getResourceId(R.styleable.maskProgressBar_progress_background, R.drawable.untitled1));
      } finally {
       typedArray.recycle();
      }  
    }
  
 paint = new Paint();
 paint.setDither(true);
 paint.setAntiAlias(true);
 
 rate = 360 / max;
 currentProgress = 0;
 realProgress = (float) (destProgress * rate);
 srcIn = new PorterDuffXfermode(Mode.SRC_IN);
 step = 360 / (totalTime * 1000 / REFRESH);
 
 bg = BitmapFactory.decodeResource(getResources(), backgroundResId);
 ct = BitmapFactory.decodeResource(getResources(), contentResId);
 
 Log.w("init", "max: " + max + "\n" + "destProgress: " + destProgress +"\n"+"totalTime: "+ totalTime+"\n"+"startAngle: "+ startAngle);
 
 initialing = true;
 new CirculateUpdateThread().start();
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 
 canvas.drawBitmap(bg, 0, (getHeight() - bg.getHeight()) / 2, paint);
 int rc = canvas.saveLayer(0, (getHeight() - bg.getHeight()) / 2, bg.getWidth(), (getHeight() + bg.getHeight()) / 2, null, Canvas.ALL_SAVE_FLAG);
 
 paint.setFilterBitmap(false);
 if(initialing){
  canvas.drawArc(rectF, startAngle, currentProgress, true, paint);
 }else{
  canvas.drawArc(rectF, startAngle, realProgress, true, paint);
 }
 paint.setXfermode(srcIn);
 canvas.drawBitmap(ct, 0, (getHeight() - ct.getHeight()) / 2, paint);
 
 paint.setXfermode(null);
 canvas.restoreToCount(rc);
 }
 
 public int[] getRectPosition(int progress){
 int[] rect = new int[4]; 
 
 rect[0] = beginX;
 rect[1] = beginY;
 rect[2] = (int)(centerX + radius * Math.cos(progress * Math.PI /180));
 rect[3] = (int)(centerY + radius * Math.sin(progress * Math.PI /180));
 
 Log.w("getRectPosition", "30: " + Math.sin(30 * Math.PI /180));
 
 Log.w("getRectPosition", "X: " + rect[2] + " " + "Y: " + rect[3]);
 
 return rect;
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
 }
 
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 
 int tmp = w >= h ? h : w;
 
 radius = tmp / 2;
 beginX = w / 2;
 beginY = 0;
 centerX = tmp / 2;
 centerY = tmp / 2;
 
 Bitmap bg_ = resizeBitmap(bg, tmp, tmp);
 Bitmap ct_ = resizeBitmap(ct, tmp, tmp);
 
 rectF = new RectF(0, (getHeight() - bg_.getHeight()) / 2, bg_.getWidth(), (getHeight() + bg_.getHeight()) / 2);
 
 bg.recycle();
 ct.recycle();
 
 bg = bg_;
 ct = ct_;
 }
 
 private Bitmap resizeBitmap(Bitmap src, int w, int h){
 
 int width = src.getWidth();
 int height = src.getHeight();
 int scaleWidht = w / width;
 int scaleHeight = h / height;
 
 Matrix matrix = new Matrix();
 matrix.postScale(scaleWidht, scaleHeight);
 
 Bitmap result = Bitmap.createScaledBitmap(src, w, h, true);
 src = null;
 
 return result;
 }
 
 class CirculateUpdateThread extends Thread{
 
 @Override
 public void run() {
  while(initialing){
  postInvalidate();
  if(currentProgress < realProgress){
   currentProgress += step * rate;
   if(currentProgress > realProgress)
   currentProgress = realProgress;
  }else{  
   // new Thread(new Runnable() {
   //
   // @Override
   // public void run() {
   // while (true) {
   // postInvalidate();
   // if (currentProgress > 0) {
   // currentProgress -= step * rate;
   // } else {
   // currentProgress = 0;
   // new CirculateUpdateThread().start();
   // break;
   // }
   // try {
   // Thread.sleep(REFRESH);
   // } catch (Exception e) {
   // e.printStackTrace();
   // }
   // }
   // }
   // }).start();
   currentProgress = 0;
   initialing = false;
   if(animateListener != null)
   animateListener.onAnimateFinish();
  }
  try{
   Thread.sleep(REFRESH);
  }catch(Exception e){
   e.printStackTrace();
  }
  }
 }
 
 } 
}

四.該Veiw自定義的屬性文件attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 
  <declare-styleable name="maskProgressBar">
    <attr name="max" format="float" />
    <attr name="progress" format="float" />
    <attr name="start_angle" format="float" />
    <attr name="progress_background" format="reference" />
    <attr name="progress_content" format="reference" />
    <attr name="anim_time" format="float" />
  </declare-styleable>
 
  
  <attr name="maskProgressStyle" format="reference" />
  
</resources>

效果圖如下,上面小的是定義xml的,下面大的是從代碼中添加的

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論