Android 垂直跑马灯,加入事件监听

说到跑马灯,android TextView控件已经有这样的属性设置,唯一要注意的就是:

  • TextView要设置单行显示:android:singleLine=”true”
  • 使用跑马灯属性:android:ellipsize=”marquee”
  • 最重要的,也是很多人发现为啥跑马灯不起作用,在设置了上面2个属性之后,其实就是忘记了要想它跑起来还得让TextView获得焦点才行。可以在代码里设置TextView.requestFocus(),会有意想不到的收获呢;

主题有点偏了,上面的跑马灯属于水平动画效果,今天我想实现的是垂直(ps. PM 想要这种效果,我们这些苦力不得不抓耳挠腮啊),网上也有很多大神实现了这样的效果,主要就是运用动画(平移动画),也可以用属性动画来搞,偶偷懒就简单用水平动画就行了,再加了点事件监听。好了,废话到此为止,上代码。

1.跑马灯布局

<?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="wrap_content"
    android:orientation="horizontal" 
    android:gravity="center_vertical"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:background="#fff">

    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingRight="5dp"
        android:paddingTop="3dp"
        android:paddingBottom="3dp">

        <TextView 
            android:id="@+id/marqueelayout_notice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="垂直跑马灯"
            android:textColor="#000"
            android:textSize="@dimen/nomarl_font"/>

    </LinearLayout>
    <View 
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="#6eb92d"/>

    <FrameLayout
        android:id="@+id/marqueelayout_layout"  
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="15dp"
        android:background="#fff">

        <LinearLayout
            android:id="@+id/marqueelayout_two" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingTop="3dp"
            android:paddingBottom="3dp"
            android:background="#fff">

            <TextView
                android:id="@+id/marqueelayout_two_title" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是标题"
                android:textColor="#000"
                android:textSize="@dimen/alitsamll_font"
                android:singleLine="true"
                android:ellipsize="end"/>

            <TextView
                android:id="@+id/marqueelayout_two_content" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是副标题"
                android:textColor="#505050"
                android:textSize="@dimen/samll_font"
                android:singleLine="true"
                android:ellipsize="end"/>
        </LinearLayout>


        <LinearLayout
            android:id="@+id/marqueelayout_one" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingTop="3dp"
            android:paddingBottom="3dp"
            android:background="#fff">

            <TextView
                android:id="@+id/marqueelayout_one_title" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是标题"
                android:textColor="#000"
                android:textSize="@dimen/alitsamll_font"
                android:singleLine="true"
                android:ellipsize="end"/>

            <TextView
                android:id="@+id/marqueelayout_one_content" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是副标题"
                android:textColor="#505050"
                android:textSize="@dimen/samll_font"
                android:singleLine="true"
                android:ellipsize="end"/>
        </LinearLayout>

    </FrameLayout>

</LinearLayout>

2.垂直跑马灯实现类

import java.util.ArrayList;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MyMarqueeLayout extends LinearLayout implements OnClickListener, AnimationListener{

    private Context mContext;
    private FrameLayout mainLayout;
    private LinearLayout oneLayout, twoLayout;
    private TextView oneTitleTV, oneContentTV, twoTitleTV, twoContentTV;
    private ArrayList<MarqueeBean> arrayList = new ArrayList<MarqueeBean>();
    private int index;
    private int h;
    private onClickPositionListener positionListener;

    public MyMarqueeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        initView();
    }

    public MyMarqueeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initView();
    }

    public MyMarqueeLayout(Context context) {
        super(context);
        this.mContext = context;
        initView();
    }


    private void initView(){
        View view = LayoutInflater.from(mContext).inflate(R.layout.base_marqueelayout_item, null,false);
        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        this.addView(view);//把view添加到我们的MyMarqueeLayout里并设置大小
        measureView(view);//计算跑马灯显示区的大小
        h = view.getMeasuredHeight();
        mainLayout = (FrameLayout)view.findViewById(R.id.marqueelayout_layout);
        oneLayout = (LinearLayout)view.findViewById(R.id.marqueelayout_one);
        twoLayout = (LinearLayout)view.findViewById(R.id.marqueelayout_two);
        oneTitleTV = (TextView)view.findViewById(R.id.marqueelayout_one_title);
        oneContentTV = (TextView)view.findViewById(R.id.marqueelayout_one_content);
        twoTitleTV = (TextView)view.findViewById(R.id.marqueelayout_two_title);
        twoContentTV = (TextView)view.findViewById(R.id.marqueelayout_two_content);

        if(arrayList.size() >= 2){//初始化文本
            oneTitleTV.setText(arrayList.get(0).getTitle());
            oneContentTV.setText(arrayList.get(0).getContent());
            twoTitleTV.setText(arrayList.get(1).getTitle());
            twoContentTV.setText(arrayList.get(1).getContent());
        }
        mainLayout.setOnClickListener(this);//给内容显示区添加点击事件
    }

    /**
     * 计算子view 大小(注意这个方面只能在LinearLayout下)
     * @param childView
     */
    private void measureView(View childView) {
        LayoutParams p = (LayoutParams) childView.getLayoutParams();  
        if (p == null) {  
            p = (LayoutParams) new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);  
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);  
        int height = p.height;  
        int childHeightSpec;  
        if (height > 0) {  
            childHeightSpec = MeasureSpec.makeMeasureSpec(height,  
                    MeasureSpec.EXACTLY);  
        } else {  
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,  
                    MeasureSpec.UNSPECIFIED);  
        }  
        childView.measure(childWidthSpec, childHeightSpec);  
    }

    /**
     * 动画效果
     * @param firstLayout
     * @param seconedLayout
     */
    private void startAnim(LinearLayout firstLayout, LinearLayout seconedLayout){
        TranslateAnimation t1 = new TranslateAnimation(0, 0, 0, -h);// 水平动画
        t1.setDuration(3000);
        t1.setFillAfter(true);
        t1.setStartOffset(1000);// 延迟1秒
        TranslateAnimation t2 = new TranslateAnimation(0, 0, h, 0);// 水平动画
        t2.setDuration(3000);
        t2.setStartOffset(1000);
        t2.setFillAfter(true);
        firstLayout.startAnimation(t1);
        seconedLayout.startAnimation(t2);
        t1.setAnimationListener(this);//添加动画监听
    }

    /**
     * 填充数据
     * @param list
     */
    public void setList(ArrayList<MarqueeBean> list){
        this.arrayList = list;

        if(arrayList.size() == 1){
            oneTitleTV.setText(arrayList.get(0).getTitle());
            oneContentTV.setText(arrayList.get(0).getContent());
        }

        if(arrayList.size() == 2){
            oneTitleTV.setText(arrayList.get(0).getTitle());
            oneContentTV.setText(arrayList.get(0).getContent());

            twoTitleTV.setText(arrayList.get(1).getTitle());
            twoContentTV.setText(arrayList.get(1).getContent());
        }
    }

    /**
     * 开始
     */
    public void start(){
        if(arrayList.size() > 1){ //只有内容条数大于1的时候 才实现跑马灯动画效果
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    startAnim(oneLayout, twoLayout);
                }
            }, 4000);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.marqueelayout_layout:
            //根据计数器index 得到点击的位置
            if(positionListener != null){
                if(index < arrayList.size()){
                    positionListener.onClick(index);
                }else{
                    int position = (index)%arrayList.size();
                    positionListener.onClick(position);
                }
            }
            break;
        default:
            break;
        }
    }

    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        int position = (index+2)%arrayList.size();//找到下一个显示内容
        if(index%2 == 0){ // 根据计数器 动态填充TextView 内容
            oneTitleTV.setText(arrayList.get(position).getTitle());
            oneContentTV.setText(arrayList.get(position).getContent());
            startAnim(twoLayout, oneLayout);
        }else{
            twoTitleTV.setText(arrayList.get(position).getTitle());
            twoContentTV.setText(arrayList.get(position).getContent());
            startAnim(oneLayout, twoLayout);
        }
        index ++;
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    /**
     * 走马灯 点击位置 接口类
     * @author YC
     */
    public interface onClickPositionListener {
        void onClick(int position);
    }

    public void setListener(onClickPositionListener listener){
        this.positionListener = listener;
    }
}

ps. MarqueeBean 只是一个跑马灯的内容存放Bean

3.MyMarqueeLayout 具体使用

final ArrayList<MarqueeBean> arrayList = new ArrayList<MarqueeBean>();
        MyMarqueeLayout marqueeLayout = (MyMarqueeLayout)headview.findViewById(R.id.main_buyfood_marquee);
        MarqueeBean bean1 = new MarqueeBean();
        bean1.setTitle("标题1");
        bean1.setContent("副标题1");
        arrayList.add(bean1);
        MarqueeBean bean2 = new MarqueeBean();
        bean2.setTitle("标题2");
        bean2.setContent("副标题2");
        arrayList.add(bean2);
        MarqueeBean bean3 = new MarqueeBean();
        bean3.setTitle("标题3");
        bean3.setContent("副标题3");
        arrayList.add(bean3);
        marqueeLayout.setList(arrayList);
        marqueeLayout.start();
        marqueeLayout.setListener(new onClickPositionListener() {
            @Override
            public void onClick(int position) {
                Toast.makeText(getActivity(), "position:"+position +"||title:"+arrayList.get(position).getTitle(), Toast.LENGTH_SHORT).show();
            }
        });

4.图呢。 其实我也想要问图呢。。我只截了几张图,准备做gif的发现,太水了,还是不拿来献丑了。还是大家自己亲测吧(我自己只是亲测过了,效果很赞,不然我也不发啦)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值