先看看知乎日报开屏页的效果,非常漂亮的开屏效果

ezgif.com-resize (2).gif

然后我来一个

ezgif.com-resize (1).gif

也不错~感觉可以以假乱真了~

很简单,直接开始。

实现这个效果先制定个三步走策略

底部布局上滑展示。

画一个知弧。

显示图片

底部布局上滑展示

直接上代码吧,属性动画基本使用

private void startAnimation() {

//位移动画,从底部滑出,Y方向移动,mHeight是底部布局的高度

ObjectAnimator translationAnimator= ObjectAnimator.ofFloat(rv_bottom, "translationY", mHeight, 0f);

//设置时长

translationAnimator.setDuration(1000);

//透明度渐变动画

ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f);

//设置时长

alphaAnimatorator.setDuration(2500);

//添加监听器,位移结束后,画圆弧开始

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

//两个动画一起执行

set.play(translationAnimator).with(alphaAnimatorator);

//go

set.start();

}

在位移动画结束的时候,调用了自定义的view的方法,开始了画弧的操作。

画个知弧

接下来开始画画~ 自定义一个view,重写ondraw方法,开画之前先初始化一个合适的画笔。

private void initPaint() {

mPaint1 = new Paint();

//设置画笔颜色

mPaint1.setColor(Color.WHITE);

// 设置画笔的样式为圆形

mPaint1.setStrokeCap(Paint.Cap.ROUND);

// 设置画笔的填充样式为描边

mPaint1.setStyle(Paint.Style.STROKE);

//抗锯齿

mPaint1.setAntiAlias(true);

//设置画笔宽度

mPaint1.setStrokeWidth(mBorderWidth1);

mPaint2 = new Paint();

mPaint2.setColor(Color.WHITE);

mPaint2.setStyle(Paint.Style.STROKE);

mPaint2.setAntiAlias(true);

mPaint2.setStrokeWidth(mBorderWidth2);

}

mPaint1用来画弧,设置填充样式为描边,这样起码我们就能轻松画一个圆环了。其实要画的知弧就是一个圆环被啃去了一块的感觉~ 但被啃的地方很光滑,所以需要一个圆头的画笔 。

mPaint2用来画外面的圆角矩形环,设置也差不多。

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawColor(Color.BLACK);

//矩形轮廓,圆弧在内部,给予一定的内边距

RectF rectF1 = new RectF(mBorderWidth1/2+dipToPx(8), mBorderWidth1/2+dipToPx(8), getWidth() -mBorderWidth1/2-dipToPx(8),getWidth()-mBorderWidth1/2-dipToPx(8) );

//画圆弧 参数1:矩形轮廓 参数2:起始位置 参数3:扫过的范围,初始为0 参数4:是否连接圆心

canvas.drawArc(rectF1, 90, mCurrentRadian, false, mPaint1);

//矩形轮廓

RectF rectF2 = new RectF(mBorderWidth2/2,mBorderWidth2/2,getWidth()-mBorderWidth2/2,getWidth()-mBorderWidth2/2);

//画圆角矩形边框 参数2 3设置x,y方向的圆角corner 都要设置

canvas.drawRoundRect(rectF2,dipToPx(8),dipToPx(8),mPaint2);

}

代码量很少,但要明确环的画法,不论是画圆环还是圆角矩形环,需要先确定一个基准矩形。基准矩形的位置和大小确定环的位置和大小。画弧的方法canvas.drawArc中的参数2 3设置了开始画弧的位置和画弧的范围。看一下运行效果,圆弧的起始画点在圆心的正下方,X轴正方向为0度,所以起始画点为90度。

接下来就使用不断增大画弧的范围的方式来完成动画的实现。上代码

private void startAnimationDraw() {

//圆弧扫过范围为270度

ValueAnimator valueAnimator=new ValueAnimator().ofFloat(0,270);

//动画持续时间

valueAnimator.setDuration(mDuration);

//设置插值器,中间快两头慢

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

//添加状态监听器

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//不断增大圆弧扫过的范围,并重绘来实现动画效果

mCurrentRadian= (float) animation.getAnimatedValue();

invalidate();

}

});

valueAnimator.start();

}

使用ValueAnimator.ofFloat创建一个值为0-270的动画,添加状态监听,在动画执行的过程中不断增大扫过的范围并重绘视图从而实现了画弧的动画效果。

整个过程就是canvas配合属性动画的方式完成了动态绘图,一点也不复杂。

显示图片

这里我使用的是Glide加载的本地图片,设置了延迟加载把握图片加载时机,获得更好的开屏效果

//延时加载图片

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

这里个人认为知乎也是用某种方式预先把图片下载到本地完成来把握精确地加载时机,不知道是不是这样。。

最后贴一下代码

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

//开始动画

startAnimation();

//延时加载图片

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() {

//位移动画,从底部滑出,Y方向移动

ObjectAnimator translationAnimator= ObjectAnimator.ofFloat(rv_bottom, "translationY", mHeight, 0f);

//设置时长

translationAnimator.setDuration(1000);

//透明度渐变动画

ObjectAnimator alphaAnimatorator = ObjectAnimator.ofFloat(rv_bottom, "alpha", 0f,1f);

//设置时长

alphaAnimatorator.setDuration(2500);

//添加监听器,位移结束后,画圆弧开始

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

//两个动画一起执行

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

//外框宽度

private int mBorderWidth2=dipToPx(1.5f);

//扫过的范围

private float mCurrentRadian=0;

//动画持续时长

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

//设置画笔颜色

mPaint1.setColor(Color.WHITE);

// 设置画笔的样式为圆形

mPaint1.setStrokeCap(Paint.Cap.ROUND);

// 设置画笔的填充样式为描边

mPaint1.setStyle(Paint.Style.STROKE);

//抗锯齿

mPaint1.setAntiAlias(true);

//设置画笔宽度

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

//矩形轮廓,圆弧在内部,给予一定的内边距

RectF rectF1 = new RectF(mBorderWidth1/2+dipToPx(8), mBorderWidth1/2+dipToPx(8), getWidth() -mBorderWidth1/2-dipToPx(8),getWidth()-mBorderWidth1/2-dipToPx(8) );

//画圆弧 参数1:矩形轮廓 参数2:起始位置 参数3:扫过的范围,初始为0 参数4:是否连接圆心

canvas.drawArc(rectF1, 90, mCurrentRadian, false, mPaint1);

//矩形轮廓

RectF rectF2 = new RectF(mBorderWidth2/2,mBorderWidth2/2,getWidth()-mBorderWidth2/2,getWidth()-mBorderWidth2/2);

//画圆角矩形边框 参数2 3设置x,y方向的圆角corner 都要设置

canvas.drawRoundRect(rectF2,dipToPx(8),dipToPx(8),mPaint2);

}

private void startAnimationDraw() {

//圆弧扫过范围为270度

ValueAnimator valueAnimator=new ValueAnimator().ofFloat(0,270);

//动画持续时间

valueAnimator.setDuration(mDuration);

//设置插值器,中间快两头慢

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

//添加状态监听器

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//不断增大圆弧扫过的范围,并重绘来实现动画效果

mCurrentRadian= (float) animation.getAnimatedValue();

invalidate();

}

});

valueAnimator.start();

}

//开始动画

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

}

}

布局文件

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

android:id="@+id/image"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_above="@+id/rv_bottom" />

android:id="@+id/rv_bottom"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:padding="20dp">

android:id="@+id/zhview"

android:layout_width="46dp"

android:layout_height="46dp"

android:layout_marginLeft="10dp" />

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="知乎日报"

android:textColor="@android:color/white"

android:textSize="19sp"

/>

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

我个人挺喜欢这些实现起来不复杂但体验非常好的设计,见到了就努力实现一下,然后边学边分享,要是跟我一样感兴趣的话可以关注我一下哦~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android仿知乎工作内容,Android仿知乎日报开屏页效果相关推荐

  1. android toast前面自动加内容,android Toast大全(五种情形)建立属于你自己的Toast...

    Toast用于向用户显示一些帮助/提示.下面我做了5中效果,来说明Toast的强大,定义一个属于你自己的Toast. 1.默认效果 代码 Toast.makeText(getApplicationCo ...

  2. 我的第一个Android应用BMI-深入浅出Android

    深入浅出 Android 1入门 .... 4 初探 Android .. 4 2008 年末最大的冲击 .... 4 Android 是什么 .... 4 从创意开始 .... 5 安装 Andro ...

  3. boss直聘Android找工作界面,Android仿Boss直聘我的界面滑动效果

    最近在找工作,我在使用boss投简历的时候,看到boss的我的界面蛮有意思的,就想如何去实现它,可能是职业病吧,所以就打算仿一下.先看下仿的效果. image 其实我们拿到这个效果的时候,看到滑动,折 ...

  4. android 打造炫酷导航栏(仿UC头条)

    年后开始上班甚是清闲,所以想捣鼓一些东西.在翻阅大神杰作Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高仿MIUI 的时候看到下面有一条评论说,如果导航栏能滑动就更好了. ...

  5. Android插件化开发指南——实践之仿酷狗音乐首页

    文章目录 1. 前言 2. 布局分析 3. 底部导航栏的实现 4. 顶部导航栏和ViewPager+Fragment的关联 1. 前言 在Android插件化开发指南--2.15 实现一个音乐播放器A ...

  6. android中仿qq最新版抽屉,Android实现3种侧滑效果(仿qq侧滑、抽屉侧滑、普通侧滑)...

    自己实现了一下侧滑的三种方式(注释都写代码里了) 本文Demo下载地址:Andriod侧滑 本文实现所需框架:nineoldandroids下载地址:nineoldandroids 1.普通侧滑: 主 ...

  7. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

  8. android标题栏不被顶上去,Android仿微信QQ聊天顶起输入法不顶起标题栏的问题

    在这记录一下输入法弹出的一系列问题,有的输入法弹出就把整个布局弹上去,有的输入法弹出布局不会有变化,有的输入法弹出遮盖输入框等等问题,网上也有很多说加着加那的,但是看一下都不是很完整,解决不了所有问题 ...

  9. Android 仿微信小程序开屏页加载loading

    Android 仿微信小程序开屏页加载loading 废话不多说,先上效果图~ 首先就是底层有一个灰色的圆,然后按照圆形的轨迹进行绘制. 啊~说那么多也没用,还是直接上代码吧,哈哈哈哈 绘制底部圆形及 ...

最新文章

  1. matlab平滑曲线_说说地震波的那些事儿(二)——地震影响曲线
  2. 清华大数据能力提升项目《数据分析方法》选课开始 !(附旁听名额)
  3. JavaScript 里,$ 代表什么?/JQuery是什么语言?/html中用link标签引入css时的中 rel=stylesheet属性?/EL表达式是什么?...
  4. 08Spring_Spring和junit测试集成
  5. 盘点几种MySQL复制的解决方案和常见的错误理解
  6. 深度学习(四)卷积神经网络Lenet-5实现
  7. C# List泛型集合中的GroupBy用法
  8. 网页编程从入门到精通 杨凡_干货 | web前端入门基础知识
  9. Spark SQL在100TB上的自适应执行实践
  10. webrtc 和 rtp 协议
  11. Gulp和Webpack对比
  12. 力压 MongoDB、Redis,PostgreSQL 蝉联“年度数据库”!
  13. sqlplus terminators - Semicolumn (;), slash (/) and a blank line
  14. ubuntu14.04LTS 安装后几个基本设置
  15. 手把手教你ssm整合 超级详细
  16. 测试工程师需掌握的技能
  17. jira是干什么_JIRA的使用介绍(一)- 概念篇
  18. Datawhale打卡活动 Kaggle Spaceship Titanic Day3
  19. 网络编程(基于socket接口技术的进程间通信)接上一篇文章补充
  20. 第四周-圆柱体的表面积

热门文章

  1. K9s 使用教程:如何高效管理 Kubernetes 集群
  2. 如何限制网页只能在微信内置浏览器中打开?
  3. 【安信可A9G专题④】A9G模块/开发板GPS定位注意事项 坐标系转换
  4. 2022年的有关语义分割的论文,含CVPR、ECCV、ICLR、AAAI
  5. 如何化身BAT面试收割机?工作感悟
  6. Android自定义仿Siri曲线View
  7. Linux xampp apache启动失败
  8. GOF 设计模式Facade模式 笔记
  9. 如何升级vmware workstation虚拟机软件
  10. 360 浏览器设置里安全设置里清除上网痕迹中没有“管理保存过的账号和密码”这个选项