很多app都有上下翻滚的公告栏来提示用户最新的公司动态及事件,先看ui图:
不知道你看到的ui图的第一反应是什么, 反正我的第一反应是找一下第三方. …结果找了半天没找到合适的,如果你和我的反应是一样的说明那么你对ViewFlipper是陌生的 ,不了解的同学请问度娘,本文就是基于Android循环滚动控件——ViewFlipper的重写。
下面上效果图,看看是否能帮助到您:
思路就是ViewFlipper的用法,再有就是代码动态添加控件,也没啥好讲的下面直接贴代码。
XML 布局:
"@+id/mnv"
android:layout_centerInParent="true"
app:mvInterval="3000"
app:mvSingleLine="true"
app:mvTextSize="@dimen/size_26px"
app:mvTextColor="@color/black_333333"
app:mvTimeTextColor="@color/grey_999999"
app:mvTimeTextSize ="@dimen/size_22px"
android:layout_width="match_parent"
android:layout_marginLeft="@dimen/size_50px"
android:layout_marginRight="@dimen/size_50px"
android:layout_height="@dimen/size_100px">
</lzh.myview.view.MyNotificationView>
attrs 文件
<declare-styleable name="MyNotificationView">
<attr name="mvInterval" format="integer|reference"/>
<attr name="mvTextSize" format="dimension|reference"/>
<attr name="mvTimeTextSize" format="dimension|reference"/>
<attr name="mvTextColor" format="color|reference"/>
<attr name="mvTimeTextColor" format="color|reference"/>
<attr name="mvSingleLine" format="boolean"/>
declare-styleable>
动画文件:
// anim_notificationview_bottom_in
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromYDelta="100%p"
android:toYDelta="0"/>
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
</set>
//anim_notificationview_top_out
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromYDelta="0"
android:toYDelta="-100%p"/>
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>
</set>
Activity 用法:
// 设置数据
mnv.setList(listStr, listtime);
// 设置监听回调
mnv.setOnItemClickListener(new MyNotificationView.OnItemClickListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(NotificationActivity.this,"第 "+position +"个",Toast.LENGTH_LONG).show();
}
});
自定义view 全部代码
public class MyNotificationView extends ViewFlipper {
private int interval = 3000;
private boolean singleLine = true;
private int textSize = 20;
private int TimetextSize = 20;
private int textColor = Color.BLUE;
private int TimetextColor = Color.RED;
private int animDuration = 1000;
private boolean hasSetAnimDuration = false;
@AnimRes
private int inAnimResId = R.anim.anim_notificationview_bottom_in;
@AnimRes
private int outAnimResId = R.anim.anim_notificationview_top_out;
private List notices = new ArrayList<>();
private List noticestime = new ArrayList<>();
private int position;
private OnItemClickListener onItemClickListener;
public MyNotificationView(Context context) {
super(context);
}
public MyNotificationView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyNotificationView);
interval = typedArray.getInteger(R.styleable.MyNotificationView_mvInterval, interval);
singleLine = typedArray.getBoolean(R.styleable.MyNotificationView_mvSingleLine, false);
if (typedArray.hasValue(R.styleable.MyNotificationView_mvTextSize)) {
textSize = (int) typedArray.getDimension(R.styleable.MyNotificationView_mvTextSize, textSize);
textSize = px2sp(context, textSize);
}
if (typedArray.hasValue(R.styleable.MyNotificationView_mvTimeTextSize)) {
TimetextSize = (int) typedArray.getDimension(R.styleable.MyNotificationView_mvTimeTextSize, textSize);
TimetextSize = px2sp(context, TimetextSize);
}
textColor = typedArray.getColor(R.styleable.MyNotificationView_mvTextColor, textColor);
TimetextColor = typedArray.getColor(R.styleable.MyNotificationView_mvTimeTextColor, TimetextColor);
typedArray.recycle();
setFlipInterval(interval);
}
// 将px值转换为sp值
private int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
public static boolean isEmpty(List list) {
if (list == null || list.size() == 0) {
return true;
}
return false;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
public int getPosition() {
return (int) getCurrentView().getTag();
}
public void setNotices(List notices) {
this.notices = notices;
}
public void setNoticesTime(List mnoticestime) {
this.noticestime = mnoticestime;
}
public void setList(List notices, List noticestime) {
if (isEmpty(notices)){
addView(createLayout("",""));
}else {
setNotices(notices);
setNoticesTime(noticestime);
StartAnimation(inAnimResId, outAnimResId);
}
}
private void StartAnimation(final int inAnimResId, final int outAnimResId) {
post(new Runnable() {
@Override
public void run() {
start(inAnimResId, outAnimResId);
}
});
}
private boolean isAnimStart = false;
private void start(final @AnimRes int inAnimResId, final @AnimRes int outAnimResID) {
removeAllViews();
clearAnimation();
position = 0;
addView(createLayout(notices.get(position),noticestime.get(position)));
if (notices.size() > 1) {
setInAndOutAnimation(inAnimResId, outAnimResID);
startFlipping();
}
if (getInAnimation() != null) {
getInAnimation().setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
if (isAnimStart) {
animation.cancel();
}
isAnimStart = true;
}
@Override
public void onAnimationEnd(Animation animation) {
position++;
if (position >= notices.size()) {
position = 0;
}
View view = createLayout(notices.get(position),noticestime.get(position));
if (view.getParent() == null) {
addView(view);
}
isAnimStart = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}
private View createLayout(CharSequence text, CharSequence texttime) {
RelativeLayout relativeLayout = (RelativeLayout) getChildAt((getDisplayedChild() + 1) % 3);
TextView textView = null;
TextView textView02 = null;
if (relativeLayout == null) {
relativeLayout = new RelativeLayout(getContext());
relativeLayout.setGravity(RelativeLayout.CENTER_IN_PARENT);
}else {
if (relativeLayout.getChildCount()>0) relativeLayout.removeAllViews();
relativeLayout.setGravity(RelativeLayout.CENTER_IN_PARENT);
}
RelativeLayout.LayoutParams mLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams mLayoutParams02 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
textView = new TextView(getContext());
textView02 = new TextView(getContext());
textView.setTextColor(textColor);
textView.setTextSize(textSize);
textView.setSingleLine(singleLine);
textView02.setTextColor(TimetextColor);
textView02.setTextSize(TimetextSize);
textView02.setSingleLine(singleLine);
textView.setMaxEms(16);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (TextUtils.isEmpty(text)) {
textView.setText("钱美美欢迎您!!!");
}else {
textView.setText(text);
}
if (!TextUtils.isEmpty(texttime)) textView02.setText(texttime);
relativeLayout.setTag(position);
mLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
mLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
relativeLayout.addView(textView,mLayoutParams);
mLayoutParams02.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
mLayoutParams02.addRule(RelativeLayout.CENTER_VERTICAL);
relativeLayout.addView(textView02,mLayoutParams02);
relativeLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(getPosition());
}
}
});
return relativeLayout;
}
/**
* 设置进入动画和离开动画
*
* @param inAnimResId 进入动画的resID
* @param outAnimResID 离开动画的resID
*/
private void setInAndOutAnimation(@AnimRes int inAnimResId, @AnimRes int outAnimResID) {
Animation inAnim = AnimationUtils.loadAnimation(getContext(), inAnimResId);
inAnim.setDuration(animDuration);
setInAnimation(inAnim);
Animation outAnim = AnimationUtils.loadAnimation(getContext(), outAnimResID);
outAnim.setDuration(animDuration);
setOutAnimation(outAnim);
}
}