在线直播系统源码,滚动式内容展示控件
在线直播系统源码,滚动式内容展示控件实现的相关代码
源码:
1 | public class RollView extends FrameLayout {<br> private static final int DEFAULTTEXTSIZE = 16 ;<br> private static final int DEFAULTTEXTHEIGHT = 72 ;<br> private List<?> contents = new LinkedList<>();<br> private float textSize;<br> private int textColor = Color.BLACK;<br> //当前显示内容在集合中的下标<br> private int curIndex = -1;<br> //下一个显示的下标<br> private TextView curText;<br> private TextView nextText;<br> private int hSize;<br> private int wSize;<br> private TranslateAnimation outAnim;<br> private TranslateAnimation inAnim;<br> //是否执行动画中<br> private boolean isAnimationing = false;<br> private onItemClickListener listener;<br> private MyHandler handler = new MyHandler(this);<br> public RollView(Context context) {<br> this(context, null);<br> }<br> public RollView(Context context, @Nullable AttributeSet attrs) {<br> this(context, attrs, 0);<br> }<br> public RollView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {<br> super(context, attrs, defStyleAttr);<br> init(context, attrs);<br> }<br> private void init(Context context, AttributeSet attrs) {<br> View view = LayoutInflater.from(context).inflate(R.layout.custom_rollview_layout, this);<br> curText = ((TextView) view.findViewById(R.id.curText));<br> nextText = ((TextView) view.findViewById(R.id.nextText));<br> TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RollView);<br> float tmpTextSize = ta.getInteger(R.styleable.RollView_rollSize, DEFAULTTEXTSIZE);<br> textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tmpTextSize, getResources().getDisplayMetrics());<br> int colorRes = ta.getResourceId(R.styleable.RollView_rollColor, -1);<br> int colorRes2 = ta.getColor(R.styleable.RollView_rollColor, -1);<br> curText.setOnClickListener(new OnClickListener() {<br> @Override<br> public void onClick(View v) {<br> //如果是执行动画中,就不响应点击事件<br> if (isAnimationing) {<br> return;<br> } else {<br> if (listener != null) {<br> listener.onClick(curIndex);<br> }<br> }<br> }<br> });<br> if (colorRes != -1) {<br> textColor = colorRes;<br> } else if (colorRes2 != -1) {<br> textColor = colorRes2;<br> }<br> curText.setTextSize(textSize);<br> curText.setTextColor(textColor);<br> nextText.setTextSize(textSize);<br> nextText.setTextColor(textColor);<br> ta.recycle();<br> }<br> public void setListener(onItemClickListener listener) {<br> this.listener = listener;<br> }<br> /**<br> * 可以是自定义类型,只需要重新toString() 方法<br> * @param contents<br> */<br> public void setObjContents(List<?> contents) {<br> if (contents == null || contents.size() == 0) {<br> return;<br> }<br> this.contents.clear();<br> List<String> list = new LinkedList<>();<br> for (Object content : contents) {<br> list.add(content.toString());<br> }<br> setContents(list);<br> }<br> public void setContents(List<String> contents) {<br> if (contents == null || contents.size() == 0) {<br> return;<br> }<br> this.contents = contents;<br> initData();<br> }<br> private void initData() {<br> curIndex = 0;<br> if (contents.size() > 0) {<br> curText.setText(contents.get(0).toString());<br> }<br> if (contents.size() > 1) {<br> nextText.setText(contents.get(1).toString());<br> }<br> }<br> @Override<br> protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {<br> super.onMeasure(widthMeasureSpec, heightMeasureSpec);<br> int wMode = MeasureSpec.getMode(widthMeasureSpec);<br> int hMode = MeasureSpec.getMode(heightMeasureSpec);<br> hSize = MeasureSpec.getSize(heightMeasureSpec);<br> wSize = MeasureSpec.getSize(widthMeasureSpec);<br> switch (hMode) {<br> case MeasureSpec.EXACTLY:<br> break;<br> case MeasureSpec.AT_MOST:<br> case MeasureSpec.UNSPECIFIED:<br> hSize = DEFAULTTEXTHEIGHT;<br> break;<br> }<br> setMeasuredDimension(wSize, hSize);<br> outAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -hSize);<br> //动画结束时,将控件还原到初始化状态,必须设置这个<br> outAnim.setFillEnabled(true);<br> outAnim.setAnimationListener(new Animation.AnimationListener() {<br> @Override<br> public void onAnimationStart(Animation animation) {<br> isAnimationing = true;<br> }<br> @Override<br> public void onAnimationEnd(Animation animation) {<br> isAnimationing = false;<br> curIndex++;<br> curIndex = curIndex % contents.size();//滚动到最后一条数据了,下一条显示第一条数据<br> int nextIndex = (curIndex + 1) % contents.size();//获取nextText 需要显示的下一条数据的下标<br> /**<br> * 这里的含义是:动画结束后,控件还原到初始化状态,<br> * curText 就需要显示滚动后的 nextText 的内容,起到界面没有视觉差<br> * nextText 就需要显示,下下条数据,为了下次滚动做准备<br> */<br> curText.setText(contents.get(curIndex).toString());<br> nextText.setText(contents.get(nextIndex).toString());<br> //动画结束后,延迟3秒继续滚动<br> handler.sendEmptyMessageDelayed(0, 2000);<br> }<br> @Override<br> public void onAnimationRepeat(Animation animation) {<br> }<br> });<br> outAnim.setDuration(1000);<br> inAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, hSize, Animation.ABSOLUTE, 0);<br> inAnim.setFillEnabled(true);<br> inAnim.setDuration(1000);<br> }<br> /**<br> * 开始滚动,数量必须大于1才会滚动,每3秒滚动一次<br> */<br> public void startRoll() {<br> if (contents.isEmpty() || contents.size() == 1) {<br> return;<br> }<br> handler.sendEmptyMessageDelayed(0, 2000);<br> }<br> private void roll() {<br> if (isAnimationing) {<br> return;<br> }<br> curText.startAnimation(outAnim);<br> nextText.startAnimation(inAnim);<br> }<br> private static class MyHandler extends Handler {<br> private WeakReference<RollView> weakReference;<br> public MyHandler(RollView rollView) {<br> this.weakReference = new WeakReference<>(rollView);<br> }<br> @Override<br> public void handleMessage(Message msg) {<br> RollView rollView = weakReference.get();<br> if (rollView == null) {<br> return;<br> }<br> rollView.roll();<br> }<br> }<br> public interface onItemClickListener {<br> /**<br> * 这里也可以用泛型,返回当前显示的自定义数据,为了简单,这里就只返回当前点击的位置<br> * @param position<br> */<br> void onClick(int position);<br> }<br>} |
自定义的布局:
1 | <?xml version= "1.0" encoding= "utf-8" ?><br><FrameLayout xmlns:android= "http://schemas.android.com/apk/res/android" <br> android:id= "@+id/textContent" <br> android:layout_width= "match_parent" <br> android:layout_height= "match_parent" <br> android:orientation= "vertical" ><br> <TextView<br> android:id= "@+id/nextText" <br> android:layout_width= "match_parent" <br> android:layout_height= "match_parent" <br> android:layout_gravity= "center_vertical" <br> android:background= "@color/white" <br> android:gravity= "center_vertical" <br> android:maxLines= "1" <br> android:text= "nextText" <br> android:textColor= "@color/black" <br> android:textSize= "@dimen/sp_16" /><br> <TextView<br> android:id= "@+id/curText" <br> android:layout_width= "match_parent" <br> android:layout_height= "match_parent" <br> android:layout_gravity= "center_vertical" <br> android:background= "@color/white" <br> android:gravity= "center_vertical" <br> android:maxLines= "1" <br> android:text= "curText" <br> android:textColor= "@color/black" <br> android:textSize= "@dimen/sp_16" /><br></FrameLayout> |
自定义属性:
1 | <declare-styleable name= "RollView" ><br> <attr name= "rollSize" format= "integer" /><br> <attr name= "rollColor" format= "reference|color" /><br> </declare-styleable> |
使用:
1 | <RollView<br> android:id= "@+id/rollView" <br> android:layout_width= "match_parent" <br> android:layout_height= "@dimen/dp_56" <br> android:background= "@color/white" <br> android:paddingLeft= "@dimen/dp_20" <br> app:rollSize= "20" /> |
代码:
1 | List<String> contents = new LinkedList<>();<br>contents.add( "lingtao" );<br>contents.add( "lingtao1" );<br>contents.add( "lingtao2" );<br>contents.add( "lingtao3" );<br>rollView.setContents(contents);<br>rollView.setListener( new RollView.onItemClickListener() {<br> @Override <br> public void onClick( int position) {<br> LogUtils.d( "TestActivity_log" , "onClick: " + contents.get(position));<br> }<br>});<br>rollView.startRoll(); |
以上就是 在线直播系统源码,滚动式内容展示控件实现的相关代码,更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现