自定義textview實現豎直滾動跑馬燈效果

xml佈局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="myandroidstituds.test3.MainActivity">

    <LinearLayout
        android:layout_centerInParent="true"
        android:layout_width="180dp"
        android:layout_height="50dp">
    <TextView
        android:padding="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#55000000"
        />
    </LinearLayout>
    <myandroidstituds.test3.MarqueeLayout
        android:id="@+id/mar"
        android:layout_centerInParent="true"
        android:layout_width="180dp"
        android:layout_height="50dp">
        <TextView
            android:id="@+id/tv1"
            android:textSize="20sp"
            android:gravity="center"
            android:background="@android:color/transparent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textColor="#000000"
            android:visibility="gone"
            android:text="兩個黃鸝鳴翠柳"
            />
        <TextView
            android:id="@+id/tv2"
            android:textSize="20sp"
            android:background="@android:color/transparent"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textColor="#000000"
            android:visibility="gone"
            android:text="一行白鷺上青天"
            />
    </myandroidstituds.test3.MarqueeLayout>
</RelativeLayout>

自定義MarqueeLayout

public class MarqueeLayout extends FrameLayout implements ViewTreeObserver.OnGlobalLayoutListener{
    private View view1;
    private View view2;
    public int interval = 2000;
    public MarqueeLayout(Context context) {
        this(context,null);
    }
    public MarqueeLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public MarqueeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getViewTreeObserver().addOnGlobalLayoutListener(this);
    }
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if(getChildCount()!=2){
            throw  new IllegalArgumentException("MarqueeLayout should have 2 child!");
        }
        view1 = getChildAt(0);
        view2 = getChildAt(1);
    }
    @Override
    public void onGlobalLayout() {
        getViewTreeObserver().removeGlobalOnLayoutListener(this);

        view2.setTranslationY(view2.getHeight());
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            startAnim();
        }
    };
    boolean isAniming = false;
    /**
     * 開始滾動
     */
    public void start(){
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                startAnim();
            }
        });
    }
    public void startAnim(){
        if(isAniming)return;

        isAniming = true;
        int targetY1 = view1.getTranslationY()==0?-view1.getHeight():0;
        int targetY2 = view2.getTranslationY()==0?-view2.getHeight():0;

        ViewCompat.animate(view1)
                .translationY(targetY1)
                .setListener(new ViewPropertyAnimatorListenerAdapter(){
                    @Override
                    public void onAnimationEnd(View view) {
                        super.onAnimationEnd(view);
                        //移動到下方
                        resetView(view);
                    }
                })
                .setDuration(400).start();
        ViewCompat.animate(view2)
                .translationY(targetY2)
                .setListener(new ViewPropertyAnimatorListenerAdapter(){
                    @Override
                    public void onAnimationEnd(View view) {
                        super.onAnimationEnd(view);
                        //移動到下方
                        resetView(view);
                        isAniming = false;
                        handler.sendEmptyMessageDelayed(0,interval);
                    }
                })
                .setDuration(400)
                .start();
    }
    private void resetView(View view) {
        if(view.getTranslationY()==-view.getHeight()){
            view.setTranslationY(view.getHeight()*2);
        }
    }
    public void stop(){
        handler.removeCallbacksAndMessages(null);
    }
}

在Activity中的使用

public class MainActivity extends AppCompatActivity {

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

        MarqueeLayout marqueeLayout = (MarqueeLayout) findViewById(R.id.mar);
        TextView tv1 = (TextView) findViewById(R.id.tv1);
        TextView tv2 = (TextView) findViewById(R.id.tv2);
        marqueeLayout.start();
        tv1.setVisibility(tv1.getTranslationY() == 0 ? View.VISIBLE : View.GONE);
        tv2.setVisibility(tv2.getTranslationY() == 0 ? View.VISIBLE : View.GONE);

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章