51.使用HorizontalScrollView+LinearLayout实现文字+图片的自动跑马灯效果

转载请注明出处 http://blog.csdn.net/qq_31715429/article/details/52786614
本文出自:猴菇先生的博客

需求是 一个集合中,每个对象的文字后面坠一个图片,然后整体滚动,效果如下
这里写图片描述
demo代码如下
1.activity_main.xml:

<HorizontalScrollView
    android:id="@+id/sv"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="#E1F4FF"
    android:scrollbars="none">

    <LinearLayout
        android:id="@+id/ll"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal" />
</HorizontalScrollView>

2.MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private List<DataBean> mList;

    private HorizontalScrollView mSv;
    private LinearLayout mLl;

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

    /**
    * 初始化数据
    */
    private void initData() {
        mList = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            DataBean bean = new DataBean();
            bean.setName("WTI");
            bean.setPrice("1000.0");
            bean.setTrend("up");
            mList.add(bean);
        }
    }

    /**
    * 初始化布局
    */
    private void initView() {
        mSv = (HorizontalScrollView) findViewById(R.id.sv);
        mLl = (LinearLayout) findViewById(R.id.ll);
        mSv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //设置ScrollView取消手动滑动
                return true;
            }
        });
        //动态添加TextView
        float scrollWidth = 0f;//滚动的总宽度
        for (int i = 0; i < mList.size(); i++) {
            DataBean bean = mList.get(i);
            TextView tv = new TextView(this);
            tv.setText("      " + bean.getName() + "    " + bean.getPrice() + "    ");
            //给TextView右边坠一个图片,四个参数分别代表在left、top、right、bottom添加图片,并使用原始大小
            tv.setCompoundDrawablesWithIntrinsicBounds(null, null,
                    getResources().getDrawable(R.mipmap.ic_launcher), null);
            //测量每个TextView的宽度
            int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            tv.measure(spec, spec);
            //每个TextView的宽度相加得到总宽度
            scrollWidth += tv.getMeasuredWidth();
            Log.e("--> ", String.valueOf(scrollWidth));
            mLl.addView(tv);
        }
        startScroll(scrollWidth);
    }

    /**
    * 开始滚动
    */
    private void startScroll(float scrollWidth) {
        if (scrollWidth != 0) {
            final long duration = (long) (scrollWidth* 5);//动画时长
            //属性动画位移,从屏幕右边向左移动到屏幕外scrollWidth长度的距离
            ObjectAnimator anim = ObjectAnimator.ofFloat(mLl, "translationX", getScreenWidth(), -scrollWidth);
            anim.setDuration(duration);
            anim.setInterpolator(new LinearInterpolator());
            anim.setRepeatMode(ValueAnimator.RESTART);//无限重复
            anim.setRepeatCount(ValueAnimator.INFINITE);
            anim.start();
        }
    }

    /**
    * 获得屏幕宽度
    */
    private int getScreenWidth() {
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }
}

需要注意的是,如果下拉刷新数据,需要在动态添加TextView之前添加

mLl.removeAllViews();
mLl.clearAnimation();

否则会造成动画混乱、mLl重复添加多个TextView的问题

实现文字图片跑马灯效果可以通过以下步骤: 1.创建一个包含文字图片的布局,可以使用LinearLayout或者RelativeLayout。 2.将布局嵌套在HorizontalScrollView中,设置HorizontalScrollView的属性为滚动。 3.使用定时器或者Handler实现自动滚动,可以使用postDelayed方法实现定时滚动。 4.在滚动的过程中,需要根据内容的长度和滚动位置动态调整滚动的速度。 5.如果需要支持手动滚动,可以使用GestureDetector或者Touch事件监听实现手动滚动。 6.在滚动过程中,需要对滚动到边界的情况进行特殊处理,例如循环滚动或者停止滚动。 以下是一个简单的示例代码: ``` class MarqueeView(context: Context, attrs: AttributeSet? = null) : HorizontalScrollView(context, attrs) { private val contentView = LinearLayout(context) private var speed = 2 // 滚动速度 private var timer: Timer? = null private var isScrolling = false init { isHorizontalScrollBarEnabled = false isVerticalScrollBarEnabled = false addView(contentView) } fun start() { if (timer == null) { timer = Timer() timer?.schedule(object : TimerTask() { override fun run() { if (isScrolling) { post { scrollBy(speed, 0) if (scrollX >= contentView.width - width) { scrollTo(0, 0) } } } } }, 0, 20) } isScrolling = true } fun stop() { isScrolling = false timer?.cancel() timer = null } fun setContent(content: String, imageResId: Int) { contentView.removeAllViews() val textView = TextView(context) textView.text = content textView.textSize = 16f textView.setTextColor(Color.BLACK) textView.setPadding(10, 10, 10, 10) val imageView = ImageView(context) imageView.setImageResource(imageResId) imageView.setPadding(10, 10, 10, 10) contentView.addView(textView) contentView.addView(imageView) val layoutParams = LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT) textView.layoutParams = layoutParams imageView.layoutParams = layoutParams } } ``` 使用示例: ``` val marqueeView = MarqueeView(this) marqueeView.setContent("这是一段跑马灯文字", R.drawable.ic_launcher_background) marqueeView.start() // 停止滚动 marqueeView.stop() ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值