自定义view实现上下翻滚的公告栏功能

很多app都有上下翻滚的公告栏来提示用户最新的公司动态及事件,先看ui图:
这里写图片描述
不知道你看到的ui图的第一反应是什么, 反正我的第一反应是找一下第三方. …结果找了半天没找到合适的,如果你和我的反应是一样的说明那么你对ViewFlipper是陌生的 ,不了解的同学请问度娘,本文就是基于Android循环滚动控件——ViewFlipper的重写。
下面上效果图,看看是否能帮助到您:
自定义view实现上下翻滚的公告栏功能_第1张图片
思路就是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);
    }
}

你可能感兴趣的:(自定义view)