垂直跑马灯,广告轮播

主要是记录一下项目中的一些效果,方便以后同样的需求直接过来copy
效果图
看到这个需求的时候去网上找了好久,都是一个textView的滚动,满足不了需求.
最后只能动手了,原来很简单,就是2个view来回倒腾,搞个动画,就行了

布局
2个LinearLayout,里面放了TextViw,隐藏其中一个LinearLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/ll_notice1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:id="@+id/tv_title1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="烟花易冷"
            android:maxLines="1"
            android:ellipsize="end"
            android:textColor="#ff333333"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_content1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="繁华声遁入空门折煞了庶人"
            android:maxLines="1"
            android:layout_marginTop="3dp"
            android:ellipsize="end"
            android:textColor="#ff999999"
            android:textSize="16sp"
            />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_notice2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:orientation="vertical">


        <TextView
            android:id="@+id/tv_title2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="烟花易冷"
            android:maxLines="1"
            android:ellipsize="end"
            android:textColor="#ff333333"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_content2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="繁华声遁入空门折煞了庶人"
            android:maxLines="1"
            android:layout_marginTop="3dp"
            android:ellipsize="end"
            android:textColor="#ff999999"
            android:textSize="16sp"
            />
    </LinearLayout>
</RelativeLayout>

LinearLayout出去的动画,向上平移,平移出去就隐藏

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="2000"
        android:fillAfter="true"
        android:fromXDelta="0%"
        android:fromYDelta="100%"
        android:toXDelta="0%"
        android:toYDelta="0%" />

</set>
 private void notice1OutAnim() {
        llNotice1.startAnimation(mSlide_Out);
        llNotice1.setVisibility(View.INVISIBLE);

        if ((++item) == mDataList.size()) {
            item = 0;
        }
        tvTitle2.setText(mTitleList.get(item));
        tvContent2.setText(mDataList.get(item));
        llNotice2.setVisibility(View.VISIBLE);
        llNotice2.startAnimation(mSlide_In);

        isOne = false;
    }

进来的动画,从下往上平移

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="2000"
        android:fillAfter="true"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="-100%" />

</set>
 private void notice2OutAnia() {
        llNotice2.startAnimation(mSlide_Out);
        llNotice2.setVisibility(View.INVISIBLE);

        if ((++item) == mDataList.size()) {
            item = 0;
        }
        tvTitle1.setText(mTitleList.get(item));
        tvContent1.setText(mDataList.get(item));
        llNotice1.setVisibility(View.VISIBLE);
        llNotice1.startAnimation(mSlide_In);

        isOne = true;
    }

然后用一个Handler来回倒腾动画

  class MyHandler extends Handler implements Runnable {
        @Override
        public void run() {
            if (isOne) {
                notice1OutAnim();
            } else {
                notice2OutAnia();
            }
            mHandler.postDelayed(this, DURATION);
        }
    }

整体的代码

package com.duanlian.demos;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class VerticalMarqueeLayout extends LinearLayout implements OnClickListener {


    private static final long DURATION = 3000;

    private MyHandler mHandler;

    private List<String> mDataList;
    private List<String> mTitleList;
    private Context mContext;
    private boolean isOne = true;

    private LinearLayout llNotice1;
    private LinearLayout llNotice2;
    private Animation mSlide_In;
    private Animation mSlide_Out;
    private TextView tvTitle1, tvContent1;
    private TextView tvTitle2, tvContent2;

    private int item = 0;// 标志位

    /**
     * 构造函数
     */
    public VerticalMarqueeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mHandler = new MyHandler();
        mContext = getContext();
        View layout = LayoutInflater.from(mContext).inflate(R.layout.layout_textview, this);

        tvTitle1 = layout.findViewById(R.id.tv_title1);
        tvContent1 = layout.findViewById(R.id.tv_content1);
        tvTitle2 = layout.findViewById(R.id.tv_title2);
        tvContent2 = layout.findViewById(R.id.tv_content2);
        llNotice1 = layout.findViewById(R.id.ll_notice1);
        llNotice2 = layout.findViewById(R.id.ll_notice2);
        llNotice1.setOnClickListener(this);
        llNotice2.setOnClickListener(this);

        mSlide_Out = AnimationUtils.loadAnimation(mContext, R.anim.slide_in);
        mSlide_In = AnimationUtils.loadAnimation(mContext, R.anim.slide_out);
    }

    /**
     * 对外,设置文本数据
     */
    public void setData(List<String> titles, List<String> list) {
        this.mDataList = list;
        this.mTitleList = titles;
        // 非空判断
        if (mDataList == null || mDataList.size() < 2) {
            mDataList = new ArrayList<>();
            mDataList.add("通知一");
            mDataList.add("通知二");
        }
        tvTitle1.setText(mTitleList.get(0));
        tvContent1.setText(mDataList.get(0));
        tvTitle1.setText(mTitleList.get(1));
        tvContent2.setText(mDataList.get(1));
    }

    /**
     * 开始执行
     */
    public void startRun() {
        mHandler.post(mHandler);
    }


    class MyHandler extends Handler implements Runnable {
        @Override
        public void run() {
            if (isOne) {
                notice1OutAnim();
            } else {
                notice2OutAnia();
            }
            mHandler.postDelayed(this, DURATION);
        }
    }


    private void notice1OutAnim() {
        llNotice1.startAnimation(mSlide_Out);
        llNotice1.setVisibility(View.INVISIBLE);

        if ((++item) == mDataList.size()) {
            item = 0;
        }
        tvTitle2.setText(mTitleList.get(item));
        tvContent2.setText(mDataList.get(item));
        llNotice2.setVisibility(View.VISIBLE);
        llNotice2.startAnimation(mSlide_In);

        isOne = false;
    }


    private void notice2OutAnia() {
        llNotice2.startAnimation(mSlide_Out);
        llNotice2.setVisibility(View.INVISIBLE);

        if ((++item) == mDataList.size()) {
            item = 0;
        }
        tvTitle1.setText(mTitleList.get(item));
        tvContent1.setText(mDataList.get(item));
        llNotice1.setVisibility(View.VISIBLE);
        llNotice1.startAnimation(mSlide_In);

        isOne = true;
    }

    @Override
    public void onClick(View view) {
        if (click != null) {
            click.onItemClick(item);
        }
    }

    public interface ItemClick {
        void onItemClick(int position);
    }

    ItemClick click;

    public void setOnItemClick(ItemClick onItemClick) {
        this.click = onItemClick;
    }

}


在activity里设置数据,触发动画,设置点击事件

  private void initView() {
        vmLayout = findViewById(R.id.vertical_marquee);
        titleList = new ArrayList<>();
        contentList = new ArrayList<>();
        titleList.add("七里香");
        titleList.add("东风破");
        titleList.add("发如雪");
        titleList.add("烟花易冷");
        contentList.add("窗外的麻雀,在电线杆上多嘴");
        contentList.add("一盏离愁孤,单伫立在窗口");
        contentList.add("狼牙月,伊人憔悴,我举杯,饮尽了风雪");
        contentList.add("繁华声遁入空门,折煞了庶人");
        vmLayout.setData(titleList, contentList);
        vmLayout.startRun();
        vmLayout.setOnItemClick(new VerticalMarqueeLayout.ItemClick() {
            @Override
            public void onItemClick(int position) {
                Toast.makeText(VerticalMarqueeActivity.this, titleList.get(position) + "", Toast.LENGTH_SHORT).show();
            }
        });

    }

demo地址,包含多个demo,自取自己需要的
有需要自取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值