Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
I
ImageVideoBanner
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
jiangjiantao
ImageVideoBanner
Commits
0ef30b50
Commit
0ef30b50
authored
Apr 28, 2021
by
委座-江
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
性能优化
parent
d75937a0
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1084 additions
and
1005 deletions
+1084
-1005
build.gradle
imageVideoBanner/build.gradle
+8
-4
AndroidManifest.xml
imageVideoBanner/src/main/AndroidManifest.xml
+9
-2
DetailActivity.java
...main/java/com/widget/imagevideobanner/DetailActivity.java
+29
-0
MainActivity.java
...c/main/java/com/widget/imagevideobanner/MainActivity.java
+48
-25
ImageVideoBanner.java
.../com/widget/imagevideobanner/banner/ImageVideoBanner.java
+0
-307
ImageVideoFragment.java
...om/widget/imagevideobanner/banner/ImageVideoFragment.java
+0
-446
MyVideoView.java
.../java/com/widget/imagevideobanner/banner/MyVideoView.java
+0
-50
MediaBean.java
...main/java/com/widget/imagevideobanner/bean/MediaBean.java
+87
-0
IPlayTarget.java
.../java/com/widget/imagevideobanner/player/IPlayTarget.java
+11
-0
PlayerManager.java
...ava/com/widget/imagevideobanner/player/PlayerManager.java
+112
-0
ImageVideoBanner.java
...va/com/widget/imagevideobanner/view/ImageVideoBanner.java
+126
-0
KeyEventCompat.java
...java/com/widget/imagevideobanner/view/KeyEventCompat.java
+4
-4
KeyEventCompatHoneycomb.java
...widget/imagevideobanner/view/KeyEventCompatHoneycomb.java
+1
-1
OnActionFinishListener.java
.../widget/imagevideobanner/view/OnActionFinishListener.java
+5
-0
ViewPager.java
...main/java/com/widget/imagevideobanner/view/ViewPager.java
+142
-139
VpImageView.java
...in/java/com/widget/imagevideobanner/view/VpImageView.java
+94
-0
VpVideoView.java
...in/java/com/widget/imagevideobanner/view/VpVideoView.java
+308
-0
activity_detail.xml
imageVideoBanner/src/main/res/layout/activity_detail.xml
+19
-0
activity_main.xml
imageVideoBanner/src/main/res/layout/activity_main.xml
+15
-4
banner_imge_video.xml
imageVideoBanner/src/main/res/layout/banner_imge_video.xml
+3
-3
item_video_view.xml
imageVideoBanner/src/main/res/layout/item_video_view.xml
+1
-1
layout_exo_player_view.xml
...ideoBanner/src/main/res/layout/layout_exo_player_view.xml
+15
-0
layout_player_view.xml
imageVideoBanner/src/main/res/layout/layout_player_view.xml
+35
-0
layout_simple_exo_player_view.xml
...ner/src/main/res/layout/layout_simple_exo_player_view.xml
+12
-0
styles.xml
imageVideoBanner/src/main/res/values/styles.xml
+0
-2
ExampleUnitTest.java
...c/test/java/com/zxj/imagevideobanner/ExampleUnitTest.java
+0
-17
No files found.
imageVideoBanner/build.gradle
View file @
0ef30b50
...
@@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
...
@@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
android
{
android
{
compileSdkVersion
28
compileSdkVersion
28
defaultConfig
{
defaultConfig
{
minSdkVersion
18
minSdkVersion
22
targetSdkVersion
22
targetSdkVersion
22
versionCode
1
versionCode
1
versionName
"1.0"
versionName
"1.0"
...
@@ -21,13 +21,17 @@ dependencies {
...
@@ -21,13 +21,17 @@ dependencies {
implementation
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
])
implementation
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
])
implementation
'com.android.support:appcompat-v7:28.0.0'
implementation
'com.android.support:appcompat-v7:28.0.0'
implementation
'com.android.support.constraint:constraint-layout:1.1.0'
implementation
'com.android.support.constraint:constraint-layout:1.1.0'
implementation
'com.github.bumptech.glide:glide:
3.7
.0'
implementation
'com.github.bumptech.glide:glide:
4.9
.0'
//当需要FFmpegMediaMetadataRetriever时必选
//当需要FFmpegMediaMetadataRetriever时必选
implementation
'com.github.wseemann:FFmpegMediaMetadataRetriever-armeabi-v7a:1.0.14'
implementation
'com.github.wseemann:FFmpegMediaMetadataRetriever-armeabi-v7a:1.0.14'
implementation
'com.wang.avi:library:2.1.3'
implementation
'com.wang.avi:library:2.1.3'
// implementation 'com.google.android.exoplayer:exoplayer:2.13.3'
// compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'
//视频播放组件
api
'com.google.android.exoplayer:exoplayer-core:2.7.2'
api
'com.google.android.exoplayer:exoplayer-dash:2.7.2'
api
'com.google.android.exoplayer:exoplayer-ui:2.7.2'
api
'jp.wasabeef:glide-transformations:4.0.0'
}
}
imageVideoBanner/src/main/AndroidManifest.xml
View file @
0ef30b50
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"com.widget.imagevideobanner"
>
package=
"com.widget.imagevideobanner"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<application
<application
android:allowBackup=
"true"
android:name=
".BaseApplication"
android:name=
".BaseApplication"
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:roundIcon=
"@mipmap/ic_launcher_round"
...
@@ -28,6 +29,12 @@
...
@@ -28,6 +29,12 @@
</activity>
</activity>
<activity
android:name=
".DetailActivity"
android:configChanges=
"orientation|keyboardHidden|screenSize|keyboard|navigation"
android:exported=
"true"
android:screenOrientation=
"portrait"
/>
</application>
</application>
</manifest>
</manifest>
\ No newline at end of file
imageVideoBanner/src/main/java/com/widget/imagevideobanner/DetailActivity.java
0 → 100644
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
;
import
android.os.Bundle
;
import
android.support.v7.app.AppCompatActivity
;
import
android.view.View
;
import
android.widget.TextView
;
import
com.widget.imagevideobanner.bean.MediaBean
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
DetailActivity
extends
AppCompatActivity
{
private
List
<
MediaBean
>
list
=
new
ArrayList
<>();
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_detail
);
TextView
tvBack
=
findViewById
(
R
.
id
.
tvBack
);
tvBack
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
finish
();
}
});
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/MainActivity.java
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
;
package
com
.
widget
.
imagevideobanner
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.Environment
;
import
android.os.Environment
;
import
android.support.v7.app.AppCompatActivity
;
import
android.support.v7.app.AppCompatActivity
;
import
android.view.View
;
import
android.widget.TextView
;
import
com.widget.imagevideobanner.banner.ImageVideoBanner
;
import
com.widget.imagevideobanner.bean.MediaBean
;
import
com.widget.imagevideobanner.bean.BannerBean
;
import
com.widget.imagevideobanner.view.ImageVideoBanner
;
import
com.widget.imagevideobanner.utils.IMMLeaks
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
static
com
.
widget
.
imagevideobanner
.
bean
.
MediaBean
.
TYPE_IMAGE
;
import
static
com
.
widget
.
imagevideobanner
.
bean
.
MediaBean
.
TYPE_VIDEO
;
public
class
MainActivity
extends
AppCompatActivity
{
public
class
MainActivity
extends
AppCompatActivity
{
private
List
<
BannerBean
>
list
=
new
ArrayList
<>();
private
List
<
MediaBean
>
list
=
new
ArrayList
<>();
ImageVideoBanner
banner
;
@Override
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
setContentView
(
R
.
layout
.
activity_main
);
ImageVideoBanner
banner
=
findViewById
(
R
.
id
.
banner
);
banner
=
findViewById
(
R
.
id
.
banner
);
setDatas
();
banner
.
addData
(
list
);
banner
.
startBanner
();
//修复inputManager引发的内存泄漏
MediaBean
mediaBean
=
new
MediaBean
();
IMMLeaks
.
fixFocusedViewLeak
(
BaseApplication
.
getApplication
());
mediaBean
.
setUrl
(
"https://hh-oss-html.miyapay.com/hhops/picture/16045733014903c31992a674f.png"
);
}
mediaBean
.
setResType
(
TYPE_IMAGE
);
list
.
add
(
mediaBean
);
MediaBean
mediaBean2
=
new
MediaBean
();
mediaBean2
.
setUrl
(
"https://hh-oss-html.miyapay.com/hhops/picture/1611112341654cffdd7b004bb.png"
);
mediaBean2
.
setResType
(
TYPE_IMAGE
);
list
.
add
(
mediaBean2
);
String
basePath
=
"http://miya-hz.oss-cn-shanghai.aliyuncs.com/huihua-test/face-pay/archive/"
;
MediaBean
mediaBean3
=
new
MediaBean
();
mediaBean3
.
setUrl
(
basePath
+
"shu.mp4"
);
mediaBean3
.
setCover
(
basePath
+
"shu.jpeg"
);
mediaBean3
.
setWidth
(
1080
);
mediaBean3
.
setHeight
(
1440
);
mediaBean3
.
setResType
(
TYPE_VIDEO
);
list
.
add
(
mediaBean3
);
MediaBean
mediaBean4
=
new
MediaBean
();
mediaBean4
.
setUrl
(
basePath
+
"heng.mp4"
);
mediaBean4
.
setCover
(
basePath
+
"heng.jpeg"
);
mediaBean4
.
setWidth
(
1440
);
mediaBean4
.
setHeight
(
1080
);
mediaBean4
.
setResType
(
TYPE_VIDEO
);
list
.
add
(
mediaBean4
);
banner
.
bindData
(
list
);
private
void
setDatas
()
{
TextView
tvGoDetail
=
findViewById
(
R
.
id
.
tvGoDetail
);
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
tvGoDetail
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
BannerBean
listBean
=
new
BannerBean
();
@Override
if
(
i
==
0
)
{
public
void
onClick
(
View
v
)
{
String
uri
=
"android.resource://"
+
getPackageName
()
+
"/"
+
R
.
raw
.
default_guide
;
startActivity
(
new
Intent
(
MainActivity
.
this
,
DetailActivity
.
class
));
listBean
.
setUrl
(
uri
);
listBean
.
setType
(
1
);
list
.
add
(
listBean
);
}
else
{
String
url
=
Environment
.
getExternalStorageDirectory
()
+
"/vertical_test.mp4"
;
listBean
.
setUrl
(
url
);
listBean
.
setType
(
1
);
list
.
add
(
listBean
);
}
}
}
}
);
}
}
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/banner/ImageVideoBanner.java
deleted
100644 → 0
View file @
d75937a0
package
com
.
widget
.
imagevideobanner
.
banner
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.media.MediaPlayer
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.Message
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.app.FragmentActivity
;
import
android.support.v4.app.FragmentManager
;
import
android.support.v4.app.FragmentStatePagerAdapter
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
android.view.LayoutInflater
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.widget.FrameLayout
;
import
com.bumptech.glide.util.Util
;
import
com.widget.imagevideobanner.R
;
import
com.widget.imagevideobanner.bean.BannerBean
;
import
com.widget.imagevideobanner.cache.BitmapCache
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
java.util.concurrent.ScheduledExecutorService
;
public
class
ImageVideoBanner
extends
FrameLayout
implements
ViewPager
.
OnPageChangeListener
,
com
.
widget
.
imagevideobanner
.
banner
.
ImageVideoFragment
.
OnVideoCompletionListener
{
private
static
final
int
UPTATE_VIEWPAGER
=
0
;
private
ViewPager
mViewPager
;
private
List
<
BannerBean
>
mList
=
new
ArrayList
<>();
private
ViewsPagerAdapter
mAdapter
;
private
int
autoCurrIndex
=
0
;
//设置当前 第几个图片 被选中
private
Timer
timer
;
private
TimerTask
timerTask
;
private
long
period
;
//轮播图展示时长,默认5秒
public
static
ScheduledExecutorService
sExecutor
;
public
Context
mContext
;
public
ImageVideoBanner
(
@NonNull
Context
context
)
{
super
(
context
);
mContext
=
context
;
initView
(
context
);
}
public
ImageVideoBanner
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
mContext
=
context
;
TypedArray
typedArray
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
banner
);
period
=
typedArray
.
getInt
(
R
.
styleable
.
banner_period
,
5000
);
typedArray
.
recycle
();
initView
(
context
);
}
private
void
initView
(
Context
context
)
{
View
view
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
banner_imge_video
,
this
,
true
);
mViewPager
=
view
.
findViewById
(
R
.
id
.
view_pager
);
mAdapter
=
new
ViewsPagerAdapter
(((
FragmentActivity
)
context
).
getSupportFragmentManager
());
mViewPager
.
setAdapter
(
mAdapter
);
mViewPager
.
setOnPageChangeListener
(
this
);
//ViewPager手势滑动禁用
mViewPager
.
setOnTouchListener
(
new
OnTouchListener
()
{
@Override
public
boolean
onTouch
(
View
v
,
MotionEvent
event
)
{
return
true
;
}
});
}
public
void
replaceData
(
List
<
com
.
widget
.
imagevideobanner
.
bean
.
BannerBean
>
listBean
)
{
mAdapter
.
replaceData
(
listBean
);
}
public
void
addData
(
List
<
com
.
widget
.
imagevideobanner
.
bean
.
BannerBean
>
listBean
)
{
mAdapter
.
addData
(
listBean
);
}
/**
* 初始化视频的Bitmap
*/
private
void
initBannerBitmap
()
{
if
(
mList
.
size
()
==
0
)
{
return
;
}
for
(
BannerBean
bannerBean
:
mList
)
{
if
(
bannerBean
.
getType
()
==
1
)
{
BitmapCache
.
getInstance
(
mContext
).
addCache
(
bannerBean
.
getUrl
());
}
}
}
@Override
public
void
onPageScrolled
(
int
position
,
float
positionOffset
,
int
positionOffsetPixels
)
{
}
@Override
public
void
onPageSelected
(
int
position
)
{
autoCurrIndex
=
position
;
if
(
mList
.
get
(
position
).
getType
()
==
1
)
{
//如果是视频
stopBanner
();
}
}
@Override
public
void
onPageScrollStateChanged
(
int
state
)
{
}
//定时轮播图片,需要在主线程里面修改 UI
private
Handler
mHandler
=
new
Handler
()
{
public
void
handleMessage
(
Message
msg
)
{
switch
(
msg
.
what
)
{
case
UPTATE_VIEWPAGER:
if
(
msg
.
arg1
!=
0
)
{
mViewPager
.
setCurrentItem
(
msg
.
arg1
);
}
else
{
mViewPager
.
setCurrentItem
(
msg
.
arg1
,
false
);
}
break
;
}
}
};
public
void
stopBanner
()
{
if
(
timer
!=
null
)
{
timer
.
cancel
();
timer
=
null
;
if
(
timerTask
!=
null
)
{
timerTask
.
cancel
();
timerTask
=
null
;
}
}
}
/**
* 设置轮播图 图片展示间隔
*/
public
void
setPeriod
(
int
period
)
{
this
.
period
=
period
;
}
public
void
startBanner
()
{
if
(
mList
.
get
(
0
).
getType
()
==
0
)
{
startBanner
(
period
);
}
}
public
void
startBanner
(
long
delay
)
{
stopBanner
();
timer
=
new
Timer
();
createTimerTask
();
timer
.
schedule
(
timerTask
,
delay
,
period
);
}
public
void
createTimerTask
()
{
timerTask
=
new
TimerTask
()
{
@Override
public
void
run
()
{
Message
message
=
new
Message
();
message
.
what
=
UPTATE_VIEWPAGER
;
if
(
autoCurrIndex
==
mList
.
size
()
-
1
)
{
autoCurrIndex
=
-
1
;
}
message
.
arg1
=
autoCurrIndex
+
1
;
mHandler
.
sendMessage
(
message
);
}
};
}
@Override
public
void
onVideoCompletion
(
MediaPlayer
mp
)
{
if
(
mList
.
size
()
==
1
)
{
mAdapter
.
getFragment
().
circulationPlayer
();
}
startBanner
(
0
);
}
@Override
public
void
onError
(
MediaPlayer
mp
)
{
startBanner
(
0
);
}
@Override
public
void
updateSize
(
BannerBean
bannerBean
)
{
if
(
mList
.
size
()
>
0
){
for
(
BannerBean
bean
:
mList
){
if
(
bannerBean
.
getUrl
().
equals
(
bean
.
getUrl
())){
bean
.
setHeight
(
bannerBean
.
getHeight
());
bean
.
setWidth
(
bannerBean
.
getWidth
());
}
}
}
}
private
final
class
ViewsPagerAdapter
extends
FragmentStatePagerAdapter
{
private
com
.
widget
.
imagevideobanner
.
banner
.
ImageVideoFragment
fragment
;
private
FragmentManager
fm
;
public
ViewsPagerAdapter
(
FragmentManager
fm
)
{
super
(
fm
);
this
.
fm
=
fm
;
}
@Override
public
Fragment
getItem
(
int
position
)
{
fragment
=
new
com
.
widget
.
imagevideobanner
.
banner
.
ImageVideoFragment
();
fragment
.
setOnVideoCompletionListener
(
ImageVideoBanner
.
this
);
com
.
widget
.
imagevideobanner
.
bean
.
BannerBean
bannerBean
=
mList
.
get
(
position
);
Bundle
bundle
=
new
Bundle
();
bundle
.
putSerializable
(
"bannerBean"
,
bannerBean
);
bundle
.
putBoolean
(
"loop"
,
getLoop
());
fragment
.
setArguments
(
bundle
);
return
fragment
;
}
/**
* 只有1个视频的时候循环播放
* @return
*/
private
boolean
getLoop
()
{
if
(
mList
.
size
()
==
1
&&
mList
.
get
(
0
).
getType
()
==
1
)
{
return
true
;
}
return
false
;
}
@Override
public
int
getCount
()
{
return
mList
.
size
();
}
@Override
public
int
getItemPosition
(
Object
object
)
{
if
(
mList
.
size
()
>
0
)
{
return
POSITION_NONE
;
}
return
super
.
getItemPosition
(
object
);
}
public
void
replaceData
(
List
<
BannerBean
>
listBean
)
{
// 新数据和原来数据对比,不一致才去刷新
boolean
change
=
compareData
(
listBean
);
if
(!
change
)
{
notifyDataSetChanged
();
return
;
}
if
(
listBean
.
size
()
>
0
)
{
mList
.
clear
();
addData
(
listBean
);
if
(
listBean
.
get
(
0
).
getType
()
==
0
)
{
startBanner
();
}
autoCurrIndex
=
0
;
}
}
/**
* 对比数据
* @param listBean
* @return
*/
private
boolean
compareData
(
List
<
BannerBean
>
listBean
)
{
if
(
listBean
==
null
||
listBean
.
size
()
==
0
)
{
return
false
;
}
if
(
listBean
.
size
()
==
mList
.
size
())
{
for
(
int
i
=
0
;
i
<
mList
.
size
();
i
++)
{
if
(
mList
.
get
(
i
).
getType
()
!=
listBean
.
get
(
i
).
getType
()
||
!
mList
.
get
(
i
).
getUrl
().
equals
(
listBean
.
get
(
i
).
getUrl
()))
{
return
true
;
}
}
return
false
;
}
return
true
;
}
public
void
addData
(
List
<
BannerBean
>
listBean
)
{
if
(
null
!=
listBean
)
{
mList
.
clear
();
mList
.
addAll
(
listBean
);
}
initBannerBitmap
();
notifyDataSetChanged
();
}
public
ImageVideoFragment
getFragment
()
{
return
fragment
;
}
}
public
List
<
BannerBean
>
getBannerInfos
(){
return
mList
;
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/banner/ImageVideoFragment.java
deleted
100644 → 0
View file @
d75937a0
This diff is collapsed.
Click to expand it.
imageVideoBanner/src/main/java/com/widget/imagevideobanner/banner/MyVideoView.java
deleted
100644 → 0
View file @
d75937a0
package
com
.
widget
.
imagevideobanner
.
banner
;
import
android.content.Context
;
import
android.util.AttributeSet
;
import
android.widget.VideoView
;
public
class
MyVideoView
extends
VideoView
{
private
int
mVideoWidth
;
private
int
mVideoHeight
;
public
MyVideoView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
MyVideoView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
public
MyVideoView
(
Context
context
)
{
super
(
context
);
}
public
void
setVideoSize
(
int
width
,
int
height
)
{
mVideoWidth
=
width
;
mVideoHeight
=
height
;
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
// Log.i("@@@", "onMeasure");
int
width
=
getDefaultSize
(
mVideoWidth
,
widthMeasureSpec
);
int
height
=
getDefaultSize
(
mVideoHeight
,
heightMeasureSpec
);
if
(
mVideoWidth
>
0
&&
mVideoHeight
>
0
)
{
if
(
mVideoWidth
*
height
>
width
*
mVideoHeight
)
{
// Log.i("@@@", "image too tall, correcting");
height
=
width
*
mVideoHeight
/
mVideoWidth
;
}
else
if
(
mVideoWidth
*
height
<
width
*
mVideoHeight
)
{
// Log.i("@@@", "image too wide, correcting");
width
=
height
*
mVideoWidth
/
mVideoHeight
;
}
else
{
// Log.i("@@@", "aspect ratio is correct: " +
// width+"/"+height+"="+
// mVideoWidth+"/"+mVideoHeight);
}
}
// Log.i("@@@", "setting size: " + width + 'x' + height);
setMeasuredDimension
(
width
,
height
);
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/bean/
Banner
Bean.java
→
imageVideoBanner/src/main/java/com/widget/imagevideobanner/bean/
Media
Bean.java
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
bean
;
package
com
.
widget
.
imagevideobanner
.
bean
;
import
android.support.annotation.Nullable
;
import
android.text.TextUtils
;
import
java.io.Serializable
;
import
java.io.Serializable
;
public
class
BannerBean
implements
Serializable
{
/**
* 资源类型
*/
public
class
MediaBean
implements
Serializable
{
public
static
final
int
TYPE_IMAGE
=
0
;
//图片
public
static
final
int
TYPE_VIDEO
=
1
;
//视频
private
String
url
;
private
String
url
;
private
int
type
;
//资源类型
private
int
resType
;
//视频的封面
private
String
cover
;
private
int
width
;
private
int
width
;
private
int
height
;
private
int
height
;
//视频首帧图片key
private
String
key
;
//视频首帧图片 高斯模糊key
private
String
blurKey
;
public
String
getKey
()
{
public
String
getUrl
()
{
return
key
;
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
int
getResType
()
{
return
resType
;
}
}
public
void
set
Key
(
String
key
)
{
public
void
set
ResType
(
int
resType
)
{
this
.
key
=
key
;
this
.
resType
=
resType
;
}
}
public
String
get
BlurKey
()
{
public
String
get
Cover
()
{
return
blurKey
;
return
cover
;
}
}
public
void
set
BlurKey
(
String
blurKey
)
{
public
void
set
Cover
(
String
cover
)
{
this
.
blurKey
=
blurKey
;
this
.
cover
=
cover
;
}
}
public
int
getWidth
()
{
public
int
getWidth
()
{
...
@@ -44,28 +62,26 @@ public class BannerBean implements Serializable {
...
@@ -44,28 +62,26 @@ public class BannerBean implements Serializable {
this
.
height
=
height
;
this
.
height
=
height
;
}
}
public
String
getUrl
()
{
@Override
return
url
;
public
boolean
equals
(
@Nullable
Object
obj
)
{
}
if
(!(
obj
instanceof
MediaBean
))
return
false
;
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
MediaBean
mediaBean
=
(
MediaBean
)
obj
;
}
return
resType
==
mediaBean
.
resType
&&
width
==
mediaBean
.
width
public
int
getType
()
{
&&
height
==
mediaBean
.
height
return
type
;
&&
TextUtils
.
equals
(
url
,
mediaBean
.
url
)
&&
TextUtils
.
equals
(
cover
,
mediaBean
.
cover
);
}
}
public
void
setType
(
int
type
)
{
public
boolean
isNull
()
{
this
.
type
=
type
;
if
(
resType
==
TYPE_IMAGE
)
{
return
TextUtils
.
isEmpty
(
url
)
;
}
return
(
width
==
0
)
||
(
height
==
0
)
||
TextUtils
.
isEmpty
(
cover
)
||
TextUtils
.
isEmpty
(
url
)
;
}
}
@Override
public
String
toString
()
{
return
"BannerBean{"
+
"url='"
+
url
+
'\''
+
", type="
+
type
+
'}'
;
}
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/player/IPlayTarget.java
0 → 100755
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
player
;
public
interface
IPlayTarget
{
//活跃状态 视频可播放
void
onActive
();
//非活跃状态,暂停它
void
inActive
();
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/player/PlayerManager.java
0 → 100755
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
player
;
import
android.app.Application
;
import
android.net.Uri
;
import
android.view.LayoutInflater
;
import
com.google.android.exoplayer2.DefaultLoadControl
;
import
com.google.android.exoplayer2.ExoPlayerFactory
;
import
com.google.android.exoplayer2.SimpleExoPlayer
;
import
com.google.android.exoplayer2.source.ExtractorMediaSource
;
import
com.google.android.exoplayer2.source.MediaSource
;
import
com.google.android.exoplayer2.trackselection.DefaultTrackSelector
;
import
com.google.android.exoplayer2.ui.PlayerView
;
import
com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
;
import
com.google.android.exoplayer2.upstream.FileDataSourceFactory
;
import
com.google.android.exoplayer2.upstream.cache.Cache
;
import
com.google.android.exoplayer2.upstream.cache.CacheDataSinkFactory
;
import
com.google.android.exoplayer2.upstream.cache.CacheDataSource
;
import
com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
;
import
com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
;
import
com.google.android.exoplayer2.upstream.cache.SimpleCache
;
import
com.google.android.exoplayer2.util.Util
;
import
com.widget.imagevideobanner.BaseApplication
;
import
com.widget.imagevideobanner.R
;
public
class
PlayerManager
{
private
final
ExtractorMediaSource
.
Factory
mediaSourceFactory
;
public
SimpleExoPlayer
exoPlayer
;
public
PlayerView
playerView
;
public
String
playUrl
;
private
static
PlayerManager
mInstance
;
public
PlayerManager
()
{
Application
application
=
BaseApplication
.
getApplication
();
//创建http视频资源如何加载的工厂对象
DefaultHttpDataSourceFactory
dataSourceFactory
=
new
DefaultHttpDataSourceFactory
(
Util
.
getUserAgent
(
application
,
application
.
getPackageName
()));
//创建缓存,指定缓存位置,和缓存策略,为最近最少使用原则,最大为200m
Cache
cache
=
new
SimpleCache
(
application
.
getCacheDir
(),
new
LeastRecentlyUsedCacheEvictor
(
1024
*
1024
*
200
));
//把缓存对象cache和负责缓存数据读取、写入的工厂类CacheDataSinkFactory 相关联
CacheDataSinkFactory
cacheDataSinkFactory
=
new
CacheDataSinkFactory
(
cache
,
Long
.
MAX_VALUE
);
/**创建能够 边播放边缓存的 本地资源加载和http网络数据写入的工厂类
* public CacheDataSourceFactory(
* Cache cache, 缓存写入策略和缓存写入位置的对象
* DataSource.Factory upstreamFactory,http视频资源如何加载的工厂对象
* DataSource.Factory cacheReadDataSourceFactory,本地缓存数据如何读取的工厂对象
* @Nullable DataSink.Factory cacheWriteDataSinkFactory,http网络数据如何写入本地缓存的工厂对象
* @CacheDataSource.Flags int flags,加载本地缓存数据进行播放时的策略,如果遇到该文件正在被写入数据,或读取缓存数据发生错误时的策略
* @Nullable CacheDataSource.EventListener eventListener 缓存数据读取的回调
*/
CacheDataSourceFactory
cacheDataSourceFactory
=
new
CacheDataSourceFactory
(
cache
,
dataSourceFactory
,
new
FileDataSourceFactory
(),
cacheDataSinkFactory
,
CacheDataSource
.
FLAG_BLOCK_ON_CACHE
,
null
);
//最后 还需要创建一个 MediaSource 媒体资源 加载的工厂类
//因为由它创建的MediaSource 能够实现边缓冲边播放的效果,
mediaSourceFactory
=
new
ExtractorMediaSource
.
Factory
(
cacheDataSourceFactory
);
//创建exoplayer播放器实例
exoPlayer
=
ExoPlayerFactory
.
newSimpleInstance
(
application
,
//视频的音视频轨道如何加载,使用默认的轨道选择器
new
DefaultTrackSelector
(),
//视频缓存控制逻辑,使用默认的即可
new
DefaultLoadControl
());
//加载咱们布局层级优化之后的能够展示视频画面的View
playerView
=
(
PlayerView
)
LayoutInflater
.
from
(
application
).
inflate
(
R
.
layout
.
layout_exo_player_view
,
null
,
false
);
//别忘记 把播放器实例 和 playerView,controlView相关联
//如此视频画面才能正常显示,播放进度条才能自动更新
playerView
.
setPlayer
(
exoPlayer
);
}
public
static
PlayerManager
getInstance
(){
if
(
mInstance
==
null
)
{
synchronized
(
PlayerManager
.
class
)
{
if
(
mInstance
==
null
)
{
mInstance
=
new
PlayerManager
();
}
}
}
return
mInstance
;
}
public
void
release
()
{
if
(
exoPlayer
!=
null
)
{
exoPlayer
.
setPlayWhenReady
(
false
);
exoPlayer
.
stop
(
true
);
exoPlayer
.
release
();
exoPlayer
=
null
;
}
if
(
playerView
!=
null
)
{
playerView
.
setPlayer
(
null
);
playerView
=
null
;
}
}
/**
* 切换与播放器exoplayer 绑定的exoplayerView。用于页面切换视频无缝续播的场景
* @param newPlayerView
* @param attach
*/
public
void
switchPlayerView
(
PlayerView
newPlayerView
,
boolean
attach
)
{
playerView
.
setPlayer
(
attach
?
null
:
exoPlayer
);
newPlayerView
.
setPlayer
(
attach
?
exoPlayer
:
null
);
}
public
MediaSource
createMediaSource
(
String
url
)
{
return
mediaSourceFactory
.
createMediaSource
(
Uri
.
parse
(
url
));
}
}
\ No newline at end of file
imageVideoBanner/src/main/java/com/widget/imagevideobanner/view/ImageVideoBanner.java
0 → 100644
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
view
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v4.view.PagerAdapter
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.FrameLayout
;
import
com.widget.imagevideobanner.R
;
import
com.widget.imagevideobanner.bean.MediaBean
;
import
java.util.ArrayList
;
import
java.util.List
;
import
static
com
.
widget
.
imagevideobanner
.
bean
.
MediaBean
.
TYPE_IMAGE
;
import
static
com
.
widget
.
imagevideobanner
.
bean
.
MediaBean
.
TYPE_VIDEO
;
/**
* 图片+视频
* 混播控件
*/
public
class
ImageVideoBanner
extends
FrameLayout
implements
ViewPager
.
OnPageChangeListener
,
OnActionFinishListener
{
private
static
String
TAG
=
"ImageVideoBanner"
;
private
ViewPager
mViewPager
;
private
List
<
View
>
mList
=
new
ArrayList
<>();
private
ViewsPagerAdapter
mAdapter
;
private
int
curIndex
;
private
ImageVideoBanner
(
@NonNull
Context
context
)
{
super
(
context
);
initView
();
}
public
ImageVideoBanner
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initView
();
}
private
void
initView
(){
View
view
=
LayoutInflater
.
from
(
getContext
()).
inflate
(
R
.
layout
.
banner_imge_video
,
this
,
true
);
mViewPager
=
view
.
findViewById
(
R
.
id
.
view_pager
);
mAdapter
=
new
ViewsPagerAdapter
(
mList
);
mViewPager
.
setAdapter
(
mAdapter
);
mViewPager
.
setOnPageChangeListener
(
this
);
}
public
void
bindData
(
List
<
MediaBean
>
beans
){
if
(
beans
==
null
){
return
;
}
mList
.
clear
();
for
(
MediaBean
mediaBean
:
beans
){
if
(!
mediaBean
.
isNull
()){
if
(
mediaBean
.
getResType
()
==
TYPE_IMAGE
){
mList
.
add
(
new
VpImageView
(
getContext
(),
mediaBean
,
this
));
}
if
(
mediaBean
.
getResType
()
==
TYPE_VIDEO
){
mList
.
add
(
new
VpVideoView
(
getContext
(),
mediaBean
,
this
));
}
}
}
if
(
mList
.
size
()
>
0
){
mAdapter
.
notifyDataSetChanged
();
}
}
@Override
public
void
onPageScrolled
(
int
position
,
float
positionOffset
,
int
positionOffsetPixels
)
{}
@Override
public
void
onPageSelected
(
int
position
)
{
curIndex
=
position
;
}
@Override
public
void
next
()
{
Log
.
e
(
TAG
,
curIndex
+
""
);
if
(
curIndex
==
mList
.
size
()
-
1
)
{
curIndex
=
0
;
}
else
{
curIndex
=
curIndex
+
1
;
}
mViewPager
.
setCurrentItem
(
curIndex
);
}
@Override
public
void
onPageScrollStateChanged
(
int
state
)
{
}
private
static
final
class
ViewsPagerAdapter
extends
PagerAdapter
{
private
List
<
View
>
mList
;
public
ViewsPagerAdapter
(
List
<
View
>
list
)
{
this
.
mList
=
list
;
}
@Override
public
int
getCount
()
{
return
mList
.
size
();
}
@Override
public
boolean
isViewFromObject
(
@NonNull
View
view
,
@NonNull
Object
object
)
{
return
view
==
object
;
}
@NonNull
@Override
public
View
instantiateItem
(
ViewGroup
container
,
int
position
)
{
container
.
addView
(
mList
.
get
(
position
));
return
mList
.
get
(
position
);
}
@Override
public
void
destroyItem
(
ViewGroup
container
,
int
position
,
@NonNull
Object
object
)
{
container
.
removeView
(
mList
.
get
(
position
));
}
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
banner
/KeyEventCompat.java
→
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
view
/KeyEventCompat.java
View file @
0ef30b50
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
* limitations under the License.
* limitations under the License.
*/
*/
package
com
.
widget
.
imagevideobanner
.
banner
;
package
com
.
widget
.
imagevideobanner
.
view
;
import
android.view.KeyEvent
;
import
android.view.KeyEvent
;
...
@@ -95,17 +95,17 @@ public class KeyEventCompat {
...
@@ -95,17 +95,17 @@ public class KeyEventCompat {
static
class
HoneycombKeyEventVersionImpl
implements
KeyEventVersionImpl
{
static
class
HoneycombKeyEventVersionImpl
implements
KeyEventVersionImpl
{
@Override
@Override
public
int
normalizeMetaState
(
int
metaState
)
{
public
int
normalizeMetaState
(
int
metaState
)
{
return
com
.
widget
.
imagevideobanner
.
banner
.
KeyEventCompatHoneycomb
.
normalizeMetaState
(
metaState
);
return
com
.
widget
.
imagevideobanner
.
view
.
KeyEventCompatHoneycomb
.
normalizeMetaState
(
metaState
);
}
}
@Override
@Override
public
boolean
metaStateHasModifiers
(
int
metaState
,
int
modifiers
)
{
public
boolean
metaStateHasModifiers
(
int
metaState
,
int
modifiers
)
{
return
com
.
widget
.
imagevideobanner
.
banner
.
KeyEventCompatHoneycomb
.
metaStateHasModifiers
(
metaState
,
modifiers
);
return
com
.
widget
.
imagevideobanner
.
view
.
KeyEventCompatHoneycomb
.
metaStateHasModifiers
(
metaState
,
modifiers
);
}
}
@Override
@Override
public
boolean
metaStateHasNoModifiers
(
int
metaState
)
{
public
boolean
metaStateHasNoModifiers
(
int
metaState
)
{
return
com
.
widget
.
imagevideobanner
.
banner
.
KeyEventCompatHoneycomb
.
metaStateHasNoModifiers
(
metaState
);
return
com
.
widget
.
imagevideobanner
.
view
.
KeyEventCompatHoneycomb
.
metaStateHasNoModifiers
(
metaState
);
}
}
}
}
...
...
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
banner
/KeyEventCompatHoneycomb.java
→
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
view
/KeyEventCompatHoneycomb.java
View file @
0ef30b50
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
* limitations under the License.
* limitations under the License.
*/
*/
package
com
.
widget
.
imagevideobanner
.
banner
;
package
com
.
widget
.
imagevideobanner
.
view
;
import
android.view.KeyEvent
;
import
android.view.KeyEvent
;
...
...
imageVideoBanner/src/main/java/com/widget/imagevideobanner/view/OnActionFinishListener.java
0 → 100644
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
view
;
public
interface
OnActionFinishListener
{
void
next
();
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
banner
/ViewPager.java
→
imageVideoBanner/src/main/java/com/widget/imagevideobanner/
view
/ViewPager.java
View file @
0ef30b50
This diff is collapsed.
Click to expand it.
imageVideoBanner/src/main/java/com/widget/imagevideobanner/view/VpImageView.java
0 → 100644
View file @
0ef30b50
package
com
.
widget
.
imagevideobanner
.
view
;
import
android.content.Context
;
import
android.graphics.drawable.Drawable
;
import
android.os.Handler
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v7.widget.AppCompatImageView
;
import
android.util.Log
;
import
android.view.View
;
import
com.bumptech.glide.Glide
;
import
com.bumptech.glide.load.DataSource
;
import
com.bumptech.glide.load.engine.GlideException
;
import
com.bumptech.glide.request.RequestListener
;
import
com.bumptech.glide.request.target.Target
;
import
com.widget.imagevideobanner.R
;
import
com.widget.imagevideobanner.bean.MediaBean
;
import
com.widget.imagevideobanner.player.IPlayTarget
;
import
com.widget.imagevideobanner.utils.ThrowableUtils
;
/**
* 5秒自动切换图片
*/
public
class
VpImageView
extends
AppCompatImageView
implements
IPlayTarget
{
private
static
final
String
TAG
=
"VpImageView"
;
private
static
final
int
DEFAULT_SWITCH_PAGE_TIME
=
5000
;
private
MediaBean
mediaBean
;
private
OnActionFinishListener
onPageChangedListener
;
private
Handler
handler
=
new
Handler
();
private
Runnable
pageChangeRunable
=
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
null
!=
onPageChangedListener
)
onPageChangedListener
.
next
();
}
};
public
VpImageView
(
Context
context
)
{
super
(
context
);
}
public
VpImageView
(
Context
context
,
final
MediaBean
mediaBean
,
final
OnActionFinishListener
onPageChangedListener
)
{
super
(
context
);
this
.
mediaBean
=
mediaBean
;
this
.
onPageChangedListener
=
onPageChangedListener
;
}
private
void
setImageUrl
(
String
url
)
{
//todo 待确定是否一定会使用缓存 缺失加载前&加载失败的备用图
Log
.
e
(
TAG
,
url
);
Glide
.
with
(
getContext
()).
load
(
url
)
.
error
(
R
.
drawable
.
load_fail
)
.
placeholder
(
R
.
drawable
.
load_fail
)
.
listener
(
new
RequestListener
<
Drawable
>()
{
@Override
public
boolean
onLoadFailed
(
@Nullable
GlideException
e
,
Object
model
,
Target
<
Drawable
>
target
,
boolean
isFirstResource
)
{
Log
.
e
(
TAG
,
ThrowableUtils
.
getFullStackTrace
(
e
));
return
false
;
}
@Override
public
boolean
onResourceReady
(
Drawable
resource
,
Object
model
,
Target
<
Drawable
>
target
,
DataSource
dataSource
,
boolean
isFirstResource
)
{
Log
.
e
(
TAG
,
"onResourceReady"
);
return
false
;
}
}).
into
(
this
);
}
@Override
protected
void
onVisibilityChanged
(
@NonNull
View
changedView
,
int
visibility
)
{
super
.
onVisibilityChanged
(
changedView
,
visibility
);
Log
.
e
(
TAG
,
"onVisibilityChanged"
);
if
(
visibility
==
VISIBLE
)
onActive
();
if
(
visibility
==
GONE
||
visibility
==
INVISIBLE
)
inActive
();
}
@Override
public
void
onActive
()
{
handler
.
removeCallbacks
(
pageChangeRunable
);
setImageUrl
(
mediaBean
.
getUrl
());
handler
.
postDelayed
(
pageChangeRunable
,
DEFAULT_SWITCH_PAGE_TIME
);
}
@Override
public
void
inActive
()
{
handler
.
removeCallbacks
(
pageChangeRunable
);
}
}
imageVideoBanner/src/main/java/com/widget/imagevideobanner/view/VpVideoView.java
0 → 100644
View file @
0ef30b50
This diff is collapsed.
Click to expand it.
imageVideoBanner/src/main/res/layout/activity_detail.xml
0 → 100644
View file @
0ef30b50
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_height=
"match_parent"
>
<TextView
android:id=
"@+id/tvBack"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textSize=
"50sp"
android:text=
"返回"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
imageVideoBanner/src/main/res/layout/activity_main.xml
View file @
0ef30b50
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
>
<com.widget.imagevideobanner.
banner
.ImageVideoBanner
<com.widget.imagevideobanner.
view
.ImageVideoBanner
android:id=
"@+id/banner"
android:id=
"@+id/banner"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
android:layout_height=
"0dp"
app:layout_constraintHeight_percent=
"0.6"
app:layout_constraintHeight_percent=
"0.6"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
app:period=
"5000"
/>
<TextView
android:id=
"@+id/tvGoDetail"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"进入第二个页面"
android:textSize=
"40sp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/banner"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
imageVideoBanner/src/main/res/layout/banner_imge_video.xml
View file @
0ef30b50
...
@@ -5,13 +5,13 @@
...
@@ -5,13 +5,13 @@
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
>
<com.widget.imagevideobanner.
banner
.ViewPager
<com.widget.imagevideobanner.
view
.ViewPager
android:id=
"@+id/view_pager"
android:id=
"@+id/view_pager"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"
wrap_cont
ent"
android:layout_height=
"
match_par
ent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
app:layout_constraintTop_toTopOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
imageVideoBanner/src/main/res/layout/item_video_view.xml
View file @
0ef30b50
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
android:layout_height=
"match_parent"
android:layout_height=
"match_parent"
android:id=
"@+id/cVideoView"
>
android:id=
"@+id/cVideoView"
>
<com.widget.imagevideobanner.
banner
.MyVideoView
<com.widget.imagevideobanner.
view
.MyVideoView
android:id=
"@+id/video_view"
android:id=
"@+id/video_view"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_height=
"match_parent"
...
...
imageVideoBanner/src/main/res/layout/layout_exo_player_view.xml
0 → 100755
View file @
0ef30b50
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.exoplayer2.ui.PlayerView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/player_view"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:keepScreenOn=
"true"
app:use_controller=
"false"
app:show_timeout=
"1000"
app:surface_type=
"texture_view"
app:resize_mode=
"zoom"
app:player_layout_id=
"@layout/layout_simple_exo_player_view"
android:orientation=
"vertical"
>
</com.google.android.exoplayer2.ui.PlayerView>
\ No newline at end of file
imageVideoBanner/src/main/res/layout/layout_player_view.xml
0 → 100755
View file @
0ef30b50
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<ImageView
android:id=
"@+id/blur_background"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:transitionName=
"blur_image"
android:scaleType=
"centerCrop"
tools:background=
"@drawable/guide_defaut"
/>
<!-- 真正能够播放展示视频画面的view 会动态的添加到这里-->
<ImageView
android:id=
"@+id/cover"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:scaleType=
"centerInside"
android:transitionName=
"cover"
/>
<ProgressBar
android:id=
"@+id/buffer_view"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:indeterminate=
"true"
android:indeterminateTint=
"#CAE7DF"
android:transitionName=
"buffer_view"
android:visibility=
"visible"
/>
</merge>
\ No newline at end of file
imageVideoBanner/src/main/res/layout/layout_simple_exo_player_view.xml
0 → 100755
View file @
0ef30b50
<merge
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
android:id=
"@id/exo_content_frame"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_gravity=
"center"
>
<!-- Video surface will be inserted as the first child of the content frame. -->
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</merge>
imageVideoBanner/src/main/res/values/styles.xml
View file @
0ef30b50
...
@@ -8,6 +8,4 @@
...
@@ -8,6 +8,4 @@
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
</style>
</style>
</resources>
</resources>
imageVideoBanner/src/test/java/com/zxj/imagevideobanner/ExampleUnitTest.java
deleted
100644 → 0
View file @
d75937a0
package
com
.
zxj
.
imagevideobanner
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public
class
ExampleUnitTest
{
@Test
public
void
addition_isCorrect
()
throws
Exception
{
assertEquals
(
4
,
2
+
2
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment