Android新闻广告条滚动效果
程序员文章站
2024-03-07 20:01:51
项目中需要用到类似公告栏的控件,能用的基本不支持多行显示,于是只好自己动手,苦于没有自定义过一个像样的控件,借鉴android公告条demo,实现了多行向上滚动的控件。在原...
项目中需要用到类似公告栏的控件,能用的基本不支持多行显示,于是只好自己动手,苦于没有自定义过一个像样的控件,借鉴android公告条demo,实现了多行向上滚动的控件。在原控件基础之上添加如下功能:
•传入数据分页显示
•添加left drawable
•手指触摸事件处理
•添加3d动画翻滚效果
效果图
源码
package com.android.view; import android.content.context; import android.content.res.typedarray; import android.graphics.camera; import android.graphics.matrix; import android.graphics.paint; import android.graphics.drawable.drawable; import android.os.handler; import android.os.looper; import android.text.textpaint; import android.text.textutils; import android.util.attributeset; import android.util.typedvalue; import android.view.gravity; import android.view.motionevent; import android.view.view; import android.view.view.onclicklistener; import android.view.animation.accelerateinterpolator; import android.view.animation.alphaanimation; import android.view.animation.animation; import android.view.animation.animationset; import android.view.animation.transformation; import android.view.animation.translateanimation; import android.widget.framelayout; import android.widget.linearlayout; import android.widget.textview; import com.sd2w.market.client.r; import java.util.arraylist; import java.util.list; import static android.view.viewgroup.layoutparams.match_parent; import static android.view.viewgroup.layoutparams.wrap_content; /** * 公告滚动区 * * @author 祁连山 * @version 1.0 * @date 2016-08-17 */ public class rollingview extends framelayout implements onclicklistener { // 默认动画执行时间 private static final int animation_duration = 1000; // 延迟滚动时间间隔 private long mduration = 3000; // 字体颜色 private int mtextcolor = 0xff000000; // 点击后字体颜色 private int mclickcolor = 0xff0099ff; // 字体大小 private float mtextsize = 14; // 行间距 private int mtextpadding = 10; // 画笔 private paint mpaint; // 默认每页信息数 private int mpagesize = 3; // 最后一页余数 private int muplimited = mpagesize; // 当前显示页码 private int mcurrentpage = 0; // 总分页数 private int mpagecount; // 左图片 private int mleftdrawable; // 分页数据对象 private list<linearlayout> mrollingpages; // 默认动画 private animationset menteranimset; private animationset mexitanimset; private rollingrunnable mrunnable; private handler mhandler; private onitemclicklistener mclicklistener; // 布局参数 private layoutparams mframeparams; private linearlayout.layoutparams mlinearparams; //menterdownanim,moutup分别构成向下翻页的进出动画 private rotate3danimation menterdownanim; private rotate3danimation mexitupanim; //menterupanim,moutdown分别构成向下翻页的进出动画 private rotate3danimation menterupanim; private rotate3danimation mexitdownanim; public rollingview(context context) { this(context, null); } public rollingview(context context, attributeset attrs) { super(context, attrs); // 从xml中获取属性 typedarray array = getcontext().obtainstyledattributes(attrs, r.styleable.rollingview); mtextsize = array.getdimension(r.styleable.rollingview_textsize, mtextsize); mtextcolor = array.getcolor(r.styleable.rollingview_textcolor, mtextcolor); array.recycle(); // 创建默认显示隐藏动画 createenteranimation(); createexitanimation(); // 初始化画笔 mpaint = new textpaint(); // 初始化handler对象 mhandler = new handler(looper.getmainlooper()); menterdownanim = createanim(-90, 0, true, true); mexitupanim = createanim(0, 90, false, true); menterupanim = createanim(90, 0, true, false); mexitdownanim = createanim(0, -90, false, false); } private rotate3danimation createanim(float start, float end, boolean turnin, boolean turnup) { final rotate3danimation rotation = new rotate3danimation(start, end, turnin, turnup); rotation.setduration(300); rotation.setfillafter(false); rotation.setinterpolator(new accelerateinterpolator()); return rotation; } /** * 设置分页大小 * * @param pagesize */ public void setpagesize(int pagesize) { this.mpagesize = this.muplimited = pagesize; } /** * 设置延迟时间 * * @param millionseconds */ public void setdelayedduration(long millionseconds) { this.mduration = millionseconds; } /** * 设置显示动画 * * @param animation */ public void setenteranimation(animationset animation) { menteranimset = animation; } /** * 设置隐藏动画 * * @param animation */ public void setexitanimation(animationset animation) { mexitanimset = animation; } /** * 设置行距 * * @param padding */ public void settextpadding(int padding) { this.mtextpadding = padding; } /** * 设置点击后字体颜色 * * @param color */ public void setclickcolor(int color) { this.mclickcolor = color; } /** * 设置左图片 * * @param drawable */ public void setleftdrawable(int drawable) { this.mleftdrawable = drawable; } /** * 设置点击事件 * * @param clicklistener */ public void setonitemclicklistener(onitemclicklistener clicklistener) { if (null == clicklistener) return; this.mclicklistener = clicklistener; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); // 如果是未指定大小,那么设置宽为300px int exceptwidth = 300; int exceptheight = 0; // 计算高度,如果将高度设置为textsize会很丑,因为文字有默认的上下边距。 if (measurespec.getmode(heightmeasurespec) != measurespec.exactly) { if (mtextsize > 0) { mpaint.settextsize(mtextsize); paint.fontmetrics fontmetrics = mpaint.getfontmetrics(); exceptheight = (int) (fontmetrics.bottom - fontmetrics.top); } } int width = resolvesize(exceptwidth, widthmeasurespec); int height = resolvesize(exceptheight, heightmeasurespec); setmeasureddimension(width, height); } public void setrollingtext(list<string> array) { if (null == array || array.isempty()) return; this.removeallviews(); if (mrollingpages == null) { mrollingpages = new arraylist<>(); } mrollingpages.clear(); // 计算商数 int quotient = array.size() / mpagesize; // 计算余数 int remainder = array.size() % mpagesize; // 计算需要创建多少页 mpagecount = remainder == 0 ? quotient : quotient + 1; for (int i = 0; i < mpagecount; i++) { // 创建一个布局 linearlayout container = createcontainer(); if (i == mpagecount - 1) { muplimited = remainder == 0 ? mpagesize : remainder; } for (int n = 0; n < muplimited; n++) { textview textview = createtextview(array.get(mpagesize * i + n)); container.addview(textview); } // 添加到分页中 mrollingpages.add(container); this.addview(container); } // 初始化显示第一页 mcurrentpage = 0; mrollingpages.get(mcurrentpage).setvisibility(visible); this.setvisibility(mrollingpages.get(mcurrentpage)); } /** * 创建页对象 * * @return */ private linearlayout createcontainer() { if (mframeparams == null) { mframeparams = new layoutparams(match_parent, wrap_content); mframeparams.gravity = gravity.center_vertical; } linearlayout container = new linearlayout(getcontext()); container.setlayoutparams(mframeparams); container.setorientation(linearlayout.vertical); return container; } private void setvisibility(linearlayout container) { int count = container.getchildcount(); for (int i = 0; i < count; i++) { container.getchildat(i).setvisibility(visible); } } /** * 创建页内容对象 * * @param text * @return */ private textview createtextview(string text) { if (mlinearparams == null) { mlinearparams = new linearlayout.layoutparams(wrap_content, wrap_content); mlinearparams.gravity = gravity.center_vertical; } textview textview = new textview(getcontext()); textview.setlayoutparams(mlinearparams); textview.setsingleline(); textview.setpadding(mtextpadding, mtextpadding, mtextpadding, mtextpadding); textview.setellipsize(textutils.truncateat.end); textview.settextcolor(mtextcolor); textview.setvisibility(invisible); textview.settext(text); if (mleftdrawable > 0) { drawable drawable = getcontext().getresources().getdrawable(mleftdrawable); // bitmap bitmap = bitmapfactory.decoderesource(getcontext().getresources(), mleftdrawable); // drawable drawable = new bitmapdrawable(getcontext().getresources(), bitmap); drawable.setbounds(0, 0, 10, 10); textview.setcompounddrawablepadding(10); textview.setcompounddrawables(drawable, null, null, null); } textview.setonclicklistener(this); // 设置字体大小 if (mtextsize > 0) { textview.settextsize(typedvalue.complex_unit_px, mtextsize); } return textview; } private void createenteranimation() { menteranimset = new animationset(false); translateanimation translateanimation = new translateanimation(0, 0, 0, 0, translateanimation.relative_to_parent, 1f, translateanimation.relative_to_self, 0f); alphaanimation alphaanimation = new alphaanimation(0f, 1f); menteranimset.addanimation(translateanimation); menteranimset.addanimation(alphaanimation); menteranimset.setduration(animation_duration); } private void createexitanimation() { mexitanimset = new animationset(false); translateanimation translateanimation = new translateanimation(0, 0, 0, 0, translateanimation.relative_to_self, 0f, translateanimation.relative_to_parent, -1f); alphaanimation alphaanimation = new alphaanimation(1f, 0f); mexitanimset.addanimation(translateanimation); mexitanimset.addanimation(alphaanimation); mexitanimset.setduration(animation_duration); } @override public boolean ontouchevent(motionevent event) { int action = event.getaction(); switch (action) { case motionevent.action_down: pause(); break; case motionevent.action_move: case motionevent.action_up: case motionevent.action_cancel: resume(); break; } return true; } public void resume() { // 只有一页时不进行切换 if (mpagecount < 1) return; if (mrunnable == null) { mrunnable = new rollingrunnable(); } else { mhandler.removecallbacks(mrunnable); } mhandler.postdelayed(mrunnable, mduration); } public void pause() { if (mrunnable != null) { mhandler.removecallbacks(mrunnable); } } @override public void onclick(view v) { if (null == mclicklistener) return; textview textview = (textview) v; mclicklistener.onitemclick(textview); textview.settextcolor(mclickcolor); } /** * 隐藏当前页,显示下一页任务 */ public class rollingrunnable implements runnable { @override public void run() { // 隐藏当前页 linearlayout currentview = mrollingpages.get(mcurrentpage); currentview.setvisibility(invisible); if (mexitanimset != null) { currentview.startanimation(mexitanimset);// mexitupanim); } mcurrentpage++; if (mcurrentpage >= mpagecount) { mcurrentpage = 0; } // 显示下一页 linearlayout nextview = mrollingpages.get(mcurrentpage); nextview.setvisibility(visible); setvisibility(nextview); if (menteranimset != null) { nextview.startanimation(menteranimset);// menterdownanim); } mhandler.postdelayed(this, mduration); } } public class rotate3danimation extends animation { private final float mfromdegrees; private final float mtodegrees; private final boolean mturnin; private final boolean mturnup; private float mcenterx; private float mcentery; private camera mcamera; public rotate3danimation(float fromdegrees, float todegrees, boolean turnin, boolean turnup) { mfromdegrees = fromdegrees; mtodegrees = todegrees; mturnin = turnin; mturnup = turnup; } @override public void initialize(int width, int height, int parentwidth, int parentheight) { super.initialize(width, height, parentwidth, parentheight); mcamera = new camera(); mcentery = getheight() / 2; mcenterx = getwidth() / 2; } @override protected void applytransformation(float interpolatedtime, transformation t) { final float fromdegrees = mfromdegrees; float degrees = fromdegrees + ((mtodegrees - fromdegrees) * interpolatedtime); final float centerx = mcenterx; final float centery = mcentery; final camera camera = mcamera; final int derection = mturnup ? 1 : -1; final matrix matrix = t.getmatrix(); camera.save(); if (mturnin) { camera.translate(0.0f, derection * mcentery * (interpolatedtime - 1.0f), 0.0f); } else { camera.translate(0.0f, derection * mcentery * (interpolatedtime), 0.0f); } camera.rotatex(degrees); camera.getmatrix(matrix); camera.restore(); matrix.pretranslate(-centerx, -centery); matrix.posttranslate(centerx, centery); } } public interface onitemclicklistener { void onitemclick(textview v); } }
使用
// 初始化号外列表 list<string> haowaiarray = new arraylist<>(); haowaiarray.add("[母婴天地] 买尿不湿送婴儿手口湿巾"); haowaiarray.add("[利民商店] 满100免费配送"); haowaiarray.add("[果之家] 泰国金枕榴莲8元/kg"); haowaiarray.add("[户外运动] 户外运动专业装备搜集"); haowaiarray.add("[天天特价] 只要9.9还包邮"); haowaiarray.add("[尖端潮品] 折叠电动车"); haowaiarray.add("[黑科技] 智能vr带你装13"); haowaiarray.add("[旅行必备] 太阳能充电宝-永不断电"); // 绑定数据 mrollingview.setpagesize(4); mrollingview.setclickcolor(0xff888888); mrollingview.setleftdrawable(r.drawable.drawable_red_dot); mrollingview.setrollingtext(haowaiarray); mrollingview.setonitemclicklistener(this); ... @override public void onitemclick(textview v) { // handle item click event } @override public void onresume() { super.onresume(); mrollingview.resume(); } @override public void onpause() { super.onpause(); mrollingview.pause(); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。