<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仿知乎日?qǐng)?bào)開屏頁效果

          共 9821字,需瀏覽 20分鐘

           ·

          2021-12-17 09:10

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



          然后我來一個(gè):



          也不錯(cuò)感覺可以以假亂真了,很簡單,直接開始。


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

          1. 底部布局上滑展示。

          2. 畫一個(gè)知弧。

          3. 顯示圖片


          底部布局上滑展示

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

          private void startAnimation() {        //位移動(dòng)畫,從底部滑出,Y方向移動(dòng),mHeight是底部布局的高度        ObjectAnimator translationAnimator= ObjectAnimator.ofFloat(rv_bottom, "translationY", mHeight, 0f);        //設(shè)置時(shí)長        translationAnimator.setDuration(1000);        //透明度漸變動(dòng)畫        ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f);        //設(shè)置時(shí)長        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è)知弧

          接下來開始畫畫~ 自定義一個(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用來畫弧,設(shè)置填充樣式為描邊,這樣起碼我們就能輕松畫一個(gè)圓環(huán)了。其實(shí)要畫的知弧就是一個(gè)圓環(huán)被啃去了一塊的感覺~ 但被啃的地方很光滑,所以需要一個(gè)圓頭的畫筆 。


          mPaint2用來畫外面的圓角矩形環(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:掃過的范圍,初始為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度。


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

          private void startAnimationDraw() {        //圓弧掃過范圍為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) {                //不斷增大圓弧掃過的范圍,并重繪來實(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í)行的過程中不斷增大掃過的范圍并重繪視圖從而實(shí)現(xiàn)了畫弧的動(dòng)畫效果。


          整個(gè)過程就是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ù)先把圖片下載到本地完成來把握精確地加載時(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í)長 translationAnimator.setDuration(1000); //透明度漸變動(dòng)畫 ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f); //設(shè)置時(shí)長 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ū)挾?/span>    private int mBorderWidth2=dipToPx(1.5f);    //掃過的范圍    private float mCurrentRadian=0;    //動(dòng)畫持續(xù)時(shí)長    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:掃過的范圍,初始為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() { //圓弧掃過范圍為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) { //不斷增大圓弧掃過的范圍,并重繪來實(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)); }}


          布局文件

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


          源碼地址:

          https://github.com/yanyiqun001/zhview


          到這里就結(jié)束啦。

          瀏覽 122
          點(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>
                  婷婷精品视频 | 高清无码视频免费在线观看 | 曰韩中文三级片 | 999av | 伊人五月婷久久 |