ANDROID視頻引導(dǎo)滑動(dòng)黑屏掃雷以及解決方案

首發(fā)自: ANDROID視頻引導(dǎo)滑動(dòng)黑屏掃雷以及解決方案

前一段時(shí)間,公司項(xiàng)目需要做一個(gè)視頻引導(dǎo)的功能聊品,剛開始以為用個(gè) ViewPager+Fragment+VideoView 不就實(shí)現(xiàn)了嗎赐俗,很快就弄好了。不過后來測(cè)試發(fā)現(xiàn)在滑動(dòng)切換頁面時(shí)會(huì)出現(xiàn)黑屏秆乳,比較影響用戶體驗(yàn),然后在網(wǎng)上找了各種“可行”的方案,都未能完全解決屹堰,最后嘗試了一種巧妙的方法才解決這個(gè)問題肛冶。

首先說明下,這里視頻引導(dǎo)用到的技術(shù)點(diǎn)是 ViewPager+Fragment+VideoView(當(dāng)然也使用過 SurfaceView 來實(shí)現(xiàn)扯键,不過原理基本一致)睦袖,產(chǎn)品提供四個(gè)單獨(dú)的視頻(不是一個(gè)視頻)+ 引導(dǎo)的圓點(diǎn)和進(jìn)入主頁的按鈕(不是直接添加在視頻上的)。另外限制條件是荣刑,產(chǎn)品未提供每個(gè)視頻的第一幀的圖片馅笙。

解決滑動(dòng)切換頁面黑屏的問題

出現(xiàn)黑屏的解釋:videoview加載資源需要一定的耗時(shí),無內(nèi)容時(shí)會(huì)繪制黑色背景厉亏。

1.用遮罩方式掩蓋黑屏

用第一幀的圖片作為 videoview 的遮罩董习,當(dāng)視頻加載好,再隱藏掉這個(gè)遮罩爱只。以下例子并不能完全解決黑屏:

2.用PageTransformer設(shè)置滑動(dòng)時(shí)切換的動(dòng)畫

當(dāng)頁面比較多時(shí)预麸,快速滑動(dòng)切換,ViewPager 會(huì)閃一下儒将,可以添加切換動(dòng)畫作為緩沖吏祸。
了解自定義 PageTransformer 動(dòng)畫可以看下這個(gè)庫: GitHub - ToxicBakery/ViewPagerTransforms: Library containing common animations needed for transforming ViewPager scrolling for Android v13+.

3.在每個(gè) page 頁增加一個(gè)寬高都為0的 SurfaceView

無效

4.入坑:使用videoView.setZOrderOnTop(true)避免黑屏

在視頻加載前設(shè)置一張圖片作為過渡圖片,之后調(diào)用videoView.setZOrderOnTop(true)钩蚊,確實(shí)可以解決滑動(dòng)黑屏問題贡翘,不過調(diào)用了該方法,會(huì)使其他控件被 VideoView 覆蓋砰逻。前面的幾種方案由于條件限制效果都不是很好鸣驱,這種方法基本看不到黑屏,但卻出現(xiàn)了另一個(gè)問題:如何將圓點(diǎn)和按鈕置于 VideoView 上面蝠咆?

解決調(diào)用videoView.setZOrderOnTop(true)踊东,其他控件被覆蓋的問題

由于 VideoView 是繼承 SurfaceView 的北滥,也查了相關(guān)解決方案,遇到不少坑

坑1:

解決SurfaceView調(diào)用setZOrderOnTop(true)遮擋其他控件的問題

調(diào)用setZOrderOnTop(true)之后調(diào)用了setZOrderMediaOverlay(true)再設(shè)置控件顯示闸翅,解決遮擋問題再芋,但是又出現(xiàn)了黑屏問題,也就是說調(diào)用setZOrderMediaOverlay(true)會(huì)使前面設(shè)置的setZOrderOnTop(true)失效

坑2:

解決SurfaceView設(shè)置透明造成覆蓋其他組件的替代方案 - jwzhangjie的專欄CSDN.NET
里面提到的兩種在 SurfaceView設(shè)置了setZOrderOnTop(true)后缎脾,添加其他組件的方法:使用 PopupWindow 作為容器承載其他控件祝闻,考慮到setZOrderOnTop(true)能覆蓋其他控件占卧,所以也嘗試了用SurfaceView 繪制圓點(diǎn)和按鈕(在 videoview調(diào)用setZOrderOnTop(true) 后調(diào)用自身的setZOrderOnTop(true)覆蓋在上面)遗菠。在我的實(shí)踐中,
a.用 PopupWindow 作為容器华蜒,大部分手機(jī)可以使圓點(diǎn)和按鈕置于上面辙纬,但小米手機(jī)第一屏不行,home 鍵后也會(huì)圓點(diǎn)也會(huì)被覆蓋掉;
b.用 SurfaceView 作為容器小米手機(jī)正常了叭喜,其他手機(jī)異常贺拣,圓點(diǎn)和按鈕不能顯示在 VideoView 上面。捂蕴。譬涡。

以上兩種方法部分手機(jī)異常都找不到具體原因。

解決方案

最終使用了Dialog 作為圓點(diǎn)和按鈕的容器才解決控件被覆蓋的問題啥辨。不過 Dialog 會(huì)使 ViewPager 的滑動(dòng)失效涡匀,需要重寫 Dialog 的 onTouch 事件,將 TouchEvent 傳遞給 ViewPager 處理溉知,同時(shí)要設(shè)置Dialog.setCancelable(false); 避免按返回鍵陨瘩,對(duì)話框消失掉。
不完整代碼如下:

public class ContainerDialog extends Dialog {
    private OnTouchOutsideListener onTouchOutsideListener;

    public ContainerDialog(Context context, int theme) {
        super(context, theme);
    }

    public void setOnTouchOutsideListener(OnTouchOutsideListener onTouchOutsideListener){
        this.onTouchOutsideListener = onTouchOutsideListener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(onTouchOutsideListener!=null){
            return onTouchOutsideListener.onTouchOutside(event);
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void show() {
        super.show();
        Window window = this.getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        window.setGravity(Gravity.BOTTOM);
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(layoutParams);
        window.setBackgroundDrawableResource(android.R.color.transparent);
    }

    public interface OnTouchOutsideListener{
        boolean onTouchOutside(MotionEvent event);
    }
}

對(duì)話框主題

<style name="FeatureDialogTheme" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

使用方法

        //……
        ContainerDialog mDialog = new ContainerDialog(this, R.style.FeatureDialogTheme);
        mDialog.setContentView(dotsAndBtnView);
        mDialog.setCancelable(false);
        mDialog.setOnTouchOutsideListener(new ContainerDialog.OnTouchOutsideListener() {
            @Override
            public boolean onTouchOutside(MotionEvent event) {
                mViewPager.onTouchEvent(event);
                return true;
            }
        });
        mDialog.show();

在調(diào)用 VideoView.start()前加以下兩行代碼避免黑屏

mVideoView.setZOrderOnTop(true);   
mVideoView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

其他代碼略

注:以上是針對(duì)公司項(xiàng)目有限的條件下的測(cè)試結(jié)果级乍,并不保證其他項(xiàng)目也一樣(代碼調(diào)用位置和使用方法不同舌劳,可能效果不一樣),只是提供一些方案和想法玫荣。

另外甚淡,未嘗試的方法:
1.只用一個(gè) VideoView,切換 ViewPager 只是變化圓點(diǎn)和 VideoView 的 url捅厂,避免切換 VideoView 的黑屏贯卦;參照 仿蝦米音樂引導(dǎo)頁面 - Kevin Blog CSDN.NET
2.使用視頻縮略圖解決視頻黑屏,參照 Android之ViewPager+VideoView引導(dǎo)界面 - 博客頻道 - CSDN.NET

獲取視頻縮略圖
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(this, mUri);
mImageView.setImageBitmap(mmr.getFrameAtTime());
添加ViewPager 滑動(dòng)監(jiān)聽
ViewPager.addOnPageChangeListener,
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
在這個(gè)函數(shù)里處理縮略圖的顯示
public void onPageScrollStateChanged(int state) state==0 時(shí)視圖準(zhǔn)備好了
在這個(gè)函數(shù)里處理縮略圖的消失

—EOF—


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恒傻,一起剝皮案震驚了整個(gè)濱河市脸侥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盈厘,老刑警劉巖睁枕,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡外遇,警方通過查閱死者的電腦和手機(jī)注簿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跳仿,“玉大人诡渴,你說我怎么就攤上這事》朴铮” “怎么了妄辩?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)山上。 經(jīng)常有香客問我眼耀,道長(zhǎng),這世上最難降的妖魔是什么佩憾? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任哮伟,我火速辦了婚禮,結(jié)果婚禮上妄帘,老公的妹妹穿的比我還像新娘楞黄。我一直安慰自己,他們只是感情好抡驼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布鬼廓。 她就那樣靜靜地躺著,像睡著了一般婶恼。 火紅的嫁衣襯著肌膚如雪桑阶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天勾邦,我揣著相機(jī)與錄音蚣录,去河邊找鬼。 笑死眷篇,一個(gè)胖子當(dāng)著我的面吹牛萎河,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蕉饼,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼虐杯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了昧港?” 一聲冷哼從身側(cè)響起擎椰,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎创肥,沒想到半個(gè)月后达舒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體值朋,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年巩搏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昨登。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贯底,死狀恐怖丰辣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情禽捆,我是刑警寧澤笙什,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站睦擂,受9級(jí)特大地震影響得湘,放射性物質(zhì)發(fā)生泄漏杖玲。R本人自食惡果不足惜顿仇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摆马。 院中可真熱鬧臼闻,春花似錦、人聲如沸囤采。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕉毯。三九已至乓搬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間代虾,已是汗流浹背进肯。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棉磨,地道東北人江掩。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像乘瓤,于是被迫代替她去往敵國和親环形。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容