最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android仿知乎日?qǐng)?bào)開屏頁(yè)效果

 更新時(shí)間:2017年06月21日 17:17:28   作者:chiyidun  
這篇文章主要為大家詳細(xì)介紹了Android仿知乎日?qǐng)?bào)開屏頁(yè)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

先看看知乎日?qǐng)?bào)開屏頁(yè)的效果,非常漂亮的開屏效果


ezgif.com-resize (2).gif

然后我來(lái)一個(gè)


ezgif.com-resize (1).gif

也不錯(cuò)~感覺(jué)可以以假亂真了~

很簡(jiǎn)單,直接開始。

實(shí)現(xiàn)這個(gè)效果先制定個(gè)三步走策略

  • 底部布局上滑展示。
  • 畫一個(gè)知弧。
  • 顯示圖片

底部布局上滑展示

直接上代碼吧,屬性動(dòng)畫基本使用

private void startAnimation() {
    //位移動(dòng)畫,從底部滑出,Y方向移動(dòng),mHeight是底部布局的高度
    ObjectAnimator translationAnimator= ObjectAnimator.ofFloat(rv_bottom, "translationY", mHeight, 0f);
    //設(shè)置時(shí)長(zhǎng)
    translationAnimator.setDuration(1000);
    //透明度漸變動(dòng)畫
    ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f);
    //設(shè)置時(shí)長(zhǎng)
    alphaAnimatorator.setDuration(2500);
    //添加監(jiān)聽器,位移結(jié)束后,畫圓弧開始
    translationAnimator.addListener(new Animator.AnimatorListener() {
      @Override
      public void onAnimationStart(Animator animation) {

      }

      @Override
      public void onAnimationEnd(Animator animation) {
        zhview.startAnimation();
      }

      @Override
      public void onAnimationCancel(Animator animation) {

      }

      @Override
      public void onAnimationRepeat(Animator animation) {

      }
    });
    AnimatorSet set = new AnimatorSet();
    //兩個(gè)動(dòng)畫一起執(zhí)行
    set.play(translationAnimator).with(alphaAnimatorator);
    //go
    set.start();
  }

在位移動(dòng)畫結(jié)束的時(shí)候,調(diào)用了自定義的view的方法,開始了畫弧的操作。

畫個(gè)知弧

接下來(lái)開始畫畫~ 自定義一個(gè)view,重寫ondraw方法,開畫之前先初始化一個(gè)合適的畫筆。

 private void initPaint() {
    mPaint1 = new Paint();
    //設(shè)置畫筆顏色
    mPaint1.setColor(Color.WHITE);
    // 設(shè)置畫筆的樣式為圓形
    mPaint1.setStrokeCap(Paint.Cap.ROUND);
    // 設(shè)置畫筆的填充樣式為描邊
    mPaint1.setStyle(Paint.Style.STROKE);
    //抗鋸齒
    mPaint1.setAntiAlias(true);
    //設(shè)置畫筆寬度
    mPaint1.setStrokeWidth(mBorderWidth1);

    mPaint2 = new Paint();
    mPaint2.setColor(Color.WHITE);
    mPaint2.setStyle(Paint.Style.STROKE);
    mPaint2.setAntiAlias(true);
    mPaint2.setStrokeWidth(mBorderWidth2);
  }

mPaint1用來(lái)畫弧,設(shè)置填充樣式為描邊,這樣起碼我們就能輕松畫一個(gè)圓環(huán)了。其實(shí)要畫的知弧就是一個(gè)圓環(huán)被啃去了一塊的感覺(jué)~ 但被啃的地方很光滑,所以需要一個(gè)圓頭的畫筆 。
mPaint2用來(lái)畫外面的圓角矩形環(huán),設(shè)置也差不多。

@Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);
    //矩形輪廓,圓弧在內(nèi)部,給予一定的內(nèi)邊距
    RectF rectF1 = new RectF(mBorderWidth1/2+dipToPx(8), mBorderWidth1/2+dipToPx(8), getWidth() -mBorderWidth1/2-dipToPx(8),getWidth()-mBorderWidth1/2-dipToPx(8) );
    //畫圓弧 參數(shù)1:矩形輪廓 參數(shù)2:起始位置 參數(shù)3:掃過(guò)的范圍,初始為0 參數(shù)4:是否連接圓心
    canvas.drawArc(rectF1, 90, mCurrentRadian, false, mPaint1);
    //矩形輪廓
    RectF rectF2 = new RectF(mBorderWidth2/2,mBorderWidth2/2,getWidth()-mBorderWidth2/2,getWidth()-mBorderWidth2/2);
    //畫圓角矩形邊框 參數(shù)2 3設(shè)置x,y方向的圓角corner 都要設(shè)置
    canvas.drawRoundRect(rectF2,dipToPx(8),dipToPx(8),mPaint2);

  }

代碼量很少,但要明確環(huán)的畫法,不論是畫圓環(huán)還是圓角矩形環(huán),需要先確定一個(gè)基準(zhǔn)矩形?;鶞?zhǔn)矩形的位置和大小確定環(huán)的位置和大小。畫弧的方法canvas.drawArc中的參數(shù)2 3設(shè)置了開始畫弧的位置和畫弧的范圍??匆幌逻\(yùn)行效果,圓弧的起始畫點(diǎn)在圓心的正下方,X軸正方向?yàn)?度,所以起始畫點(diǎn)為90度。

接下來(lái)就使用不斷增大畫弧的范圍的方式來(lái)完成動(dòng)畫的實(shí)現(xiàn)。上代碼

private void startAnimationDraw() {
    //圓弧掃過(guò)范圍為270度
    ValueAnimator valueAnimator=new ValueAnimator().ofFloat(0,270);
    //動(dòng)畫持續(xù)時(shí)間
    valueAnimator.setDuration(mDuration);
    //設(shè)置插值器,中間快兩頭慢
    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
    //添加狀態(tài)監(jiān)聽器
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        //不斷增大圓弧掃過(guò)的范圍,并重繪來(lái)實(shí)現(xiàn)動(dòng)畫效果
        mCurrentRadian= (float) animation.getAnimatedValue();
        invalidate();
      }
    });
    valueAnimator.start();
  }

使用ValueAnimator.ofFloat創(chuàng)建一個(gè)值為0-270的動(dòng)畫,添加狀態(tài)監(jiān)聽,在動(dòng)畫執(zhí)行的過(guò)程中不斷增大掃過(guò)的范圍并重繪視圖從而實(shí)現(xiàn)了畫弧的動(dòng)畫效果。

整個(gè)過(guò)程就是canvas配合屬性動(dòng)畫的方式完成了動(dòng)態(tài)繪圖,一點(diǎn)也不復(fù)雜。

顯示圖片

這里我使用的是Glide加載的本地圖片,設(shè)置了延遲加載把握?qǐng)D片加載時(shí)機(jī),獲得更好的開屏效果

 //延時(shí)加載圖片
        new Handler().postDelayed(new Runnable() {
          @Override
          public void run() {
            Glide.with(MainActivity.this).
                load(R.drawable.timg).
                centerCrop().
                skipMemoryCache(true).
                diskCacheStrategy(DiskCacheStrategy.NONE).
                crossFade(500).
                into(image)
            ;
          }
        },2000);

這里個(gè)人認(rèn)為知乎也是用某種方式預(yù)先把圖片下載到本地完成來(lái)把握精確地加載時(shí)機(jī),不知道是不是這樣。。

最后貼一下代碼

activity

public class MainActivity extends AppCompatActivity {
  private RelativeLayout rv_bottom;
  private Zhview zhview;
  private float mHeight;
  private ImageView image;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    rv_bottom= (RelativeLayout) this.findViewById(R.id.rv_bottom);
    zhview= (Zhview) this.findViewById(R.id.zhview);
    image= (ImageView) this.findViewById(R.id.image);
    rv_bottom.post(new Runnable() {
      @Override
      public void run() {
        //獲得底部的高度
        mHeight=rv_bottom.getHeight();
        //開始動(dòng)畫
        startAnimation();
        //延時(shí)加載圖片
        new Handler().postDelayed(new Runnable() {
          @Override
          public void run() {
            Glide.with(MainActivity.this).
                load(R.drawable.timg).
                centerCrop().
                skipMemoryCache(true).
                diskCacheStrategy(DiskCacheStrategy.NONE).
                crossFade(500).
                into(image)
            ;
          }
        },2000);
      }
    });
  }

  private void startAnimation() {
    //位移動(dòng)畫,從底部滑出,Y方向移動(dòng)
    ObjectAnimator translationAnimator= ObjectAnimator.ofFloat(rv_bottom, "translationY", mHeight, 0f);
    //設(shè)置時(shí)長(zhǎng)
    translationAnimator.setDuration(1000);
    //透明度漸變動(dòng)畫
    ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f);
    //設(shè)置時(shí)長(zhǎng)
    alphaAnimatorator.setDuration(2500);
    //添加監(jiān)聽器,位移結(jié)束后,畫圓弧開始
    translationAnimator.addListener(new Animator.AnimatorListener() {
      @Override
      public void onAnimationStart(Animator animation) {

      }

      @Override
      public void onAnimationEnd(Animator animation) {
        zhview.startAnimation();
      }

      @Override
      public void onAnimationCancel(Animator animation) {

      }

      @Override
      public void onAnimationRepeat(Animator animation) {

      }
    });
    AnimatorSet set = new AnimatorSet();
    //兩個(gè)動(dòng)畫一起執(zhí)行
    set.play(translationAnimator).with(alphaAnimatorator);
    //go
    set.start();
  }
}

自定義view

public class Zhview extends View {
  private Paint mPaint1; //圓弧畫筆
  private Paint mPaint2; //外框畫筆
  //圓弧寬度
  private int mBorderWidth1=dipToPx(5);
  //外框?qū)挾?
  private int mBorderWidth2=dipToPx(1.5f);
  //掃過(guò)的范圍
  private float mCurrentRadian=0;
  //動(dòng)畫持續(xù)時(shí)長(zhǎng)
  private int mDuration=1500;

  public Zhview(Context context) {
    this(context,null);
  }

  public Zhview(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs,0);

  }

  public Zhview(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    //初始化畫筆
    initPaint();
  }

  private void initPaint() {
    mPaint1 = new Paint();
    //設(shè)置畫筆顏色
    mPaint1.setColor(Color.WHITE);
    // 設(shè)置畫筆的樣式為圓形
    mPaint1.setStrokeCap(Paint.Cap.ROUND);
    // 設(shè)置畫筆的填充樣式為描邊
    mPaint1.setStyle(Paint.Style.STROKE);
    //抗鋸齒
    mPaint1.setAntiAlias(true);
    //設(shè)置畫筆寬度
    mPaint1.setStrokeWidth(mBorderWidth1);

    mPaint2 = new Paint();
    mPaint2.setColor(Color.WHITE);
    mPaint2.setStyle(Paint.Style.STROKE);
    mPaint2.setAntiAlias(true);
    mPaint2.setStrokeWidth(mBorderWidth2);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);
    //矩形輪廓,圓弧在內(nèi)部,給予一定的內(nèi)邊距
    RectF rectF1 = new RectF(mBorderWidth1/2+dipToPx(8), mBorderWidth1/2+dipToPx(8), getWidth() -mBorderWidth1/2-dipToPx(8),getWidth()-mBorderWidth1/2-dipToPx(8) );
    //畫圓弧 參數(shù)1:矩形輪廓 參數(shù)2:起始位置 參數(shù)3:掃過(guò)的范圍,初始為0 參數(shù)4:是否連接圓心
    canvas.drawArc(rectF1, 90, mCurrentRadian, false, mPaint1);
    //矩形輪廓
    RectF rectF2 = new RectF(mBorderWidth2/2,mBorderWidth2/2,getWidth()-mBorderWidth2/2,getWidth()-mBorderWidth2/2);
    //畫圓角矩形邊框 參數(shù)2 3設(shè)置x,y方向的圓角corner 都要設(shè)置
    canvas.drawRoundRect(rectF2,dipToPx(8),dipToPx(8),mPaint2);

  }

  private void startAnimationDraw() {
    //圓弧掃過(guò)范圍為270度
    ValueAnimator valueAnimator=new ValueAnimator().ofFloat(0,270);
    //動(dòng)畫持續(xù)時(shí)間
    valueAnimator.setDuration(mDuration);
    //設(shè)置插值器,中間快兩頭慢
    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
    //添加狀態(tài)監(jiān)聽器
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        //不斷增大圓弧掃過(guò)的范圍,并重繪來(lái)實(shí)現(xiàn)動(dòng)畫效果
        mCurrentRadian= (float) animation.getAnimatedValue();
        invalidate();
      }
    });
    valueAnimator.start();
  }
  //開始動(dòng)畫
  public void startAnimation(){
    startAnimationDraw();
  }
  private int dipToPx(float dip) {
    float density = getContext().getResources().getDisplayMetrics().density;
    return (int) (dip * density + 0.5f * (dip >= 0 ? 1 : -1));
  }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@android:color/black"
  tools:context="com.zhview.MainActivity">

  <ImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/rv_bottom" />

  <RelativeLayout
    android:id="@+id/rv_bottom"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:padding="20dp">

    <com.zhview.Zhview
      android:id="@+id/zhview"
      android:layout_width="46dp"
      android:layout_height="46dp"
      android:layout_marginLeft="10dp" />

    <TextView
      android:id="@+id/tv_title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginLeft="20dp"
      android:layout_toRightOf="@+id/zhview"
      android:text="知乎日?qǐng)?bào)"
      android:textColor="@android:color/white"
      android:textSize="19sp"

      />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignBottom="@+id/zhview"
      android:layout_marginLeft="20dp"
      android:layout_toRightOf="@+id/zhview"
      android:text="每天三次,每次七分鐘"
      android:textColor="@android:color/darker_gray"
      android:textSize="13sp" />
  </RelativeLayout>
</RelativeLayout>

我個(gè)人挺喜歡這些實(shí)現(xiàn)起來(lái)不復(fù)雜但體驗(yàn)非常好的設(shè)計(jì),見(jiàn)到了就努力實(shí)現(xiàn)一下,然后邊學(xué)邊分享,要是跟我一樣感興趣的話可以關(guān)注我一下哦~

完整代碼地址https://github.com/yanyiqun001/zhview

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

相關(guān)文章

最新評(píng)論

竹溪县| 日土县| 东平县| 稻城县| 云浮市| 广元市| 上高县| 逊克县| 仲巴县| 杭锦后旗| 砀山县| 大田县| 固阳县| 平果县| 庆元县| 安溪县| 潞西市| 武乡县| 巩义市| 陆丰市| 益阳市| 自治县| 肃南| 阳原县| 左权县| 平定县| 佳木斯市| 渝北区| 孙吴县| 昌吉市| 剑河县| 临邑县| 鱼台县| 内丘县| 屏山县| 德惠市| 共和县| 鄢陵县| 怀化市| 嘉荫县| 上栗县|