Android 公告新闻消息资讯之垂直滚动效果
垂直滚动新闻栏的实现原理:
就是一个自定义的LinearLayout,并且textView能够循环垂直滚动,而且条目可以点击,显示区域最多显示2个条目,并且还有交替的属性垂直移动的动画效果,通过线程来控制滚动的实现。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
自定义属性:
<style name="AppTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
<declare-styleable name="NoticeView">
<attr name="gap" format="integer" />
<attr name="animDuration" format="integer" />
</declare-styleable>
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
自定义控件的获取属性方法都一样:
//获取自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.NoticeView);
mAdverHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, jdAdverHeight, getResources().getDisplayMetrics());
int gap = array.getInteger(R.styleable.NoticeView_gap, mGap);
//关闭清空TypedArray,防止内存泄露
int animDuration = array.getInteger(R.styleable.NoticeView_animDuration, mAnimDuration);
//关闭清空TypedArray
array.recycle();
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
自定义条目布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/blue_line_bg4"
android:layout_marginTop="10dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center_vertical"
android:layout_marginBottom="10dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/blue_line_bg"
android:padding="5dp"
android:text="最新"
android:textColor="#ff0000" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="价格惊呆!电信千兆光纤上市"
android:textColor="#000000"
android:textSize="12sp" >
</TextView>
</LinearLayout>
...........................................................................................................................
//适配器
package com.notice.scroll;
import java.util.List;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class NoticeAdapter {
private List<NoticeEntity> mDatas;
public NoticeAdapter(List<NoticeEntity> datas) {
this.mDatas = datas;
if (datas == null || datas.isEmpty()) {
throw new RuntimeException("nothing to show");
}
}
/**
* 获取数据的条数
*
* @return
*/
public int getCount() {
return mDatas == null ? 0 : mDatas.size();
}
/**
* 获取摸个数据
*
* @param position
* @return
*/
public NoticeEntity getItem(int position) {
return mDatas.get(position);
}
/**
* 获取条目布局
*
* @param parent
* @return
*/
public View getView(NoticeView parent) {
return LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null);
}
/**
* 条目数据适配
*
* @param view
* @param data
*/
public void setItem(final View view, final NoticeEntity data) {
TextView tv = (TextView) view.findViewById(R.id.title);
tv.setText(data.title);
TextView tag = (TextView) view.findViewById(R.id.tag);
tag.setText(data.url);
// 你可以增加点击事件
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 比如打开url
Toast.makeText(view.getContext(), data.url, Toast.LENGTH_SHORT).show();
}
});
}
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
公告实体
package com.notice.scroll;
public class NoticeEntity {
public String title;
public String url;
public NoticeEntity(String title, String url) {
super();
this.title = title;
this.url = url;
}
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
自定义View
package com.notice.scroll;
public class NoticeView extends LinearLayout {
//控件高度
private float mAdverHeight = 0f;
//间隔时间
private final int mGap = 4000;
//动画间隔时间
private final int mAnimDuration = 1000;
//显示文字的尺寸
private final float TEXTSIZE = 20f;
private NoticeAdapter mAdapter;
private final float jdAdverHeight = 50;
//显示的view
private View mFirstView;
private View mSecondView;
//播放的下标
private int mPosition;
//线程的标识
private boolean isStarted;
//画笔
private Paint mPaint;
public NoticeView(Context context) {
this(context, null);
}
public NoticeView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NoticeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
/**
* 初始化属性
* @param context
* @param attrs
* @param defStyleAttr
*/
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
//设置为垂直方向
setOrientation(VERTICAL);
//抗锯齿效果
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//获取自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.NoticeView);
mAdverHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, jdAdverHeight, getResources().getDisplayMetrics());
int gap = array.getInteger(R.styleable.NoticeView_gap, mGap);
//关闭清空TypedArray,防止内存泄露
int animDuration = array.getInteger(R.styleable.NoticeView_animDuration, mAnimDuration);
if (mGap <= mAnimDuration) {
gap = mGap;
animDuration = mAnimDuration;
}
//关闭清空TypedArray
array.recycle();
}
/**
* 设置数据
*/
public void setAdapter(NoticeAdapter adapter) {
this.mAdapter = adapter;
setupAdapter();
}
/**
* 开启线程
*/
public void start() {
if (!isStarted && mAdapter.getCount() > 1) {
isStarted = true;
postDelayed(mRunnable, mGap);//间隔mgap刷新一次UI
}
}
/**
* 暂停滚动
*/
public void stop() {
//移除handle更新
removeCallbacks(mRunnable);
//暂停线程
isStarted = false;
}
/**
* 设置数据适配
*/
private void setupAdapter() {
//移除所有view
removeAllViews();
//只有一条数据,不滚东
if (mAdapter.getCount() == 1) {
mFirstView = mAdapter.getView(this);
mAdapter.setItem(mFirstView, mAdapter.getItem(0));
addView(mFirstView);
} else {
//多个数据
mFirstView = mAdapter.getView(this);
mSecondView = mAdapter.getView(this);
mAdapter.setItem(mFirstView, mAdapter.getItem(0));
mAdapter.setItem(mSecondView, mAdapter.getItem(1));
//把2个添加到此控件里
addView(mFirstView);
addView(mSecondView);
mPosition = 1;
isStarted = false;
}
}
/**
* 测量控件的宽高
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (LayoutParams.WRAP_CONTENT == getLayoutParams().height) {
getLayoutParams().height = (int) mAdverHeight;
} else {
mAdverHeight = getHeight();
}
if (mFirstView != null) {
mFirstView.getLayoutParams().height = (int) mAdverHeight;
}
if (mSecondView != null) {
mSecondView.getLayoutParams().height = (int) mAdverHeight;
}
}
/**
* 画布局
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, TEXTSIZE, getResources().getDisplayMetrics()));
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawText("恭喜你中了5000w大奖", TEXTSIZE, getHeight() * 2 / 3, mPaint);//写文字2/3的高度
}
/**
* 垂直滚蛋
*/
private void performSwitch() {
//属性动画控制控件滚动,y轴方向移动
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mFirstView, "translationY", mFirstView.getTranslationY() - mAdverHeight);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mSecondView, "translationY", mSecondView.getTranslationY() - mAdverHeight);
//动画集
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2);//2个动画一起
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {//动画结束
mFirstView.setTranslationY(0);
mSecondView.setTranslationY(0);
View removedView = getChildAt(0);//获得第一个子布局
mPosition++;
//设置显示的布局
mAdapter.setItem(removedView, mAdapter.getItem(mPosition % mAdapter.getCount()));
//移除前一个view
removeView(removedView);
//添加下一个view
addView(removedView, 1);
}
});
set.setDuration(mAnimDuration);//持续时间
set.start();//开启动画
}
private AnimRunnable mRunnable = new AnimRunnable();
private class AnimRunnable implements Runnable {
@Override
public void run() {
performSwitch();
postDelayed(this, mGap);
}
}
/**
* 销毁View的时候调用
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
//停止滚动
stop();
}
/**
* 屏幕 旋转
*
* @param newConfig
*/
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
......................................................................................................
启动Activity
package com.notice.scroll;
public class ScrollNoticeActivity extends Activity {
private List<NoticeEntity> mDataList = new ArrayList<NoticeEntity>();
private TextView mNoticeTextView;
private NoticeAdapter mNoticeAdapter;
private NoticeView mNoticeView;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
int index = msg.arg1 + 1;
if (index >= mDataList.size()) {
index = 0;
}
mNoticeTextView.setText(mDataList.get(index).title);
mHandler.sendMessageDelayed(mHandler.obtainMessage(1, index, 0), 2000);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
mDataList.add(new NoticeEntity("剩余流量查询XXXXXXXX", "最新"));
mDataList.add(new NoticeEntity("恭喜你中了5000w大奖!", "最火爆"));
mDataList.add(new NoticeEntity("新入网用户领取福利专区", "HOT"));
mDataList.add(new NoticeEntity("温馨提示此乃诈骗消息", "new"));
mNoticeTextView = (TextView) findViewById(R.id.tv_notice);
mNoticeAdapter = new NoticeAdapter(mDataList);
mNoticeView = (NoticeView) findViewById(R.id.tv_notices);
mNoticeView.setAdapter(mNoticeAdapter);
// 开启线程滚动
mNoticeView.start();
getNotices();
}
/**
* 直接通过设置textview达到公告显示的效果
*/
private void getNotices() {
if (mDataList.size() > 0) {
mNoticeTextView.setText(mDataList.get(0).title);
mHandler.sendMessageDelayed(mHandler.obtainMessage(1, 0, 0), 2000);
}
}
}
Android 公告新闻消息资讯之垂直滚动效果的更多相关文章
- Android 仿 新闻阅读器 菜单弹出效果(附源码DEMO)
这一系列博文都是:(android高仿系列)今日头条 --新闻阅读器 (一) 开发中碰到问题之后实现的,觉得可能有的开发者用的到或则希望独立成一个小功能DEMO,所以就放出来这么一个DEMO. 原本觉 ...
- DIV垂直滚动效果源码
<div id="demo" style="width: 300; overflow: hidden; line-height:24px; height: 100p ...
- js实现的新闻列表垂直滚动实现详解
js实现的新闻列表垂直滚动实现详解:新闻列表垂直滚动效果在大量的网站都有应用,有点自然是不言而喻的,首先由于网页的空间有限,使用滚动代码可以使用最小的空间提供更多的信息量,还有让网页有了动态的效果,更 ...
- Expression Blend4经验分享:文字公告无缝循环滚动效果
这次分享一个类似新闻公告板的无缝循环滚动效果,相信很多项目都会应用到这个效果.之前我也百度了一下,网上的一些Silverlight的文字或图片滚动效果,都是一次性滚动的,如果要做到无缝循环滚动,多数要 ...
- [转]jquery.vTicker(垂直滚动)
转至:http://www.w3ci.com/plugin/660.html 简介 vTicker 是一款非常小巧的 jQuery 垂直滚动插件,压缩后只有 2KB.vTicker 支持自定义滚动时间 ...
- Android TextView多行垂直滚动
在Android应用中,有时候需要TextView可以垂直滚动,今天我就介绍一下怎么实现的.在布局里: <TextView android:id="@+id/tvCWJ" a ...
- Android自定义垂直滚动自动选择日期控件
------------------本博客如未明正声明转载,皆为原创,转载请注明出处!------------------ 项目中需要一个日期选择控件,该日期选择控件是垂直滚动,停止滚动时需要校正日期 ...
- android开源新闻小程序、3D翻转公告效果、小说检索、Kotlin开发TODO清单等源码
Android精选源码 开源新闻小程序源码分享 android动态壁纸.锁屏动画.来电秀等源码 android笔记App效果源码 Android实现3D版翻页公告效果 android小说搜索阅读源码 ...
- TextSwitcher实现文本自动垂直滚动
实现功能:用TextSwitcher实现文本自动垂直滚动,类似淘宝首页广告条. 实现效果: 注意:由于网上横向滚动的例子比较多,所以这里通过垂直的例子演示. 实现步骤:1.extends TextSw ...
随机推荐
- Redis 详解 (六) RDB 持久化
目录 1.RDB 简介 2.触发方式 ①.自动触发 ②.手动触发 3.恢复数据 4.停止 RDB 持久化 5.RDB 的优势和劣势 6.RDB 自动保存的原理 前面我们说过,Redis 相对于 Me ...
- 指令——pwd
完整的指令的标准格式:Linux通用的格式 #指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个. 指令pwd: 用法:#pwd(print workin ...
- Hadoop完全高可用集群安装
架构图(HA模型没有SNN节点) 用vm规划了8台机器,用到了7台,SNN节点没用 NN DN SN ZKFC ZK JNN RM NM node1 * * node2 * ...
- Mysql 事务隔离级别分析
Mysql默认事务隔离级别是:REPEATABLE-READ --查询当前会话事务隔离级别mysql> select @@tx_isolation; +-----------------+ | ...
- 洛谷P1433 吃奶酪 题解 状态压缩DP
题目链接:https://www.luogu.com.cn/problem/P1433 题目大意 房间里放着 \(n\) 块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 \((0, ...
- CentOS下的安装命令 安装Nginx 更新yum源 kali系统当中的软件管理命令(第五天)
Linux下软件的安装:方式:yum/rpm/源码安装YUM安装(帮助管理员解决依赖关系):yum search mysqld 在源中搜索软件包yum install mysql-connector- ...
- 【Android】家庭记账本手机版开发报告二
一.说在前面 昨天 完成了对记账本的账单的增删 今天 完善昨天的框架结构( 1.引入ViewModel管理数据.使MainActive 只管理界面.不再管数据了 2.引入AsyncTask.后台执行. ...
- 【LeetCode】最长公共子序列
[问题]给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共子串,并返回其长度.例如:A = "HelloWorld"B = "loop"则A与B的最 ...
- Linux笔记01
linux目录结构 : linux只有一个目录. usr:等价于programfiles: etc:存放系统配置 root:管理员(超级用户)目录, home:存放其他用户的目录: lib:共享包: ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习:作用域
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...