京东APP首页的垂直跑马灯实现公告播放效果,之前用过自定义View来实现,最近看到了ViewFlipper。。。突然萌发了想用他来实现该效果的想法。。。
官方文档~
Simple ViewAnimator that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each child at a regular interval.
在这贴上了他的继承关系,大家可以看到他自带动画效果啦~
不说别的了,直接撸代码,详细说明大家看注释吧~(附两个GIF看效果,因为录制软件的问题,有重影,,,但是大家自己写完之后是不会出现问题的,同时我将时间间隔设置为了1秒,节约时间~~)
public class NoticeView extends ViewFlipper implements View.OnClickListener { private Context mContext; private ArrayList<Notice> mArrayList; private OnNoticeClickListener mListener; public NoticeView(Context context) { super(context); } public NoticeView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; init(mContext); } private void init(Context context) { mArrayList = new ArrayList<>(); setFlipInterval(1000);//设置滚动间隔时间 setPadding(SizeUtils.dp2px(context, 5f), SizeUtils.dp2px(context, 5f), SizeUtils.dp2px(context, 5f), SizeUtils.dp2px(context, 5f)); setInAnimation(AnimationUtils.loadAnimation(context, R.anim.notice_in)); setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.notice_out)); } public void addNotice(ArrayList<Notice> notices) { mArrayList = notices; removeAllViews(); for (int i = 0; i < mArrayList.size(); i++) { Notice notice = notices.get(i); int titleLength = notice.getTitle().length();//取出来标题的文案的长度 int contentLength = notice.getContent().length();//取出来内容的文案的长度 String string = notice.getTitle() + " " + notice.getContent(); int color = 0; if (TextUtils.isEmpty(notice.getTitleColor())) { color = Color.RED; } else { color = Color.parseColor(notice.getTitleColor()); } SpannableString spannableString = SpannableStrings.setTextColor(string, color, 0, titleLength); TextView textView = new TextView(mContext); textView.setSingleLine(true); textView.setText(spannableString); textView.setTextSize(20f);//字体大小 textView.setEllipsize(TextUtils.TruncateAt.END); textView.setGravity(Gravity.CENTER_VERTICAL); textView.setTag(i); textView.setOnClickListener(this); NoticeView.this.addView(textView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); } } @Override public void onClick(View v) { int position = (int) v.getTag(); Notice notice = mArrayList.get(position); if (mListener != null) { mListener.onNotieClick(position, notice); } } /** * 接口回调 */ public interface OnNoticeClickListener { void onNotieClick(int position, Notice notice); } public void setListener(OnNoticeClickListener listener) { mListener = listener; } }
关于SpannableString的工具类(本文用到的);
/** * 设置部分文本的字体颜色 * * @param text 文本 * @param textColor 文本颜色 * @param start 开始位置 * @param end 结束位置(不包含) * @return SpannableString */ public static SpannableString setTextColor(String text, int textColor, int start, int end) { SpannableString spannableString = new SpannableString(text); spannableString.setSpan(new ForegroundColorSpan(textColor), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE); return spannableString; }
/** * 设置部分文本的背景色和字体颜色 * * @param text 文本 * @param backgroundColor 背景色 * @param textColor 文本色 * @param backgroundArr 背景色设置文本位置 * @param textColorArr 文本颜色位置 * @return SpannableString */ public static SpannableString setTextBackgroundAndTextColor(String text, int backgroundColor, int textColor, int[] backgroundArr, int[] textColorArr) { SpannableString spannableString = new SpannableString(text); spannableString.setSpan(new BackgroundColorSpan(backgroundColor), backgroundArr[0], backgroundArr[1], Spanned.SPAN_INCLUSIVE_INCLUSIVE); spannableString.setSpan(new ForegroundColorSpan(textColor), textColorArr[0], textColorArr[1], Spanned.SPAN_INCLUSIVE_INCLUSIVE); return spannableString; }
Activity中就调用了一个方法而已~;
private void init() { tv_jd = (TextView) findViewById(R.id.tv_jd); SpannableString spannableString = SpannableStrings.setTextBackgroundAndTextColor("京东快报:", Color.RED, Color.WHITE, new int[]{2, 4}, new int[]{2, 4}); tv_jd.setText(spannableString); notice_view = (NoticeView) findViewById(R.id.notice_view); ArrayList<Notice> list = new ArrayList<>(); Notice notice = new Notice("大促", "新年好货马上抢", "#ff0000", null, "www.baidu.com"); Notice notice2 = new Notice("爆", "9.9元好东西啊~~~", "#0000ff", null, "www.google.com"); Notice notice3 = new Notice("疯子", "疯子一样的抢购,来吧", "#00ff00", null, "www.qq.com"); list.add(notice); list.add(notice2); list.add(notice3); notice_view.addNotice(list); notice_view.setListener(new NoticeView.OnNoticeClickListener() { @Override public void onNotieClick(int position, Notice notice) { T.showShort(NoticeViewActivity.this, "url = " + notice.getUrl()); } }); notice_view.startFlipping(); }
进入的动画效果:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!--平移--> <translate android:duration="@android:integer/config_mediumAnimTime" android:fromYDelta="50%p" android:toYDelta="0"/> <!--渐变--> <alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="0.0" android:toAlpha="1.0"/> </set>
出去的动画效果:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!--平移--> <translate android:duration="@android:integer/config_mediumAnimTime" android:fromYDelta="0" android:toYDelta="-50%p"/> <!--渐变--> <alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="1.0" android:toAlpha="0.0"/> </set>
作者:Ivenes