android 实现一个滚动文本

效果图

效果图

实现方法

懒得写了,哪天有空就补上。直接上代码
首先是一个自定义layout,继承自FrameLayout

public class AnimationTextLayout extends FrameLayout {
    private static final String TAG = "AnimationTextLayout";
    private List<String> tipList;
    private List<Integer> displayList;
    private List<TextView> viewList;
    private List<VirtualPos> virtualPosList;
    private double deviantAngle = 0;

    public AnimationTextLayout(@NonNull Context context) {
        super(context);
        initView();
    }

    public AnimationTextLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AnimationTextLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        viewList = new ArrayList<>();
        displayList = new ArrayList<>();
        virtualPosList = new ArrayList<>();
    }

    /**
     * 设置需要显示的数据
     *
     * @param data         需要显示的数据
     */
    public void setData(List<String> data) {
        this.tipList = data;
        initTips();
    }


    private void initTips() {
        while (tipList.size() > viewList.size()) {
            addTipsView();
        }
        refreshTips();
        initVirPos();

        post(new Runnable() {
            @Override
            public void run() {
                initPosition();
                requestLayout();
            }
        });

    }

    /**
     * 计算虚拟位置
     */
    private void initVirPos() {
        virtualPosList.clear();
        for (int i = 0; i < viewList.size(); i++) {
            double angle = (Math.PI * ((double) i / viewList.size())*2)+(deviantAngle*Math.PI*2);
            if (angle>Math.PI*2){
                angle-=Math.PI*2;
            }
            VirtualPos virtualPos = new VirtualPos();
            virtualPos.text = tipList.get(i);
            virtualPos.z = 100 * Math.sin(angle);
            virtualPos.y = 100 * Math.cos(angle);
            virtualPosList.add(virtualPos);
        }
    }

    /**
     * 将虚拟位置转化为实际高度和位置
     */
    private void initPosition() {
        for (int i = 0; i < viewList.size(); i++) {
            TextView textView = viewList.get(i);
            VirtualPos virtualPos=virtualPosList.get(i);
            int realY = (int) ((100 - virtualPos.y)/200 *getMeasuredHeight());
            FrameLayout.LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
            layoutParams.topMargin = realY;
            if (virtualPos.z>=0){
               float textSize= (float) (( virtualPos.z)/100)*20+5;
                textView.setTextSize(textSize);
                textView.setVisibility(VISIBLE);
            }else {
                textView.setVisibility(GONE);
            }

            Log.d(TAG, "initPosition: y=="+realY);
        }

    }

    private void refreshTips() {
        for (int i = 0; i < viewList.size(); i++) {
            TextView tip = viewList.get(i);
            if (i < tipList.size()) {
                tip.setVisibility(VISIBLE);
                tip.setText(tipList.get(i));
                continue;
            }
            tip.setVisibility(GONE);
        }
    }

    private TextView addTipsView() {
        TextView textView = new TextView(getContext());
        textView.setTextSize(COMPLEX_UNIT_DIP, 12);
        textView.setTextColor(Color.parseColor("#444444"));
        textView.setPadding(ConvertUtil.dp2px(5), ConvertUtil.dp2px(3), ConvertUtil.dp2px(5), ConvertUtil.dp2px(3));
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.gravity=Gravity.CENTER_HORIZONTAL;
        layoutParams.rightMargin = ConvertUtil.dp2px(6);
        addView(textView, layoutParams);
        viewList.add(textView);
        return textView;
    }

    /**
     * 虚拟位置,最大x,y,z 最大值为100,最小值为-100
     */
    public static class VirtualPos {
        public double x;
        public double y;
        public double z;
        public String text;
    }

    /**
     * 滚动的偏移值
     * @param deviantAngle 最大为1
     */
    public void setDeviantAngle(float deviantAngle) {
        this.deviantAngle = deviantAngle;
        initVirPos();
        initPosition();
    }

    public double getDeviantAngle() {
        return deviantAngle;
    }
}

调用方布局

<FrameLayout 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=".AnimationTextActivity">
    <com.lanlengran.test.view.AnimationTextLayout
        android:id="@+id/anim_text_layout"
        android:layout_width="match_parent"
        android:background="@color/colorAccent"
        android:layout_height="400dp"/>
</FrameLayout>

调用方代码

public class AnimationTextActivity extends Activity {
    private AnimationTextLayout mAnimTextLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animation_text);
        mAnimTextLayout = findViewById(R.id.anim_text_layout);

        List<String> testData = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            testData.add("测试数据" + i);
        }
        mAnimTextLayout.setData(testData);

        ObjectAnimator animator = ObjectAnimator.ofFloat(mAnimTextLayout, "deviantAngle",  0f, 1f);
        animator.setDuration(5000);
        animator.setRepeatCount(-1);
        animator.start();
    }
}

注意事项

此处的动画只是为了演示。可以根据需要改变自定view的改变滚动值的方法,就可以使滚轮滚动。例如将滚动的角度和手指拖动相结合啥的

    /**
     * 滚动的偏移值
     * @param deviantAngle 最大为1
     */
    public void setDeviantAngle(float deviantAngle)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中,你可以通过使用ScrollView和TextView实现文本的上下滚动。 1. 首先,在布局文件中使用ScrollView和TextView,将TextView放在ScrollView中,这样TextView的内容就可以在ScrollView的范围内上下滚动。 示例代码如下: ```xml <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="这里是一段很长的文本,需要滚动才能看完。"/> </ScrollView> ``` 2. 接下来,在代码中,你可以使用`TextView`的`setMovementMethod()`方法来启用TextView滚动功能。这个方法接受一个实现了`MovementMethod`接口的对象,我们可以使用`android.text.method.ScrollingMovementMethod`类来实现文本滚动。 示例代码如下: ```java TextView textView = findViewById(R.id.text_view); textView.setMovementMethod(new ScrollingMovementMethod()); ``` 这样,当用户在TextView中滑动时,文本就可以上下滚动了。 注意,如果你在TextView中使用了`android:autoLink`属性或者添加了点击事件,滚动可能会失效。这时你可以在代码中为TextView设置`setClickable(false)`和`setLongClickable(false)`来禁用点击事件。 示例代码如下: ```java TextView textView = findViewById(R.id.text_view); textView.setMovementMethod(new ScrollingMovementMethod()); textView.setClickable(false); textView.setLongClickable(false); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值