滚动的广告通知栏

 <declare-styleable name="ADTextView">
        <!--文字进入与消失的时间-->
        <attr name="ad_text_view_speed" format="integer"/>

        <!--文字停留在中心的时间-->
        <attr name="ad_text_view_interval" format="integer"/>

        <!--前缀文字颜色-->
        <attr name="ad_text_front_color" format="color"/>
        <!--前缀文字大小-->
        <attr name="ad_text_front_size" format="dimension"/>

        <!--内容文字颜色-->
        <attr name="ad_text_content_color" format="color"/>
        <!--内容文字大小-->
        <attr name="ad_text_content_size" format="dimension"/>
    </declare-styleable>




效果图:







实现仿京东垂直滚动广告栏,它是一个动态的无限自动轮播图,让我们看看它是怎么实现的:

先看一看布局文件:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.bawei.com.wangruixin20171116.MainActivity">

    <com.bawei.com.wangruixin20171116.ADTextView
        android:id="@+id/re"
        android:layout_width="match_parent"
        android:layout_height="20dp" />
</RelativeLayout>

 
MainActivity 

package com.bawei.com.wangruixin20171116;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ADTextView mADTextView1;
    private ArrayList<ADEnity> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();


    }
    public void init(){
        mADTextView1 = (ADTextView) findViewById(R.id.re);
        mList = new ArrayList<>();
        mList.add(new ADEnity("推荐","国货PK美国货,结果让人震惊", "连接1"));
        mList.add(new ADEnity("推荐","这次XiPhone,可能让你迷路", "连接2"));
        mList.add(new ADEnity("HOT", "为什么吉普,奥巴马都爱钓鱼", "连接3"));
        mList.add(new ADEnity("HOT", "虽然我字难看,但我钢笔好看啊", "连接4"));
        mADTextView1.setSpeed(3);
        mADTextView1.setInterval(1500);
        mADTextView1.setFrontColor(Color.RED);
        mADTextView1.setBackColor(Color.BLACK);
        mADTextView1.setmTexts(mList);
//        mADTextView.setOnItemClickListener(new ADTextView.OnItemClickListener() {
//            @Override
//            public void onClick(String mUrl) {
//                if (mToast == null) {
//                    mToast = Toast.makeText(getActivity(), mUrl, Toast.LENGTH_LONG);
//                } else {
//                    mToast.setText(mUrl);
//                }
//                mToast.show();
//            }
//        });

    }
}
ADEnity

package com.bawei.com.wangruixin20171116;

/**
 *
 */

public class ADEnity {
    private String mFront ; //前面的文字
    private String mBack ; //后面的文字
    private String mUrl ;//包含的链接

    public ADEnity(String mFront, String mBack,String mUrl) {
        this.mFront = mFront;
        this.mBack = mBack;
        this.mUrl = mUrl;
    }

    public String getmUrl() {
        return mUrl;
    }

    public void setmUrl(String mUrl) {
        this.mUrl = mUrl;
    }

    public String getmFront() {
        return mFront;
    }

    public void setmFront(String mFront) {
        this.mFront = mFront;
    }

    public String getmBack() {
        return mBack;
    }

    public void setmBack(String mBack) {
        this.mBack = mBack;
    }
}
ADTextView

package com.bawei.com.wangruixin20171116;

/**
 * Created by Zhouyf on 2017/11/14.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 仿京东垂直滚动广告栏
 *
 */

public class ADTextView extends View {
    private int mSpeed; //文字出现或消失的速度 建议1~5
    private int mInterval; //文字停留在中间的时长
    private int mFrontColor; //前缀颜色
    private int mContentColor; //内容的颜色
    private int mFrontTextSize; //前缀文字大小
    private int mContentTextSize; //内容文字大小

    private List<ADEnity> mTexts; //显示文字的数据源
    private int mY = 0; //文字的Y坐标
    private int mIndex = 0; //当前的数据下标
    private Paint mPaintContent; //绘制内容的画笔
    private Paint mPaintFront; //绘制前缀的画笔
    private boolean isMove = true; //文字是否移动
    private String TAG = "ADTextView";
    private boolean hasInit = false;
    private boolean isPaused = false;

    public interface onClickListener {
        public void onClick(String mUrl);
    }

    private onClickListener onClickListener;

    public void setOnClickListener(onClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public ADTextView(Context context) {
        this(context, null);
    }

    public ADTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        obtainStyledAttrs(attrs);
        init();
    }

    //获取资源文件
    private void obtainStyledAttrs(AttributeSet attrs) {
        TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.ADTextView);
        mSpeed = array.getInt(R.styleable.ADTextView_ad_text_view_speed, 1);
        mInterval = array.getInt(R.styleable.ADTextView_ad_text_view_interval, 2000);
        mFrontColor = array.getColor(R.styleable.ADTextView_ad_text_front_color, Color.RED);
        mContentColor = array.getColor(R.styleable.ADTextView_ad_text_content_color, Color.BLACK);
        mFrontTextSize = (int) array.getDimension(R.styleable.ADTextView_ad_text_front_size, SizeUtil.Sp2Px(getContext(), 15));
        mContentTextSize = (int) array.getDimension(R.styleable.ADTextView_ad_text_content_size, SizeUtil.Sp2Px(getContext(), 15));
        array.recycle();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (onClickListener != null) {
                    onClickListener.onClick(mTexts.get(mIndex).getmUrl());
                }

                break;
        }
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(DensityUtil.dip2px(getContext(), 500), DensityUtil.dip2px(getContext(), 40));
    }

    //测量宽度
    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else { //高度至少为两倍字高
            int mfronTextHeight = (int) (mPaintFront.descent() - mPaintFront.ascent()); //前缀文字字高
            int mContentTextHeight = (int) (mPaintContent.descent() - mPaintContent.ascent()); //内容文字字高
            result = Math.max(mfronTextHeight, mContentTextHeight) * 2;

            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    //测量高度
    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else { //宽度最小十个字的宽度
            String text = "十个字十个字十个字字";
            Rect rect = new Rect();
            mPaintContent.getTextBounds(text, 0, text.length(), rect);
            result = rect.right - rect.left;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    //设置数据源
    public void setmTexts(List<ADEnity> mTexts) {
        this.mTexts = mTexts;
    }

    //设置广告文字的停顿时间
    public void setInterval(int mInterval) {
        this.mInterval = mInterval;
    }

    //设置速度
    public void setSpeed(int spedd) {
        this.mSpeed = spedd;
    }

    //设置前缀的文字颜色
    public void setFrontColor(int mFrontColor) {
        mPaintFront.setColor(mFrontColor);
    }

    //设置正文内容的颜色
    public void setBackColor(int mBackColor) {
        mPaintContent.setColor(mBackColor);
    }

    //初始化默认值
    private void init() {
        mIndex = 0;
        mPaintFront = new Paint();
        mPaintFront.setAntiAlias(true);
        mPaintFront.setDither(true);
        mPaintFront.setTextSize(mFrontTextSize);
        mPaintFront.setColor(mFrontColor);

        mPaintContent = new Paint();
        mPaintContent.setAntiAlias(true);
        mPaintContent.setDither(true);
        mPaintContent.setTextSize(mContentTextSize);
        mPaintContent.setColor(mContentColor);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mTexts != null) {
            ADEnity model = mTexts.get(mIndex);
            String font = model.getmFront();
            String back = model.getmBack();
            //绘制前缀
            Rect indexBound = new Rect();
            mPaintFront.getTextBounds(font, 0, font.length(), indexBound);

            //绘制内容文字
            Rect contentBound = new Rect();
            mPaintContent.getTextBounds(back, 0, back.length(), contentBound);
            if (mY == 0 && hasInit == false) {
                mY = getMeasuredHeight() - indexBound.top;
                hasInit = true;
            }
            //移动到最上面
            if (mY <= 0 - indexBound.bottom) {
                Log.i(TAG, "onDraw: " + getMeasuredHeight());
                mY = getMeasuredHeight() - indexBound.top;
                mIndex++;
                isPaused = false;
            }
            canvas.drawText(back, 0, back.length(), (indexBound.right - indexBound.left) + 20, mY, mPaintContent);
            canvas.drawText(font, 0, font.length(), 10, mY, mPaintFront);
            //移动到中间
            if (!isPaused && mY <= getMeasuredHeight() / 2 - (indexBound.top + indexBound.bottom) / 2) {
                isMove = false;
                isPaused = true;
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        postInvalidate();
                        isMove = true;
                    }
                }, mInterval);
            }
            mY -= mSpeed;
            //循环使用数据
            if (mIndex == mTexts.size()) {
                mIndex = 0;
            }
            //如果是处于移动状态时的,则延迟绘制
            //计算公式为一个比例,一个时间间隔移动组件高度,则多少毫秒来移动1像素
            if (isMove) {
                postInvalidateDelayed(2);
            }
        }

    }
}
DensityUtil

package com.bawei.com.wangruixin20171116;


import android.content.Context;

public class DensityUtil {
    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}
SizeUtil

package com.bawei.com.wangruixin20171116;

import android.content.Context;
import android.util.TypedValue;

/**
 *
 */

public class SizeUtil {
    public static int Dp2Px(Context context, int dpi) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpi, context.getResources().getDisplayMetrics());
    }
    public static int Px2Dp(Context context, int px) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, context.getResources().getDisplayMetrics());
    }
    public static int Sp2Px(Context context, int sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
    }
    public static int Px2Sp(Context context, int px) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, context.getResources().getDisplayMetrics());
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值