1. 程式人生 > >Android TV利用viewPager實現輪播圖,並通過handler進行邏輯控制

Android TV利用viewPager實現輪播圖,並通過handler進行邏輯控制

    公司要求實現一個輪播圖,滾動圖片及其對應文字。共有五張圖,包含小圓點。

    最初的實現是參考了https://blog.csdn.net/zhaoxiaojian1213/article/details/78280132,使用ViewPager實現,新開一個執行緒去開啟輪播,並在其中控制跳向下一張圖。給viewPager設定OnPageChangeListener,來控制小圓點的變化。在Adapter中重寫的getCount方法中設定return Integer.MAX_VALUE;實現偽無限迴圈。除資料部分是動態獲取的,大致思路與連結中相似。但是這樣做有一些問題:輪播只有在Activity銷燬的時候才可以停止,不可以手動根據需求控制其停止與播放。

    現在增加如下的需求:當焦點位於輪播圖內時,禁用輪播,可以左右鍵控制圖片的切換;當輪播圖位於第五張時(總共五張),按下右鍵之後跳轉到右邊的ListView上,並且開啟輪播;在輪播圖內按下鍵,焦點會到下方的TextView上,且也會開啟輪播(這兩句的意思也就是說焦點在輪播圖以外需要開啟輪播);當輪播圖位於第一張時,禁用左鍵切換圖片。

    之後根據組長的建議修改了實現的方法:不開啟執行緒,而是重寫dispatchKeyEvent方法,在其中判斷對應的狀態,分別sendEmptyMessage和removeMessages,在Handler中進行控制。關鍵程式碼如下:

//viewPager是輪播圖,text_right是ListView推薦位,e1是下方的TextView
@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		int flag = viewPager.getCurrentItem();
		// 不響應按鍵彈起動作
		if (event.getAction() != KeyEvent.ACTION_UP) {
			if (viewPager.hasFocus()) {
				// 輪播圖位於第五張圖時,再次按右鍵跳到右邊的推薦,並開啟輪播
				if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT & flag % 5 == 4) {
					uiHandler.removeMessages(MSG_START_PPT);
					text_right.requestFocus();
					// 始終跳到第一個推薦位
					text_right.setSelection(0);
					uiHandler.sendEmptyMessage(MSG_START_PPT);
					return true;
				}

				// 焦點在輪播圖時,按下鍵跳到下方的按鈕,並開啟輪播
				if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
					e1.requestFocus();
					uiHandler.sendEmptyMessage(MSG_START_PPT);
				}

				// 輪播圖位於第一張圖時,按左鍵無響應
				if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT & flag % 5 == 0) {
					uiHandler.removeMessages(MSG_START_PPT);
					return true;
				}
			}
		}

		// 不響應按鍵按下動作
		if (event.getAction() != KeyEvent.ACTION_DOWN) {
			// 焦點位於輪播圖時,輪播圖停止輪播
			if (viewPager.hasFocus()) {
				uiHandler.removeMessages(MSG_START_PPT);
			}
		}
		return super.dispatchKeyEvent(event);
	}
static final int MSG_START_PPT = 1;
Handler uiHandler = new Handler(Looper.getMainLooper()) {
	public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
            case MSG_START_PPT:
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                sendEmptyMessageDelayed(MSG_START_PPT, 5000);
                break;
            default:
                break;
        }
    };
};

    比較有趣的一點是關於dispatchKeyEvent的。在遙控器按下和鬆開時分別會分發一次。可以設定判斷event.getAction() != KeyEvent.ACTION_UP和DOWN來遮蔽其中的一種,再在裡面寫邏輯,實現的效果是不一樣的。