教你一步步封装vue的toast和loading组件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教你一步步封装vue的toast和loading组件相关的知识,希望对你有一定的参考价值。
参考技术A 我们在项目中都会用到toast,loading加载器。特别是在进行移动端的项目开发的时候,
进行异步操作的时候去等待,在必要的时候用toast给用户提示。在app开发中,ios有成熟的MBProgressHUD插件等等。
在web前端也有很多第三方库也提供了这些组件,比如mint-ui,element-ui等都包含这些组件,
但是存在一个缺点,当我们只需要使用toast,loading组件,并用不到其他组件的时候,我们还是需要安装整个组件库,
会导致我们依赖的第三方库增大。所以我就做了一个轻量级的toast,loading插件vue-toast-indicator。
这里我推荐一个福利,更多精彩内容请点击链接, 点击这里
导入包,全局使用
举个栗子:
上面创建了一个最简单的vue组件
假设我们导入该组件名字是HelloWorld
就是这么简单,上面用到了vue的插件,自定义vue插件需要导出一个install方法
使用就更简单了
在项目中的任意vue组件可以通过 this.$component(); 使用了
推荐文章
移动端调试神器vConsole
一名程序猿的失业之前世今生
教你一步步实现bibibi弹幕功能。
在bibibi推出弹幕功能,我也爱上了边看视频边看吐槽了,现在让我们也来实现这一个功能吧。
首先我们要整理一下思绪我们大概需要实现哪个细节板块呢。
我们最直观的看来,弹幕就是总右往左出现到消失。我们要实现这个动画,弹幕的大小,颜色,出现方式,加速,弹幕的不重叠(这个我想了好久还没有实现,有实现方法可以联系下我)。
我们先来了解一下等会程序里面会用到的相关知识点,等会看代码会更轻松一点。
/*getHeight跟getMeasureHeight的区别
* 实际上在当屏幕可以包裹内容的时候,他们的值相等,只有当view超出屏幕后,才能看出他们的区别:
* getMeasuredHeight()是实际View的大小,与屏幕无关,而getHeight的大小此时则是屏幕的大小。
* 当超出屏幕后, getMeasuredHeight() 等于 getHeight()加上屏幕之外没有显示的大小
*
* */
/Activity生命周期中,onStart, onResume, onCreate都不是真正visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。
//当你屏幕的焦点发生变化时候,想要操作什么也完全可以在这个方法里面执行
// Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。
/*
* AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置
* fillBefore是指动画结束时画面停留在此动画的第一帧;
fillAfter是指动画结束是画面停留在此动画的最后一帧。
Java代码设置如下:
/*****动画结束时,停留在最后一帧*********
setFillAfter(true);
setFillBefore(false);
/*****动画结束时,停留在第一帧*********
setFillAfter(false);
setFillBefore(true);
*
下面我们就来看一下弹幕实现的效果。
弹幕会出现重叠,这个问题还未解决
让我们开始看代码结构吧。
我们字体颜色的xml都写在了colors.xml中了,BarrageItem里面存放着我们的一些变量,而核心代码都在View中
BraagetItem.java
package com.example.bibibibibibibibi;
import android.widget.TextView;
import android.widget.TextView;
/**
* Created by lixueyong on 16/2/19.
*/
public class BarrageItem {
public TextView textView;//文本框
public int textColor;//文本颜色
public String text;//文本对象
public int textSize;//文本的大小
public int moveSpeed;//移动速度
public int verticalPos;//垂直方向显示的位置
public int textMeasuredWidth;//字体显示占据的宽度
}
在BarrageItem里面处理了弹幕的速度,大小,颜色,动画,等事件 在这个文件中 我注释的内容是我对弹幕重叠的操作代码,但是除了问题,有兴趣的可以看一下
package com.example.bibibibibibibibi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import com.example.bibibibibibibibi.R.integer;
/**
* Created by nzx on 16/5/30.
*/
public class BarrageView extends RelativeLayout {
private Context mContext;
private BarrageHandler mHandler = new BarrageHandler();
private Random random = new Random(System.currentTimeMillis());//System.currentTimeMillis()产生一个当前的毫秒
private static final long BARRAGE_GAP_MIN_DURATION = 1000;//两个弹幕的最小间隔时间
private static final long BARRAGE_GAP_MAX_DURATION = 2000;//两个弹幕的最大间隔时间
private int maxSpeed = 10000;//速度,ms
private int minSpeed = 5000;//速度,ms
private int maxSize = 30;//文字大小,dp
private int minSize = 15;//文字大小,dp
private int totalHeight = 0;//整个的高度
private int lineHeight = 0;//每一行弹幕的高度
private int totalLine = 0;//弹幕的行数
private String[] itemText = {"大头死变态", "老圩人最屌了", "唉这把中单是火男,难玩了", "大头是傻子", "世界上最长的路是套路", "英雄联盟最强的是补丁",
"我不会轻易的go die", "嘿嘿", "加班加班"};
private int textCount;//文本的组数
//private RelativeLayout Rparams;
// private List<BarrageItem> itemList = new ArrayList<BarrageItem>();
//实现RelativeLayout的重写的构造方法。
/*
* //content 上下文
//AttributeSet 属性集
//defStyleAttr 预设样式属性集
//defStyleRes 预设样式资源属性集
*
* */
public BarrageView(Context context) {
this(context, null);
}
public BarrageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BarrageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init();
}
private void init() {
textCount = itemText.length;
int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math.random());
mHandler.sendEmptyMessageDelayed(0, duration);
}
@Override
//Activity生命周期中,onStart, onResume, onCreate都不是真正visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。
//当你屏幕的焦点发生变化时候,想要操作什么也完全可以在这个方法里面执行。
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
totalHeight = getMeasuredHeight();
/*getHeight跟getMeasureHeight的区别
* 实际上在当屏幕可以包裹内容的时候,他们的值相等,只有当view超出屏幕后,才能看出他们的区别:
* getMeasuredHeight()是实际View的大小,与屏幕无关,而getHeight的大小此时则是屏幕的大小。
* 当超出屏幕后, getMeasuredHeight() 等于 getHeight()加上屏幕之外没有显示的大小
*
* */
//获取每一行弹幕的最大高度
lineHeight = getLineHeight();
//我们整个弹幕的高度view/每一行的最大弹幕高度=
totalLine = totalHeight / lineHeight;
}
private void generateItem() {
BarrageItem item = new BarrageItem();
//把我们的每行弹幕的行数顺序跟弹幕进行一个随机
String tx = itemText[(int) (Math.random() * textCount)];
//随机弹幕大小
int sz = (int) (minSize + (maxSize - minSize) * Math.random());
item.textView = new TextView(mContext);
item.textView.setText(tx);
item.textView.setTextSize(sz);
item.textView.setTextColor(Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
//这里我们需要传入三个参数 文本对象,文字行数跟大小
item.textMeasuredWidth=(int) getTextWidth(item, tx, sz);
//这是设置弹幕移动速度,实现有快有慢的感觉
item.moveSpeed = (int) (minSpeed + (maxSpeed - minSpeed) * Math.random());
//这里为了实现一个弹幕循环播放的项目,在我们实际中看情况而定
if (totalLine == 0) {
totalHeight = getMeasuredHeight();
lineHeight = getLineHeight();
totalLine = totalHeight / lineHeight;
}
//弹幕在y轴上出现的位置
item.verticalPos = random.nextInt(totalLine) * lineHeight;
// itemList.add(item);
showBarrageItem(item);
}
private void showBarrageItem(final BarrageItem item) {
//paddingLeft是设置布局里面的内容左边的距离,这样我们这就可以让这个弹幕的textview完全消失
int leftMargin = this.getRight() - this.getLeft() - this.getPaddingLeft();
//这里我们通过动态的方式去设置一些我们布局的属性。
// int verticalMargin = getRandomTopMargin();
// item.textView.setTag(verticalMargin);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.topMargin = item.verticalPos;
this.addView(item.textView, params);
Animation anim = generateTranslateAnim(item, leftMargin);
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
//当我们动画结束的时候,清除该条弹幕
public void onAnimationEnd(Animation animation) {
item.textView.clearAnimation();
BarrageView.this.removeView(item.textView);
}
@Override
//动画被取消的时候出发
public void onAnimationRepeat(Animation animation) {
}
});
item.textView.startAnimation(anim);
}
//
private TranslateAnimation generateTranslateAnim(BarrageItem item, int leftMargin) {
//这里我们有四个参数(动画开始的x点,结束点,开始y轴点,结束的y点)
TranslateAnimation anim = new TranslateAnimation(leftMargin, -item.textMeasuredWidth, 0, 0);
//我们设置动画的持续时间,弹幕移动多久,我们就持续多久动画
anim.setDuration(item.moveSpeed);
// Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。
/*
* AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置
* */
anim.setInterpolator(new AccelerateDecelerateInterpolator());
/*
* fillBefore是指动画结束时画面停留在此动画的第一帧;
fillAfter是指动画结束是画面停留在此动画的最后一帧。
Java代码设置如下:
/*****动画结束时,停留在最后一帧*********
setFillAfter(true);
setFillBefore(false);
/*****动画结束时,停留在第一帧*********
setFillAfter(false);
setFillBefore(true);
*
* */
anim.setFillAfter(true);
return anim;
}
/**
* 计算TextView中字符串的长度
*
* @param text 要计算的字符串
* @param Size 字体大小
* @return TextView中字符串的长度
*/
//因为我们的弹幕包裹在一个矩形中
public float getTextWidth(BarrageItem item, String text, float Size) {
Rect bounds = new Rect();
TextPaint paint;
paint = item.textView.getPaint();
//这里参数是获取文本对象,开始的长度,结束的长度,我们绘制好的矩形框
paint.getTextBounds(text, 0, text.length(), bounds);
return bounds.width();
}
/**
* 获得每一行弹幕的最大高度
*
* @return
*/
private int getLineHeight() {
BarrageItem item = new BarrageItem();
String tx = itemText[0];
item.textView = new TextView(mContext);
item.textView.setText(tx);
item.textView.setTextSize(maxSize);
Rect bounds = new Rect();
TextPaint paint;
paint = item.textView.getPaint();
paint.getTextBounds(tx, 0, tx.length(), bounds);
return bounds.height();
}
class BarrageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
generateItem();
//每个弹幕产生的间隔时间随机
int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math.random());
//多个消息可以使用同一个handler, 通过what不同区分不同的消息来源, 从而获取消息内容
this.sendEmptyMessageDelayed(0, duration);
}
}
//记录一下当前在显示弹幕的高度,避免弹幕出现重叠
private Set<integer> existMarginValues = new HashSet<>();
private int linesCount;
// private int getRandomTopMargin()
// {
// //计算弹幕的空间高度
// if(totalLine==0)
// {
// totalLine=Rparams.getBottom()-Rparams.getTop()-Rparams.getPaddingTop()
// -Rparams.getPaddingBottom();
// if (totalHeight==0) {
// totalHeight = getMeasuredHeight();
// lineHeight = getLineHeight();
// totalLine = totalHeight / lineHeight;
// }
// //检查重叠
// while (true) {
// int randomIndex = (int) (Math.random() * linesCount);
// int marginValue = (int) (randomIndex * (totalLine / linesCount));
//
// if (!existMarginValues.contains(marginValue)) {
// existMarginValues.add(marginValue);
// return marginValue;
// }
// }
//
//
// }
}
BarrageActivity.java
在这个类里面我们可以去进行一些事件,但是我这里没有去处理,大家按自己的需求来。
package com.example.bibibibibibibibi;
import android.app.Activity;
import android.os.Bundle;
/**
* Created by lixueyong on 16/2/19.
*/
public class BarrageActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barrage);
}
}
还有一些关于颜色的xml 大家可以通过demo去看下了,这样我们就实现了类似于bibibi弹幕的功能,是不是很简单(ps:哪里简单了(手动蔑视))。
等我把弹幕重叠的bug解决,我在博客上也会更新的。
demo下载地址:http://download.csdn.net/detail/ningzhouxu/9535392
今后我会更新更多有趣好玩的博客的。
以上是关于教你一步步封装vue的toast和loading组件的主要内容,如果未能解决你的问题,请参考以下文章
source insight 教你一步步建立linux源码工程
Android 教你一步步搭建MVP+Retrofit+RxJava网络请求框架
带你一步步剖析Retrofit 源码解析:一款基于 OkHttp 实现的网络请求框架