1. 程式人生 > >【Android 進階】淘寶頭條:向上滾動廣告條ViewFlipper

【Android 進階】淘寶頭條:向上滾動廣告條ViewFlipper

所謂前人栽樹,後人乘涼,在此感謝博主的貢獻。
參考博文:
仿淘寶首頁的淘寶頭條View垂直滾動

歡迎關注我的微信公眾號
不只是原創技術文章,更多的是對生活的思考總結
這裡寫圖片描述

我在博主的基礎上做了如下工作

  • 修復了滾動條第二條點選事件無法觸發這個bug;
  • 充分簡化了自定義ViewFlipper類的程式碼;
  • 添加了直接使用ViewFlipper控制元件實現同樣效果;

先上效果圖

這裡寫圖片描述

這裡使用了一個比較少用的控制元件:ViewFlipper
學習一個未知的東西,第一步就是要搞懂what:學的這個東西是什麼以及能夠實現什麼效果!第二步就是要搞懂How:這個東西如何使用。

What:

該控制元件的官方介紹

Simple ViewAnimator that will animate between two or more views that
have been added to it. Only one child is shown at a time. If
requested, can automatically flip between each child at a regular
interval.

鄙人的翻譯

簡單ViewAnimator實現器將已新增到其兩個或多個檢視之間實現動畫效果。 一次只顯示一個孩子(子檢視)。
如果需要,可以在每個孩子(子檢視)之間定期自動翻轉。

How:

實現方式

1.繼承ViewFlipper類通過程式碼設定動畫間隔時間以及動畫效果

1.1自定義ViewFlipper


/**
 * Created by Veyron on 2017/2/20.
 * Function:自定義ViewFlipper控制元件
 */

public class UpView extends ViewFlipper {

    private Context mContext;
    private boolean isSetAnimDuration = false;
    private int interval = 2000;
    /**
     * 動畫時間
     */
private int animDuration = 500; public UpView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { this.mContext = context; setFlipInterval(interval);//設定時間間隔2000毫秒 //進來的動畫 Animation animIn = AnimationUtils.loadAnimation(mContext, R.anim.anim_in); if (isSetAnimDuration) animIn.setDuration(animDuration); setInAnimation(animIn); //退出的動畫 Animation animOut = AnimationUtils.loadAnimation(mContext, R.anim.anim_out); if (isSetAnimDuration) animOut.setDuration(animDuration); setOutAnimation(animOut); } /** * 設定迴圈滾動的View陣列 * * @param views */ public void setViews(final List<View> views) { if (views == null || views.size() == 0) return; removeAllViews(); for ( int i = 0; i < views.size(); i++) { final int position=i; //設定翻滾的子view addView(views.get(i)); } startFlipping(); //開啟翻滾 } }

1.2佈局檔案中引入

 <com.veyron.www.viewflipperdemo.View.UpView
            android:id="@+id/upview1"
            android:layout_marginLeft="20dp"
            android:layout_width="match_parent"
            android:layout_toRightOf="@+id/tbtv"
            android:layout_centerVertical="true"
            android:layout_marginTop="10dp"
            android:layout_height="match_parent">
            </com.veyron.www.viewflipperdemo.View.UpView>

2.除了方式一,還可以在佈局檔案中通過設定ViewFlipper的屬性來達到同樣的效果。

<ViewFlipper
            android:id="@+id/upview2"
            android:autoStart="true"
            android:background="#fff"
            android:inAnimation="@anim/anim_in"
            android:outAnimation="@anim/anim_out"
            android:flipInterval="3000">
            </ViewFlipper>

具體實現上面兩種方式

MainActivity.java


/**
 * Created by Veyron on 2017/2/20.
 * Function:主介面,載入佈局
 */
public class MainActivity extends AppCompatActivity {
        private UpView upview1;   //自定義的ViewFlipper
        private ViewFlipper mViewFlipper;  //直接使用該控制元件

        List<String> data = new ArrayList<>();   //文字資料集合
        List<View> views = new ArrayList<>();    //滾動的view集合

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

    private void initView() {
        //自定義的
        upview1 = (UpView) findViewById(R.id.upview1);
        setView();
        upview1.setViews(views);//給自定義的ViewFlipper設定滾動的view


        //非自定義的,直接使用控制元件的
        mViewFlipper = (ViewFlipper) findViewById(R.id.upview2);
        //新增翻滾的子view
        mViewFlipper.addView(View.inflate(this, R.layout.view1, null));
        mViewFlipper.addView(View.inflate(this, R.layout.view2, null));
    }

    /**
     * 初始化需要迴圈的View
     * 為了靈活的使用滾動的View,所以把滾動的內容讓使用者自定義
     * 假如滾動的是三條或者一條,或者是其他,只需要把對應的佈局,和這個方法稍微改改就可以了,
     */
    private void setView() {
        for (int i = 0; i < data.size(); i = i + 2) {
            final int position = i;
            //設定滾動的單個佈局
            LinearLayout moreView = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.item_view, null);
            //初始化佈局裡面的控制元件,只要設定這兩個控制元件的監聽就達到目的
            TextView tv1 = (TextView) moreView.findViewById(R.id.tv1);
            TextView tv2 = (TextView) moreView.findViewById(R.id.tv2);

            /**
             * 設定監聽
             */
            moreView.findViewById(R.id.rl).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this,  data.get(position).toString(), Toast.LENGTH_SHORT).show();
                    Log.d("TAG",data.get(position).toString());
                    /**
                     * 新增業務程式碼
                     */
                }
            });
            /**
             * 設定監聽
             */
            moreView.findViewById(R.id.rl2).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this,  data.get(position+1).toString(), Toast.LENGTH_SHORT).show();
                    Log.d("TAG",data.get(position+1).toString());
                    /**
                     * 新增業務程式碼
                     */
                }
            });


            //進行對控制元件賦值
            tv1.setText(data.get(i).toString());
            if (data.size() > i + 1) {
                //因為淘寶那兒是兩條資料,但是當資料是奇數時就不需要賦值第二個,所以加了一個判斷,還應該把第二個佈局給隱藏掉
                tv2.setText(data.get(i + 1).toString());
            } else {
                moreView.findViewById(R.id.rl2).setVisibility(View.GONE);
            }

            //新增到迴圈滾動數組裡面去
            views.add(moreView);   //也就是滾動的view集合
        }
    }
    /**
     * 初始化資料
     */
    private void initdata() {
        data = new ArrayList<>();
        data.add("美劇《行屍走肉》上線Steam 每一集售價2.99...");
        data.add("2017四月新番動畫全預覽!你期待那部");
        data.add("生娃後,老公有過這些舉動,你卻沒加錯人!");
        data.add("汽車開空調耗油?只因為按錯了一個鍵");
        data.add("心疼S7 edge 三星官方‘虐機’視訊上線");
    }
}

API介紹

常用屬性

  • autoStart:ture,則自動開始滾動
  • inAnimation:滾動進入的動畫
  • outAnimation:滾動出去的動畫
  • flipInterval:時間間隔

常用方法

  • startFlipping():開始翻滾
  • setOutAnimation():滾動出去的動畫
  • setInAnimation():滾動進入的動畫
  • setFlipInterval():設定時間間隔-毫秒
  • ViewFlipper物件的addView():載入需要滾動的檢視物件

原始碼

如果該你喜歡該專案,歡迎fork,歡迎點個Star!!