Réalisation d'effet de défilement vers le haut et vers le bas Android

Le produit doit faire défiler le texte de haut en bas. La première chose qui me vient à l'esprit est d'utiliser l'animation d'attributs pour basculer entre deux TextViews. J'ai lu un tas de documents sur Internet et la plupart sont TextSwitch. Il est vraiment mélancolique d'écrire un blog sans publier les rendus. Je ne connais pas l'effet spécifique, s'il y a un problème avec le premier interrupteur, s'il y a un problème avec le dernier passage au second, si l'animation est fluide, etc. Je ne vois rien. Donc selon la première idée, j'ai trouvé une approche similaire, mais cela semble être un problème, alors je l'ai modifiée. Le rendu est le suivant: (La cadence d'images gif est un peu faible, pas très fluide, et ça marche bien sur la vraie machine)

 

L'idée est que les deux TextViews utilisent une animation d'attribut pour basculer vers le haut et vers le bas, retardant le thread d'envoi pour déclencher le prochain défilement.

code montrer comme ci-dessous:

1.ScrrollTextView.java

import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.lanjinger.choiassociatedpress.R;

import java.util.List;

/**
 * 上下滚动的 textView
 */
public class ScrollTextView extends LinearLayout {
    private TextView mBannerTV1;
    private TextView mBannerTV2;
    private Handler handler;
    private boolean isShow = false;
    private int startY1, endY1, startY2, endY2;
    private Runnable runnable;
    private List<String> list;
    private int position = 0;
    private int offsetY = 100;
    private boolean hasPostRunnable = false;

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

    public ScrollTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        View view = LayoutInflater.from(context).inflate(R.layout.widget_scroll_text_layout, this);
        mBannerTV1 = view.findViewById(R.id.tv_banner1);
        mBannerTV2 = view.findViewById(R.id.tv_banner2);
        handler = new Handler();
        runnable = new Runnable() {
            @Override
            public void run() {
                isShow = !isShow;
                if (position == list.size() - 1) {
                    position = 0;
                }

                if (isShow) {
                    mBannerTV1.setText(list.get(position++));
                    mBannerTV2.setText(list.get(position));
                } else {
                    mBannerTV2.setText(list.get(position++));
                    mBannerTV1.setText(list.get(position));
                }

                startY1 = isShow ? 0 : offsetY;
                endY1 = isShow ? -offsetY : 0;
                ObjectAnimator.ofFloat(mBannerTV1, "translationY", startY1, endY1).setDuration(300).start();

                startY2 = isShow ? offsetY : 0;
                endY2 = isShow ? 0 : -offsetY;
                ObjectAnimator.ofFloat(mBannerTV2, "translationY", startY2, endY2).setDuration(300).start();

                handler.postDelayed(runnable, 3000);
            }
        };
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;

        //处理最后一条数据切换到第一条数据 太快的问题
        if (list.size() > 1) {
            list.add(list.get(0));
        }
    }

    public void startScroll() {
        mBannerTV1.setText(list.get(0));
        if (list.size() > 1) {
            if(!hasPostRunnable) {
                hasPostRunnable = true;
                //处理第一次进入 第一条数据切换第二条 太快的问题
                handler.postDelayed(runnable,3000);
            }
        } else {
            //只有一条数据不进行滚动
            hasPostRunnable = false;
//            mBannerTV1.setText(list.get(0));
        }
    }

    public void stopScroll() {
        handler.removeCallbacks(runnable);
        hasPostRunnable = false;
    }


}

Points à noter: 1. Pour activer et désactiver le défilement, les deux doivent être contrôlés en dehors du contrôle. Si vous avez besoin de le contrôler vous-même à l'intérieur du contrôle,

onAttachedToWindow Démarrez le fil de discussion ici, faites attention à déterminer si la liste est vide.

2. Lorsque les données de la liste sont supérieures à 1, j'ajouterai manuellement les premières données à l'arrière. Afin d'éviter, la dernière est commutée sur une car le défilement est trop rapide (c'est-à-dire le problème d'un effet dynamique non évident ), Je ne l'ai pas jugé ici., Parce qu'il doit y avoir des données transmises, donc Yan Jin peut ajouter un blanc.


2.widget_scroll_text_layout.xml

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

    <TextView
        android:id="@+id/tv_banner1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:ellipsize="end"
        android:singleLine="true"
        android:textColor="@color/skin_common_title"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/tv_banner2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:ellipsize="end"
        android:singleLine="true"
        android:textColor="@color/skin_common_title"
        android:textSize="12sp" />

</RelativeLayout>

3. Appel spécifique

        ScrollTextView marqueeText = headView.findViewById(R.id.xxxx);

        List<String> demographicsList = new ArrayList<>();

        demographicsList.add("今日测试股票 上市");
        demographicsList.add("今日科伦药业 中国人保 可申购");
        demographicsList.add("今日中国平安 上市");

        marqueeText.setList(demographicsList);
        marqueeText.startScroll();

Remarque: gérez correctement le problème du cycle de vie. Quand appeler starScroll () et stopScroll (), cela dépend du cycle de vie spécifique;


queue:

Je pense que vous pouvez définir n'importe quelle animation de cette manière, et vous pouvez personnaliser l'animation d'attribut en fonction de vos besoins, et il n'y a pas besoin de nouveau TextView () supplémentaire; un simple regard, il semble que TextSwitch est un peu plus gênant.

Une fois la tâche d’aujourd’hui terminée, j’étudierai TextSwitch et comparerai les avantages et les inconvénients des deux;

 

Je suppose que tu aimes

Origine blog.csdn.net/android_freshman/article/details/84105637
conseillé
Classement