1. 程式人生 > >在匯入阿里 坑神SDK 時的新發現。

在匯入阿里 坑神SDK 時的新發現。

1.
隨便建一個    . gradle  字尾名  檔案。

比如說起名叫
config . gradle

內容如下::


ext {

/**
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 * 匯入狗日的阿里雲短視訊SDK
 */
projectVersion = '3.0.0-2017.1.22'
externalAndroidBuildGradlePlugin = 
'com.android.tools.build:gradle:2.2.0' externalAndroidAppCompatV7 = 'com.android.support:appcompat-v7:24.2.1' externalAndroidCardView = 'com.android.support:cardview-v7:21.0.+' externalAndroidMultiDex = 'com.android.support:multidex:1.0.1' externalAndroidRecyclerView = 'com.android.support:recyclerview-v7:24.2.1'
externalAndroidSupportV13 = 'com.android.support:support-v13:23.4.0' externalAndroidSupportV4 = 'com.android.support:support-v4:23.4.0' externalAndroidDesign = 'com.android.support:design:24.2.1' externalAndroidTestEspressoCore = 'com.android.support.test.espresso:espresso-core:2.2.2' externalAndroidTestRunner =
'com.android.support.test:runner:0.4.1' // externalAndroidAsyncHttp = 'com.loopj.android:android-async-http:1.4.9' // externalAutoFactory = 'com.google.auto.factory:auto-factory:1.0-beta2' // externalDagger = 'com.google.dagger:dagger:2.0.1' // externalDaggerCompiler = 'com.google.dagger:dagger-compiler:2.0.1' externalDexmakerDx = 'com.crittercism.dexmaker:dexmaker-dx:1.4' externalDexmakerMockito = 'com.crittercism.dexmaker:dexmaker-mockito:1.4' // externalFastJson = 'com.alibaba:fastjson:1.2.5' externalHamcrestLibrary = 'org.hamcrest:hamcrest-library:1.3' // externalInject = 'javax.inject:javax.inject:1' externalJSR305 = 'com.google.code.findbugs:jsr305:3.0.0' externalMockito = 'org.mockito:mockito-core:1.10.19' externalOrmLiteAndroid = 'com.j256.ormlite:ormlite-android:4.48' externalGlide = 'com.github.bumptech.glide:glide:3.7.0' externalGlideOkHttp = 'com.github.bumptech.glide:okhttp3-integration:[email protected]' externalOKHTTP = 'com.squareup.okhttp3:okhttp:3.2.0' externalGSON = 'com.google.code.gson:gson:2.8.0' externalOKIO = 'com.squareup.okio:okio:1.12.0' externalPagerSlidingTabStrip = 'com.astuetz:pagerslidingtabstrip:1.0.1' externalEasyPermissions = 'pub.devrel:easypermissions:0.2.1' externalJunit = 'junit:junit:4.12' externalCompileSdkVersion = 25 externalBuildToolsVersion = "25.0.1" externalMinSdkVersion=15 externalTargetSdkVersion=25 }


然後在  Module 的 build  裡面的  根目錄  ,   或者    Project專案 的  build  裡面的  buildScript {  }  目錄



apply from: 'config.gradle'




這豈不是
這豈不是
這豈不是

這豈不是  和  PHP 很像很像很像嗎????



require() 函式


或者 


include() 函式


然後變數值都可以用了啊啊啊啊

ext  列表名,  或許就意味著
global  關鍵字    在PHP中

只有聲明瞭,  才能全域性使用







2.非常詭異,非常     邪性的一點

詭異   +   邪性



這樣子能寫,

哪怕是   compile     ==     25

而官方限定死的     24.2.1

以下程式碼也可以光明正大的跑通

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile(project(':AliyunSnap:snap_core')) {
        transitive = false
}


    compile externalAndroidAppCompatV7
    compile externalAndroidDesign

    compile externalJSR305
    compile externalGlide
    compile externalEasyPermissions
    compile externalOKHTTP
    compile externalGlideOkHttp
    compile externalOKIO
    compile externalGSON

}




而以下這樣寫就不行


    compile 'com.android.support:appcompat-v7:24.2.1'//此處報錯
compile 'com.android.support:design:24.2.1'//此處報錯
compile 'com.google.code.findbugs:jsr305:3.0.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'pub.devrel:easypermissions:0.2.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.github.bumptech.glide:okhttp3-integration:[email protected]'
compile 'com.squareup.okio:okio:1.12.0'
compile 'com.google.code.gson:gson:2.8.0'
}



可見非常   邪性    ,    血腥      ,      邪性


但無疑非常好用。




3.

一些關鍵詞

compile

Conflict with dependency

App   ( 3.0.0 )

test App  ( 2.0.1 )

Resolved versions

testCompile

androidTestCompile

configurations.all  { }  
resolutionStrategy  { }
force  ' 倉庫:模組:版本  '
androidTestCompile (' 倉庫:模組:版本  '){
    exclude module:'模組名稱'}


以及,參照以下文章

https://github.com/square/assertj-android/issues/193

https://stackoverflow.com/questions/33317555/conflict-with-dependency-com-android-supportsupport-annotations-resolved-ver  【正解】

https://stackoverflow.com/questions/28999124/resolved-versions-for-app-22-0-0-and-test-app-21-0-3-differ

https://www.google.com.hk/search?safe=strict&source=hp&q=Error%3AConflict+with+dependency++Resolved+versions&oq=Error%3AConflict+with+dependency++Resolved+versions&gs_l=psy-ab.3...226.39418.0.40394.6.6.0.0.0.0.99.99.1.1.0....0...1.1.64.psy-ab..5.0.0.1RofdFC0v9c【搜尋】



【已解決】


4.

(1)
Error:

Dependency  XXXXX:  unspecified on project app resolves to an APK archive which is not supported as a compilation dependency


可能是:建立了兩個Module,其中一個Module依賴另一個Module而導致了出現該問題


解法:

  1. apply plugin: 'com.android.application'  

修改為
  1. apply plugin: 'com.android.library'  

(2)

Error:
Library projects cannot set applicationId. applicationId is set to 'package_name' in default config


Module  —— build . gradle ——  android {         defaultConfig     {            
                                                                           applicationId    "xxx包名“     //註釋掉。
                                                            }             }



以上兩種解法,
均來自於同一篇文章

http://blog.csdn.net/u012336923/article/details/48049479    【csdn部落格:yao偉斌







4.發現一點——————驚天大謎團。


阿里雲短視訊的  Demo 是   SDK  25 的版本,
卻可以使用
24.2.1 的V7包。


android {
    compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
        minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"


compile externalAndroidAppCompatV7
compile externalAndroidDesign



externalAndroidAppCompatV7 = 'com.android.support:appcompat-v7:24.2.1'
externalAndroidDesign = 'com.android.support:design:24.2.1'


至少編譯器錯誤層面上的區別,

在於從 外界ext  compile導的不會報錯。
直接寫固定的版本號,必定報錯。




後來再三檢視,好像只解決了編譯器在  dependencies中的  執行:

即————
                    使得  compileSDK  為  25,26  的Module  ,  能夠使用    24.0.0  的  v7  support  (以及其它各  版本同步包)


但仍然解決不了,
其它所有第三方庫中,    因為已封裝,      無法直接調換已寫死的    v7  support  (以及其它各  版本同步包)      的問題
即,只能解決【當前】        【所處專案】        的【問題】。

仍然無法穿透,

,,,,,,,,,,,,,,,,,,,,,,,,,,





5.改用【標準版】
基礎版的內容,連客服也說了,除了逐個改第三方庫的路徑,別無別法。

標準版:

1.問題一
unable to delete directory
解決辦法,將  報錯的build路徑,整個刪掉。重新來。

2.問題二

明明已經匯入了DownloaderManager包,偏偏說找不到。

更改build:gradle 外掛版本,即可   2.20 ————> 2.3.3

'com.android.tools.build:gradle:2.3.3'



6.
    if(key == R.mipmap.demo_camera_icon){Intent camera = new Intent("com.duanqu.qupai.action.camera");
    }


然後Manifest檔案,
<activity
android:name="com.aliyun.demo.recorder.CameraDemo">
    <intent-filter>
        <action android:name="com.duanqu.qupai.action.camera"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>


可見,是從這裡開始調取的。





7.大神文章,      解決所有傻逼阿里依賴。

【踩坑速記】二次依賴?android studio編譯執行各種踩坑解決方案,杜絕彎路,總有你想要的~

http://www.cnblogs.com/liushilin/p/6068098.html


針對《基礎版》,有可能達到必殺效果!!!

【等待嘗試  ing  】


【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去嘗試!!!!!!!!!!!!!!!!!!!!】


8.
結構分析【標準版】

Demo:引導頁面,進入各分支SDK的選單頁面。
AliyunCrop:crop_demo:視訊拼接與裁剪頁面。
AliyunRecorder:record_demo:視訊錄製頁面。
AliyunVideoSdk:僅包含arr和gradle的模組。
AliyunHelp:展示版權文字的頁面。
AliyunFileDownLoader:downloadermanager:提供下載各種彩圖動畫特效的下載模組。(如果不加入彩圖動畫,可以去掉。)
STMobileJNI:(據說是要,讓使用者自己選擇)怎樣顯示彩圖動畫、怎樣捕捉人臉位置加特效。(但因為沒有交費,沒有授權,所以Demo中不可用。)【而且,捕捉人臉和彩圖動圖,都是專業版才有的功能(那你他孃的放在這裡幹嘛?)】
AliyunView:用到的諸多自定義特效控制元件。

9.

有空要研究一下下面的寫法:

configurations.maybeCreate("default")
artifacts.add("default", file('AliyunSdk-RC.aar'))


在一個Module中,只有
一個    build.gradle    和一個    AliyunSdk-RC.arr    檔案

build.gradle    只有兩行程式碼。


而其它模組對這個寫法的模組的匯入為

dependencies {
    compile(project(':AliyunVideoSdk')) {
        transitive = false
}
}





10.【最新訊息】

經過與阿里的安卓程式設計師的聯絡,

他們一時半會也找不到根本原因,只說和arr的分包有關。

他們給了我一個
v7   support  包  為  25.3.1 的版本。

經過我的匯入,目前問題暫時得到了解決。


問題暫時得到了解決!!!

問題暫時得到了解決!!!

問題暫時得到了解決!!!

問題暫時得到了解決!!!


問題暫時得到了解決!!!


以下是除錯的大體經過,

基本按照【基礎版3.3.1】的流程來的,

不同之處我列在下面:

1.註釋了  v7包 為  25.4.0  的第三方庫Compile 。
保證都是小於等於  25.3.1 的情況。


2.根據


編譯器的報錯結果,分別逐條對比,新增force如下。  (根據每個人個人情況)





configurations.all {//【測試】【測試】【測試】【測試】【測試】【測試】
    resolutionStrategy {
        failOnVersionConflict()
        force 'org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2'


        force 'com.android.support:appcompat-v7:25.3.1'
        force 'com.android.support:recyclerview-v7:25.3.1'
        force 'com.android.support:support-compat:25.3.1'
        force 'com.squareup.okio:okio:1.12.0'
        force 'com.squareup.okhttp3:okhttp:3.2.0'
        force 'com.squareup.retrofit2:retrofit:2.3.0'
        force 'com.google.code.gson:gson:2.8.0'
        force 'com.android.support:support-annotations:25.3.1'
        force 'com.android.support:support-v4:25.3.1'


        force 'com.squareup:javapoet:1.8.0'
        force 'com.google.code.findbugs:jsr305:3.0.0'
    }
}




然後操作的原理,和技術備忘錄,
如下:


然後我的一些自己的嘗試總結如下:


1.將短視訊SDK的  v7  包  指定為唯一的最高版本標準。然後所有在此版本之下的第三方庫,都是有著自己的向下相容機制的,所以都可以得到合理解決。


2.然後解決相容問題。用 configurations.all    裡面的    resolutionStrategy   策略,
用    failOnVersionConflict    和    forece    這兩個方法,
來根據編譯器的實時報錯,進行版本的強制修改。



3.以上的情況,都是建立在    短視訊SDK    的  v7    包,高於所有第三方庫的    v7包的情況之下。



4.若存在某一  第三方庫的v7版本,
高於短視訊SDK    的標準v7版本。(當前為    25.3.1    )
則以上的向下相容機制,則失效。
而且,很有可能,產生預料之外的錯誤(版本衝突)。









11.並且,
我還預備給他們兩條建議,————更好的使用第三方庫:


建議一:

(1)
除了利用

resolutionStrategy
的
force之外,

還有一種
待選解法

具體解決方案為:由於很多第三方包都會用到v4支援包,這樣在你匯入多個支援的時候難免會出現這樣的錯誤,只需在build.gradle裡面新增上

configurations {

  all*.exclude group: 'com.android.support', module: 'support-v4'

}

參見大神文章:

【踩坑速記】二次依賴?android studio編譯執行各種踩坑解決方案,杜絕彎路,總有你想要的~

裡面的第二點,就是講這個的。



(2)

所有的activity  xml  命名, 
一、不應讓使用者避讓自己的  xml檔案命名。

二、應該自己想辦法,比如在  xml檔名、各種value屬性,的後面,加上自己獨一無二僅有的不可能衝突的字尾名。應該是自己主動避讓客戶。














整體上!學習到了非常多的東西!自學,是最厲害最無法阻攔的解法!

榮神益人!







進入常規專案階段:
12.

base-64  加密的  UploadAddress 欄位:



eyJFbmRwb2ludCI6Imh0dHBzOi8vb3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbSIsIkJ1Y2tldCI6ImluLTIwMTcwODAzMTg1MDE1OTE4LWlyMjVsajE2dGwiLCJGaWxlTmFtZSI6InZpZGVvLzEwQkREMzBFLTE1RTE4MEJFMTNELTExOTEtNzAwNS00MDUtMDE2MTgubXA0In0=

變為了:

eyJFbmRwb2ludCI6Imh0dHBzOi8vb3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbSIsIkJ1Y2tldCI6ImluLTIwMTcwODAzMTg1MDE1OTE4LWlyMjVsajE2dGwiLCJGaWxlTmFtZSI6InZpZGVvLzEwQkREMzBFLTE1RTE4MEJFMTNELTExOTEtNzAwNS00MDUtMDE2MTgubXA0In0\u003d


末位的等號,變了


解析出來的Json也由

{"Endpoint":"https://oss-cn-shanghai.aliyuncs.com","Bucket":"in-20170803185015918-ir25lj16tl","FileName":"video/10BDD30E-15E180BE13D-1191-7005-405-01618.mp4"}

變為了

{"Endpoint":"https://oss-cn-shanghai.aliyuncs.com","Bucket":"in-20170803185015918-ir25lj16tl","FileName":"video/10BDD30E-15E180BE13D-1191-7005-405-01618.mp4"}.Ӎ݀


相關解決文章為:

使用Gson將物件類轉成Json物件時出現\u003d的問題

http://blog.csdn.net/taven/article/details/42706451


這種情況,如果Student屬性中的某個值包含有=,會變為\u003d的情況

只需將Gson的初始化修改

  1. Gson gson = new GsonBuilder().disableHtmlEscaping().create();  


對於

retrofit = Retrofit.Builder().baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create(gson))

沒用。

那麼,手動轉化吧:


uploadAddress = uploadAddress?.replace("\\u003d","=")//【解決Gson的Bug。】

13.


全屏,SDK不提供現成方法。      手動調整。


豎向:

//自己的一些控制元件,進行顯示
rl_titlebar_012.visibility = View.VISIBLE
rl_namebar_012.visibility = View.VISIBLE
ll_menubar_public.visibility = View.VISIBLE
ll_describebar_012.visibility  = View.VISIBLE
btn_join_005.visibility = View.VISIBLE



橫向:


//自己的一些控制元件,進行隱藏
rl_titlebar_012.visibility = View.GONE
rl_namebar_012.visibility = View.GONE
ll_menubar_public.visibility = View.GONE
ll_describebar_012.visibility  = View.GONE
btn_join_005.visibility = View.GONE



然後


ViewGroup.LayoutParams.MATCH_PARENT.let { params.height = it; params.width = it }
不起作用

windowManager.defaultDisplay
.let { params.width = it.width*3; params.height = it.height*3 }
不起作用

var trueParams = rl_wrap_match_home_player.layoutParams
windowManager.defaultDisplay
.let { trueParams.width = 500;trueParams.height = 500 }

不起作用

甚至天才般的思考:

windowManager.defaultDisplay
.let { params.width = it.height;params.height = it.width }

都不起作用。



A
match_home_player.changeScreenMode(AliyunScreenMode.Full)//全屏模式




B
ViewGroup.LayoutParams.MATCH_PARENT.let { params.height = it; params.width = it }

的前後順序交換,都不起作用。




match_home_player.layoutParams = params
也不起作用。

params.width  = windowManager.defaultDisplay.width
params.height  = windowManager.defaultDisplay.height
match_home_player.layoutParams = params
手動一個個字,打進去,也不起作用。




14、
外層wrap巢狀可以改layoutParams,

內層的播放器不可以改layoutParams



始終擴不到全屏。




14問題已解決。。。。。【核心方案是:1.width必須寫  wrap_content  或者  match_parent  。  2.  height必須寫  dp  或  px   。   3.  其他的任意佔用面積的UI,都gone掉。4.在onConfigurationChanged裡面,  設定對應的尺寸變化方法。   5.  說不定有其他   6.說不定有其他】


15.

自己設計了一套,  用Surface  顯示,   player  管理流程的,   基本的播放。

以及自己設計的高階版UI。

16.

自己設計了一套,  List中    播放器Item 的全套生命管理系統。

17.




基礎版的短視訊錄製,這個  選擇相簿  的按鈕,應該用什麼方法去隱藏呢?





答曰:

snap_demo 裡style檔案裡面<item name="qusnap_gallery_icon_visibility">visible</item>  該屬性設定為gone就可以了

18.

多Item列表的播放器模式

和單列表item的播放器模式

的抽取與組合。

19.

全畫面點選。

而且簡單重排了一下生命週期中的方法。

20.

自動播放處理。

21.

播放器

音量設定

//TODO 測試
TLog.l("現在監測到的音量是——————${playerHashMap[index]?.player?.volume}")

每次變動7個。

音量從 0 -- 100 。  有14階變數。

可以手動  setVolume ( Int  )

和  手動   getVolume (  Int  ) 

22.

設定螢幕亮度

  * 設定螢幕亮度
    * 0 最暗
    * 1 最亮
    */
    public void setBrightness(float brightness) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = lp.screenBrightness + brightness / 255.0f;
        if (lp.screenBrightness > 1) {
            lp.screenBrightness = 1;
        } else if (lp.screenBrightness < 0.1) {
            lp.screenBrightness = (float) 0.1;
        }
        getWindow().setAttributes(lp);

        float sb = lp.screenBrightness;
        brightnessTextView.setText((int) Math.ceil(sb * 100) + "%");
    }

直接設定整機的螢幕亮度程式碼。


23.

設定了好久。

發現  馬雲視訊播放器的   setVolume   這個api  ,是沒用的

無論輸入什麼進去,  都是播放器的   音量為   0

playerHashMap[index]?.volumeBtn?.setOnClickListener {
/**
     * 如果播放器音量大於0。則記錄下播放器音量,並重新將音量設為0
     * 如果播放器音量已為0。則將播放器音量設定為上次儲存的音量。
     */
TLog.l("根據系統音量,此時當前系統媒體音量是 ${getSystemMediaVolume(true)}", "Volume")


    TLog.l("此時播放器的音量是  ${playerHashMap[index]?.player?.volume}", "Volume")
    TLog.l("現在儲存的上次音量值為   ${playerHashMap[index]?.original_volume},然後開始判斷", "Volume")
    playerHashMap[index]?.original_volume?.let {
when (it > 0) {
        /**
         * 若大於0
         */
true -> let {
TLog.l("走大於0的分支  :設定之前前前,播放器的音量為${playerHashMap[index]?.player?.volume}", "Volume")


                val savedVolume = playerHashMap[index]?.player?.volume
playerHashMap[index]?.original_volume = savedVolume

                playerHashMap[index]?.player?.volume = 0//設定為0
TLog.l("設定之後後後,播放器的音量為${playerHashMap[index]?.player?.volume}", "Volume")
            }
/**
         * 若小於等於0
         */
false -> let {
TLog.l("走小於等於0的分支  :設定之前前前播放器的音量為${playerHashMap[index]?.player?.volume}", "Volume")

                playerHashMap[index]?.player?.volume = playerHashMap[index]?.original_volume ?: 50//設為上一次的值。如為null則50
TLog.l("設定之後後後播放器的音量為${playerHashMap[index]?.player?.volume}", "Volume")

            }
}
    }
}

哪怕有乘了一百倍後,也照樣無效。

後來發現。。。。

上面那個判斷分支寫錯了:

TLog.l("現在儲存的上次音量值為   ${playerHashMap[index]?.original_volume},然後開始判斷", "Volume")
應該是:

playerHashMap[index]?.player?.volume?.let {



寫著寫著寫多了,就糊塗了。


24.

系統的  Call  通話音量

從  0  最小  到   7  最大  , 有    7  級



系統 的   Media(Music一樣的) 媒體音量

從  0  最小 到   15最大  , 有    15   級

馬雲視訊播放器,    

是從   0   - -----  --  100   ,總共有  100   級。

25.

經過很多微細的調整和Log調整之後。

馬雲視訊播放器的音量功能,調通了。

音量是可以調節的。
沒問題,只是SDK比較繞。

還要注意有一點。

public class PlayerProxy implements IAliyunVodPlayer

裡面是這樣寫的

public void setVolume(int volume) {
    if(this.mAvmPlayer != null) {
        this.mAvmPlayer.setVolume((float)volume * 1.0F / 100.0F);
}
}

public int getVolume() {
    if(this.mAvmPlayer == null) {
        return 0;
} else {
        float volume = this.mAvmPlayer.getVolume();
        return (int)(volume * 100.0F);
}
}





26.

firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()//完全可見。————?
firstVisibleItem = layoutManager.findFirstVisibleItemPosition()//只要有一點點部分可見。——————?


RecyclerView.LayoutManager

找到的方法——————

一、第一個為部分可見的條目

二、第一個全部可見的條目

最後一個以此類推

感覺。。。

這API很神奇

可以大作文章