<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android實(shí)現(xiàn)抖音評(píng)論彈窗與視頻聯(lián)動(dòng)縮放效果

          共 5744字,需瀏覽 12分鐘

           ·

          2022-05-18 17:08

          閑來(lái)無(wú)事刷刷抖音,發(fā)現(xiàn)抖音從最開(kāi)始的彈窗已換成了彈出彈窗視頻在最上方并且按一定比例縮放,如下圖:



          要實(shí)現(xiàn)上圖聯(lián)動(dòng)效果,接下來(lái)提幾個(gè)方法:

          setScaleX(float scaleX) //水平方向的縮放比例setScaleY(float scaleY) //垂直方向的縮放比例//scaleX scaleY = 1.0f 表示初始大小// scaleX scaleY < 1.0f,表示縮小,如scale=0.5f,表示寬高是原來(lái)的0.5倍//scaleX scaleY> 1.0f,表示放大,如scale=2.0f,表示寬高是原來(lái)的2.0倍//設(shè)置錨點(diǎn)的X坐標(biāo)值,以像素為單位。默認(rèn)是View的中心。setPivotX(float pivotX)//設(shè)置錨點(diǎn)的Y坐標(biāo)值,以像素為單位。默認(rèn)是View的中心。setPivotX(float?pivotX)

          其他的我就不一一介紹了,本文主要用到的就是這幾個(gè)方法。


          接下來(lái)講一下我的思路,我在這里并沒(méi)有用特別復(fù)雜的功能,所以本文主要是為了實(shí)現(xiàn)滑動(dòng)縮放功能。


          首先分析一下布局方式,主頁(yè)一個(gè)視頻View,然后點(diǎn)擊評(píng)論按鈕彈出底部操作欄,放出布局,一個(gè)視頻一個(gè)按鈕:

          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent">
          <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="match_parent" />
          <android.support.design.widget.FloatingActionButton android:id="@+id/floatBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentBottom="true" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" app:srcCompat="@android:drawable/ic_dialog_email" />
          RelativeLayout>


          Fab添加點(diǎn)擊事件,彈出BottomSheetDialog

                  findViewById(R.id.floatBtn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                BottomSheetDialog bsd= new BottomSheetDialog();                bsd.setFragmentManager(getSupportFragmentManager())                        .setLayoutRes(R.layout.view_dialog_comment)                        .setCancelOutside(true)                        .setViewListener(v1 -> {                        })                        .show();            }        });



          是彈出來(lái)了但是還沒(méi)有關(guān)聯(lián)上,所以還要定義一個(gè)狀態(tài)回調(diào)接口來(lái)獲取每次操作狀態(tài)回調(diào)。


          關(guān)鍵代碼

              public IBehaviorChanged getBehaviorChanged() {        return mBehaviorChanged;    }
          public void setBehaviorChanged(IBehaviorChanged behaviorChanged) { mBehaviorChanged = behaviorChanged; }
          public interface IBehaviorChanged { void changedState(View bottomSheet, int state);
          void changedOffset(View bottomSheet, float slideOffset); }


                      BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);            // 初始為展開(kāi)狀態(tài)            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);            behavior.setPeekHeight(0);            //注意這句,初始的時(shí)候給一個(gè)默認(rèn)值,因?yàn)槟J(rèn)是展開(kāi)狀態(tài),所以給的狀態(tài)是STATE_EXPANDED,具體可以根據(jù)需求來(lái)            if (mBehaviorChanged != null)                mBehaviorChanged.changedState(null, BottomSheetBehavior.STATE_EXPANDED);            behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {                @Override                public void onStateChanged(@NonNull View bottomSheet, int newState) {                    //這里加上這句話是因?yàn)樾枰褷顟B(tài)加上,不然的話滑出屏幕會(huì)有黑色陰影                    //具體可以看源碼                    if (newState == BottomSheetBehavior.STATE_HIDDEN || newState == BottomSheetBehavior.STATE_COLLAPSED) {                        dismiss();                    }                    if (mBehaviorChanged != null)                        mBehaviorChanged.changedState(bottomSheet, newState);                }
          @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { if (mBehaviorChanged != null) mBehaviorChanged.changedOffset(bottomSheet, slideOffset); } });


          因?yàn)槭謾C(jī)坐標(biāo)系統(tǒng)默認(rèn)是從屏幕左上角開(kāi)始計(jì)算。

          我在這里默認(rèn)給了dialog的高度是1280/(3/2),也就是用1280-1280/(3/2)就是視頻的最小高度。


          得到高度之后還要繼續(xù)計(jì)算高度占比來(lái)進(jìn)行等比例縮放:

          Dialog 高度占比 = 1280/(3/2)/1280≈0.67

          VideoView 高度占比 = 1280-(1280/(3/2))/1280≈0.33

          所以0.33這個(gè)系數(shù)就是setScaleX()和setScaleY()的縮放比


          因?yàn)镈ialog滑動(dòng)距離一直在改變,得到滑動(dòng)距離之后用當(dāng)前距離除以總高度,就是縮放比。


          當(dāng)Dialog滑動(dòng)到屏幕最大之后也就會(huì)變成1280/1280=1.0f,所以視頻也要恢復(fù)初始大小scale(1.0f)。


          可以看到視頻始終是在屏幕正上方,中心點(diǎn)在屏幕寬度的1/2處,進(jìn)行縮放,所以當(dāng)Dialog彈出的時(shí)候videoView的x,y坐標(biāo)可以固定在這個(gè)地方,初始狀態(tài)也就是從0開(kāi)始

                  if (scale) {            float width = Screen.getWidth();            float x = width / 2f;            videoView.setPivotX(x);            videoView.setPivotY(0);        } else {            videoView.setPivotX(0);            videoView.setPivotY(0);        }


          這里畫(huà)個(gè)圖:


          按照這個(gè)思路,查看BottomSheetCallback回調(diào),這里來(lái)添加一個(gè)Log打印一下bottomSheet的Y坐標(biāo):

                     behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {                @Override                public void onStateChanged(@NonNull View bottomSheet, int newState) {                }
          @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { Log.e("BottomSheetCallback","bottomSheet"+bottomSheet.getY());????????????});

          com.behavior.bottombehaviormaster E/BottomSheetCallback: bottomSheet382.0~~~com.behavior.bottombehaviormaster E/BottomSheetCallback: bottomSheet1230.0


          因太長(zhǎng)這里取最大值和最小值來(lái)比較一下1230~382 之間的高度差是848,為什么是1230呢?因?yàn)闆](méi)有計(jì)算系統(tǒng)狀態(tài)欄的高度,默認(rèn)是50dp,所以要加上這50dp


          接下來(lái),實(shí)現(xiàn)過(guò)程在回調(diào)方法中添加按比例縮放代碼及x,y坐標(biāo)代碼:

                          bcs.setBehaviorChanged(new BaseBottomSheetDialog.IBehaviorChanged() {                    @Override                    public void changedState(View bottomSheet, int state) {                        if (state == BottomSheetBehavior.STATE_EXPANDED) {                                float width = Screen.getWidth();                                float height = Screen.getHeight();                                float x = width / 2f;                                float scale = height - view.getHeight();                                videoView.setScaleX(scale / height);                                videoView.setScaleY(scale / height);                                videoView.setPivotX(x);                                videoView.setPivotY(0);                            });                        }                    }
          @Override public void changedOffset(View bottomSheet, float slideOffset) { startAnimator(bottomSheet); } }); /** * 根據(jù)滑動(dòng)高度進(jìn)行縮放 * @param parent */ private void startAnimator(View parent) { float width = Screen.getWidth(); float height = Screen.getHeight(); float x = width / 2f; float py = (parent.getY() + 50) / height; videoView.setScaleX(py); videoView.setScaleY(py); videoView.setPivotX(x); videoView.setPivotY(0); }


          接下來(lái)看實(shí)現(xiàn)結(jié)果:
          有一些需要優(yōu)化的地方,比如彈出Dialog不顯示StatusBar,彈出Dialog背景會(huì)變暗,解決掉這兩個(gè)問(wèn)題之后基本符合。



          源碼地址:

          https://github.com/futureLix/behavior


          到這里就結(jié)束啦。

          瀏覽 895
          點(diǎn)贊
          2評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          全部評(píng)論
          QS351966022eb68d7c12024-03-26 10:42
          你好
          點(diǎn)贊回復(fù)
          QS818665bb3fdbaec742024-02-01 14:54
          請(qǐng)教樓主下,如果是橫屏,有什么思路做嗎
          點(diǎn)贊回復(fù)
          推薦
          點(diǎn)贊
          2評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91精品国产综合久久久久久久 | 国产黄色影片免费 | 欧美一级视频在线观看 | 日韩中文在线观看视频 | 亚洲无码性爱视频在线观看 |