浅谈android中仅仅使用一个TextView实现高仿京东,淘宝各种倒计时

本文介绍如何仅使用一个TextView实现类似京东、淘宝的活动倒计时效果,通过优化原有多个TextView的拼接方式,提高代码效率和扩展性。采用CountDownTimer和SpannableString结合,设计基类和子类实现不同样式的倒计时,同时通过TimerUtils管理类增强代码封装性和隐藏性。
摘要由CSDN通过智能技术生成

  今天给大家带来的是仅仅使用一个TextView实现一个高仿京东、淘宝、唯品会等各种电商APP的活动倒计时。最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习。为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了。不知道从何处开始优化。然后我就查看京东,饿了么,唯品会等各个APP的倒计时,并在开发者中打开层级界面显示,发现他们都有一个共同的特点就是一个View,没有使用多个TextView来拼接。相信大家都知道仅仅使用一个TextView比使用多个TextView拼接去实现的优势吧,下面不妨来看看几个界面就知道了。




看到这个,大家心里自然就想到了自定义View来实现吧。对,自定义View确实可以实现这样的效果。但是今天我们不采用自定义View来做。而是使用一个TextView来实现。

由于项目经理要求此次优化的代码具有可扩展性。所以此次代码的设计加了一些面向对象的知识。有一些自己的设计和架构的思路。

此次demo的设计思路:

          1、编写一个倒计时的基类作为实现最普通和最基本的倒计时的功能,没有任何样式,让这个基类去继承CountDownTimer类,并且在该基类中

保存一个TextView的对象,并且把每次倒计时的数据,显示在TextView中,然后公布一个getmDateTv()方法返回一个TextView对象即可。然后只要拿到这个TextView对象显示界面的布局中即可。非常方便。

          2、然后不同样式的倒计时,只需要编写不同的子类去继承最普通的倒计时基类即可,然后重写其中的设置数据和设置样式的两个方法即可,然后就能给最普通的倒计时添加不同的样式。下次如果需要扩展新的倒计时样式,不需要改变其他类的代码,只需编写一个普通倒计时的派生类重写两个方法即可,使得可扩展性更灵活。

          3、然后通过一个TimerUtils管理类,去集中承担子类和父类压力,让子类和父类所需实现功能分担到TimerUtils类中,并且该TimerUtils管理类是与客户端唯一打交道的类,比如获得倒计时对象以及获得倒计时的TextView对象都通过这个管理类分配,避免客户端直接与倒计时的基类和子类打交道。从而使得类的封装性和隐藏性得到体现。

下面可以看下这个Demo设计的简单的UML类图:


通过以上思路分析下面我们就看看此次Demo的实现需要用到哪些知识点.

            1、CountDownTimer类的用法。

    2、SpannableString的用法。

    3、MikyouCountDownTimer的封装。

    4、自定义MikyouBackgroundSpan的实现。

一、通过以上的分析我们首先得复习一下有关CountDownTimer的知识,CountDownTimer是一个很简单的类我们可以看下的它的源码,它的用法自然就知道了。

CountDownTimer是一个抽象类。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package android.os;

public abstract class CountDownTimer {
    public CountDownTimer(long millisInFuture, long countDownInterval) {
        throw new RuntimeException("Stub!");
    }

    public final synchronized void cancel() {
        throw new RuntimeException("Stub!");
    }

    public final synchronized CountDownTimer start() {
        throw new RuntimeException("Stub!");
    }

    public abstract void onTick(long var1);

    public abstract void onFinish();
}

可以看到倒计时的总时长就是millisFuture,和countDownInterVal间隔步长默认是1000ms,所以数据都是通过其构造器进行初始化,然后需要去重写一个回调方法onTick,

里面的一个参数就是每隔相应的步长后剩余的时间毫秒数。然后我们只需要在onTick方法中将每隔1000ms时间毫秒数进行时间格式化即可得到相应时间格式的倒计时这就是实现了最基本倒计时样式。格式化倒计时格式采用的是apache中的common的lang包中DurationFormatUtils类中的formatDuration,通过传入一个时间格式就会自动将倒计时转换成相应的mTimePattern的样式(HH:mm:ss或dd天HH时mm分ss秒).

二、复习一下有关SpannableString的用法。

在Android中EditText用于编辑文本,TextView用于显示文本,但是有时候我们需要对其中的文本进行样式等方面的设置。Android为我们提供了SpannableString类来对指定文本进行处理。

1) ForegroundColorSpan        文本颜色

private void setForegroundColorSpan() {    
    SpannableString spanString = new SpannableString("前景色");    
    ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);    
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
    tv.append(spanString);    
}    


2) BackgroundColorSpan 文本背景色 

private void setBackgroundColorSpan() {    
    SpannableString spanString = new SpannableString("背景色");    
    BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);    
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
    tv.append(spanString);    
}   


3) StyleSpan         字体样式:粗体、斜体等


private void setStyleSpan() {    
    SpannableString spanString = new SpannableString("粗体斜体");    
    StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);    
    spanString.setSpan(span, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
    tv.append(spanString);    
}    


4) RelativeSizeSpan 相对大小


private void setRelativeFontSpan() {  
    SpannableString spanString = new SpannableString("字体相对大小");  
    spanString.setSpan(new RelativeSizeSpan(2.5f), 0, 6,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);      
}  


5) TypefaceSpan         文本字体


private void setTypefaceSpan() {  
    SpannableString spanString = new SpannableString("文本字体");  
    spanString.setSpan(new TypefaceSpan("monospace"), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanText);  
}  


6) URLSpan 文本超链接

private void addUrlSpan() {    
    SpannableString spanString = new SpannableString("超链接");    
    URLSpan span = new URLSpan("http://www.baidu.com");    
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
    tv.append(spanString);    
}    


7) ImageSpan         图片

private void addImageSpan() {    
    SpannableString spanString = new SpannableString(" ");    
    Drawable d = getResources().getDrawable(R.drawable.ic_launcher);    
    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());    
    ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);    
    spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);    
    tv.append(spanString);    
}   


8) ClickableSpan                 文本有点击事件

private TextView textView;  
textView = (TextView)this.findViewById(R.id.textView);  
String text = "显示Activity";  
SpannableString spannableString = new SpannableString(text);  
spannableString.setSpan(new ClickableSpan() {  
    @Override  
    public void onClick(View widget) {  
        Intent intent = new Intent(Main.this,OtherActivity.class);  
        startActivity(intent);  
    }  
    // 表示点击整个text的长度都有效触发这个事件  
}, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  
textView.setText(spannableString);  
textView.setMovementMethod(LinkMovementMethod.getInstance());  


9) UnderlineSpan         下划线

private void addUnderLineSpan() {    
    SpannableString spanString = new SpannableString("下划线");    
    UnderlineSpan span = new UnderlineSpan();    
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊喵先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值