<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android實(shí)現(xiàn)炫酷的圖片展示效果

          共 6030字,需瀏覽 13分鐘

           ·

          2021-07-17 07:01

          效果展示


          實(shí)現(xiàn)原理


          這里的實(shí)現(xiàn)原理很簡(jiǎn)單,就是添加多個(gè)矩形路徑,并不斷的延長(zhǎng)各個(gè)矩形路徑的寬度(通過onDraw方法的遞歸實(shí)現(xiàn)),然后在矩形路徑中繪制Bitmap即可。


          實(shí)現(xiàn)步驟


          1. 構(gòu)建用于展示的Bitmap

          這里我們選擇在onSizeChanged方法中初始化Bitmap,
          因?yàn)楫?dāng)控件大小改變時(shí)方便我們重新計(jì)算所需展示Bitmap的大小。
           @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false);//根據(jù)控件大小創(chuàng)建一個(gè)與控件寬高相同的Bitmap對(duì)象        postInvalidate();//創(chuàng)建完Bitmap后對(duì)控件進(jìn)行刷新        super.onSizeChanged(w, h, oldw, oldh);    }


          2. 構(gòu)建矩形裁剪區(qū)域并添加到Path中



          由上圖可以看出我們需要添加的矩形路徑分為左半邊部分和右半邊部分,
          我們以左半部分第一個(gè)矩形和右半部分第一個(gè)矩形為例:

          左邊矩形的構(gòu)建參數(shù):
              left = 0,
              top = 0,
              right = clipwidth,
              bottom = SINGLERECT_HEIGHT。

          右邊矩形的構(gòu)建參數(shù):
              left = View_Width - clipwidth,
              top = SINGLERECT_HEIGHT,
              right = View_Width,
              bottom = 2 * SINGLERECT_HEIGHT。

          根據(jù)如上構(gòu)建參數(shù)的規(guī)律我們總結(jié)出如下公式(其中i代表由上到下第幾個(gè)矩形):

          左邊矩形構(gòu)建公式:
          RectF rectleft = new RectF(0,i * SINGLEREGION_HEIGHT,cilpWidth,(i + 1) * SINGLEREGION_HEIGHT)

          右邊矩形構(gòu)建公式:
          RectF rectright = new RectF(View_Width - cilpWidth,i * SINGLEREGION_HEIGHT,getWidth(),(i + 1) * SINGLEREGION_HEIGHT)

          根據(jù)如上公式我們?cè)诖a中添加路徑:
          //根據(jù)控件的高度來(lái)添加矩形路徑for(int i=0;i*SINGLEREGION_HEIGHT<getHeight();i++){            if(i%2==0){                mPath.addRect(new RectF(0,i*SINGLEREGION_HEIGHT,cilpWidth,(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);            }else {                mPath.addRect(new RectF(getWidth()-cilpWidth,i*SINGLEREGION_HEIGHT,getWidth(),(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);            }        }


          3. 在對(duì)應(yīng)的路徑中繪制出Bitmap

          這里使用Canvas的clipPath方法將畫布裁切成路徑的形狀,
          然后在裁切后的畫布上繪制圖片。
          canvas.clipPath(mPath);//根據(jù)路徑裁切畫布canvas.drawBitmap(mBitmap,0,0,mPaint);//在裁切后的畫布上繪制圖片


          4. 利用遞歸實(shí)現(xiàn)動(dòng)畫效果

          if(cilpWidth>getWidth()){    //當(dāng)矩形的寬度等于控件寬度時(shí)停止重繪     return;}cilpWidth+=5;//每次繪制完需要增加clipWidth的寬度 invalidate();//重繪(運(yùn)用遞歸)


          5. 當(dāng)圖片完全顯示時(shí)替換圖片

          圖片完全顯示也是cilpWidth>控件寬度的時(shí)候。
          if(cilpWidth>getWidth()){     //當(dāng)圖片完全展示時(shí)替換圖片     mBitmap=Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false);     canvas.drawBitmap(mBitmap,0,0,mPaint);     return;}


          完整代碼展示

          public class View_ClipAnim extends View {    private Paint mPaint;    private Path mPath;    private final float SINGLEREGION_HEIGHT=30;//每個(gè)長(zhǎng)條的高度    private Bitmap mBitmap;    float cilpWidth=0;//矩形寬度    public View_ClipAnim(Context context) {        this(context,null);    }
          public View_ClipAnim(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); }
          public View_ClipAnim(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }
          /** * 初始化畫筆等 */ private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPath = new Path(); }
          @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false); cilpWidth=0; postInvalidate(); super.onSizeChanged(w, h, oldw, oldh); }
          @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset();//每次繪制之前先將Path重置 for(int i=0;i*SINGLEREGION_HEIGHT<getHeight();i++){ if(i%2==0){ mPath.addRect(new RectF(0,i*SINGLEREGION_HEIGHT,cilpWidth,(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW); }else { mPath.addRect(new RectF(getWidth()-cilpWidth,i*SINGLEREGION_HEIGHT,getWidth(),(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW); } } canvas.clipPath(mPath);//根據(jù)路徑裁切畫布 canvas.drawBitmap(mBitmap,0,0,mPaint);//在裁切后的畫布上繪制圖片 if(cilpWidth>getWidth()){ //當(dāng)圖片完全展示時(shí)替換圖片 mBitmap=Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false); canvas.drawBitmap(mBitmap,0,0,mPaint); return; } cilpWidth+=5;//每次繪制完需要增加clipWidth的寬度 invalidate();//重繪(運(yùn)用遞歸) }}


          擴(kuò)展

          掃描式圖片展示



          這里主要是使用弧形路徑來(lái)展示圖片的,通過不斷增加弧形角度來(lái)擴(kuò)大顯示區(qū)域(這里的弧形半徑是通過勾股定理得出的)。
          public class View_ClipCircleAnim extends View {    private Paint mPaint;    private float mRadius;//圓形的半徑    private Path mPath;    private Bitmap mBitmap;    private int mAngle=0;//圓形角度    public View_ClipCircleAnim(Context context) {        this(context,null);    }
          public View_ClipCircleAnim(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); }
          public View_ClipCircleAnim(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }
          private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPath = new Path(); }
          @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { float a = w/2; float b = h/2; mRadius = (float) Math.sqrt(a*a+b*b);//根據(jù)勾股定理算出圓形的半徑 mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false); super.onSizeChanged(w, h, oldw, oldh); }
          @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.translate(getWidth()/2,getHeight()/2);//將(0,0)點(diǎn)移動(dòng)到畫布中心 if(mAngle>=360){ canvas.drawBitmap(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false),-getWidth()/2,-getHeight()/2,mPaint); return; } mPath.reset();//清空路徑 mPath.moveTo(0,0); mPath.arcTo(new RectF(-mRadius,-mRadius,mRadius,mRadius),0,mAngle,false);//添加閉合的弧形 canvas.clipPath(mPath);//裁剪畫布為路徑的形狀 canvas.drawBitmap(mBitmap,-getWidth()/2,-getHeight()/2,mPaint); mAngle++; postInvalidate(); }}

          到這里就結(jié)束啦。
          瀏覽 104
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  jjzz国产| 苍井空视频一区二区 | 久久9视频 | 午夜精品在线观看 | 日韩av电影免费在线观看 |