作者 zhangji

封装视频播放模块

... ... @@ -11,18 +11,19 @@
<!-- 往sdcard中写入数据的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 在sdcard中创建/删除文件的权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:usesCleartextTraffic="true"
android:hardwareAccelerated="true"
android:supportsRtl="true"
android:theme="@style/Theme.SecurityTrainMaster">
android:theme="@style/Theme.SecurityTrainMaster"
android:usesCleartextTraffic="true">
<meta-data
android:name="design_width_in_dp"
android:value="375" />
... ... @@ -65,10 +66,13 @@
<activity
android:name=".ui.home.activity.SearchActivity"
android:screenOrientation="portrait" />
<activity android:name=".ui.home.activity.DatabaseActivity"
android:screenOrientation="portrait"/>
<activity android:name=".ui.home.activity.DatabaseDetailActivity"
android:screenOrientation="portrait"/>
<activity
android:name=".ui.home.activity.DatabaseActivity"
android:screenOrientation="portrait" />
<activity
android:name=".ui.home.activity.DatabaseDetailActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
android:screenOrientation="portrait" />
<activity android:name=".ui.home.activity.WebViewActivity" />
<activity android:name=".ui.home.activity.TextCourseActivity" />
<activity android:name=".ui.home.activity.TextDetailActivity" />
... ... @@ -81,15 +85,17 @@
<activity android:name=".ui.bank.activity.ExamTypeActivity" />
<activity android:name=".ui.bank.activity.ExamDetailActivity" />
<activity android:name=".ui.bank.activity.ExamCardActivity" />
<activity android:name=".ui.home.activity.OnlineDetailActivity"
android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name=".ui.home.activity.LiveCourseActivity"/>
<activity android:name=".ui.mine.activity.EditPersonalInfoActivity"/>
<activity android:name=".ui.mine.activity.ChangePwdActivity"/>
<activity android:name=".ui.mine.activity.ChangePhoneActivity"/>
<activity android:name=".ui.mine.activity.MyErrorQuestionActivity"/>
<activity android:name=".ui.mine.activity.QuestionRecordActivity"/>
<activity android:name=".ui.mine.activity.MyCredentialsActivity"/>
<activity
android:name=".ui.home.activity.OnlineDetailActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
android:screenOrientation="portrait" />
<activity android:name=".ui.home.activity.LiveCourseActivity" />
<activity android:name=".ui.mine.activity.EditPersonalInfoActivity" />
<activity android:name=".ui.mine.activity.ChangePwdActivity" />
<activity android:name=".ui.mine.activity.ChangePhoneActivity" />
<activity android:name=".ui.mine.activity.MyErrorQuestionActivity" />
<activity android:name=".ui.mine.activity.QuestionRecordActivity" />
<activity android:name=".ui.mine.activity.MyCredentialsActivity" />
</application>
... ...
... ... @@ -34,4 +34,11 @@ fun ImageView.courseHead(pic: String) {
.load(pic)
.placeholder(R.mipmap.placeholder_head)
.into(this)
}
\ No newline at end of file
}
fun ImageView.loadPic(pic: String) {
Glide.with(this)
.load(pic)
.placeholder(R.mipmap.placeholder_head)
.into(this)
}
... ...
... ... @@ -168,7 +168,7 @@ class DatabaseActivity :
}
})
databaseRecycler.adapter = resultAdapter
// resultAdapter.addList(recommendList)
resultAdapter.addList(recommendList)
}
... ...
package com.br_technology.securitytrain_master.ui.home.activity
import android.content.res.Configuration
import android.os.Bundle
import android.view.View
import com.br_technology.securitytrain_master.databinding.ActivityDatabaseDetailBinding
import com.br_technology.securitytrain_master.ui.home.adapter.PdfAdapter
import com.br_technology.securitytrain_master.ui.home.viewmodel.DatabaseDetailViewModel
import com.br_technology.securitytrain_master.view.listener.OnItemClickListener
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleActivity
/**
... ... @@ -24,6 +27,17 @@ class DatabaseDetailActivity :
back.setOnClickListener {
finish()
}
videoPlayer.initVideoBuilderMode(
"",
"http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4",
this@DatabaseDetailActivity,
lifecycle
)
videoPlayer.titleTextView.visibility = View.GONE
videoPlayer.backButton.visibility = View.GONE
val data: String =
"<p>2021年1月20日0时25分,我国在西昌卫星发射中心用长征三号乙运载火箭," +
"成功将天通一号03星发射升空。在为中国航天发射带来2021年开门红的同时," +
... ... @@ -65,7 +79,7 @@ class DatabaseDetailActivity :
webView.loadDataWithBaseURL(null, dataImg, "text/html", "utf-8", null)
val pdfAdapter = PdfAdapter()
pdfAdapter.addListener(object :OnItemClickListener<String>{
pdfAdapter.addListener(object : OnItemClickListener<String> {
override fun onClick(position: Int, data: String) {
startActivity(WebViewActivity::class.java)
}
... ... @@ -90,4 +104,20 @@ class DatabaseDetailActivity :
override fun initDataObserver() {
}
override fun onBackPressed() {
binding.videoPlayer.onBackPressed()
if (GSYVideoManager.backFromWindowFull(this)) {
return
}
super.onBackPressed()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
//如果旋转了就全屏
binding.videoPlayer.onConfigurationChanged(newConfig, this)
}
}
\ No newline at end of file
... ...
... ... @@ -2,15 +2,22 @@ package com.br_technology.securitytrain_master.ui.home.activity
import android.content.res.Configuration
import android.view.View
import android.widget.ImageView
import androidx.fragment.app.FragmentPagerAdapter
import com.br_technology.securitytrain_master.base.view.BasePagerAdapter
import com.br_technology.securitytrain_master.databinding.ActivityOnlineDetailBinding
import com.br_technology.securitytrain_master.expand.courseHead
import com.br_technology.securitytrain_master.expand.glideRound
import com.br_technology.securitytrain_master.expand.loadPic
import com.br_technology.securitytrain_master.ui.home.fragment.CourseListFragment
import com.br_technology.securitytrain_master.ui.home.fragment.OnlineDetailFragment
import com.br_technology.securitytrain_master.ui.home.viewmodel.OnlineDetailViewModel
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.OrientationOption
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleActivity
... ... @@ -24,18 +31,23 @@ class OnlineDetailActivity
ActivityOnlineDetailBinding::inflate
) {
var orientationUtils: OrientationUtils ? =null
override fun initDataObserver() {
}
var isPlay : Boolean = false
var isPause : Boolean = false
override fun initData() {
super.initData()
binding.apply {
videoPlayer.initVideoBuilderMode(
"",
"http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4",
this@OnlineDetailActivity,
lifecycle
)
videoPlayer.titleTextView.visibility = View.GONE
videoPlayer.backButton.visibility = View.GONE
val searchResultAdapter = BasePagerAdapter(
supportFragmentManager,
... ... @@ -49,62 +61,23 @@ class OnlineDetailActivity
viewPager.adapter = searchResultAdapter
tabLayout.setupWithViewPager(viewPager)
initOrientationUtils(videoPlayer, false)
val source1 =
"http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4"
videoPlayer.setUp(source1, true, "测试视频")
videoPlayer.backButton.visibility = View.GONE
videoPlayer.startButton.setOnClickListener {
videoPlayer.startPlayLogic()
}
videoPlayer.fullscreenButton.setOnClickListener {
// orientationUtils!!.resolveByClick()
videoPlayer.startWindowFullscreen(this@OnlineDetailActivity,true,true)
}
}
}
private fun initOrientationUtils(videoPlayer: StandardGSYVideoPlayer, full: Boolean) {
orientationUtils = OrientationUtils(this, videoPlayer)
//是否需要跟随系统旋转设置
//orientationUtils.setRotateWithSystem(false);
orientationUtils!!.isLand = if (full) 1 else 0
}
override fun onPause() {
super.onPause()
binding.videoPlayer.onVideoPause()
}
override fun onResume() {
super.onResume()
binding.videoPlayer.onVideoResume()
}
override fun onDestroy() {
GSYVideoManager.releaseAllVideos();
if (orientationUtils != null)
orientationUtils!!.releaseListener();
super.onDestroy()
override fun onBackPressed() {
binding.videoPlayer.onBackPressed()
if (GSYVideoManager.backFromWindowFull(this)) {
return
}
super.onBackPressed()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
//如果旋转了就全屏
// if (isPlay && !isPause) {
binding.videoPlayer.onConfigurationChanged(
this,
newConfig,
orientationUtils,
true,
true
);
// }
binding.videoPlayer.onConfigurationChanged(newConfig, this)
}
}
\ No newline at end of file
... ...
... ... @@ -19,6 +19,7 @@ class WebViewActivity : AppCompatActivity() {
setContentView(R.layout.activity_web)
val webView: WebView = findViewById(R.id.web_view)
webView.loadUrl("file:///android_asset/index.html?"+"http://www.tjxqda.com/cms/picture/8697695a-b8a6-4379-b89e-85c11fd127e2.pdf")
// webView.loadUrl("http://static.bszh.com/js/pdf/web/viewer.html?file"+"http://www.tjxqda.com/cms/picture/8697695a-b8a6-4379-b89e-85c11fd127e2.pdf")
webView.webViewClient=object :WebViewClient(){
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
... ...
package com.br_technology.securitytrain_master.ui.home.fragment
import android.view.View
import androidx.core.content.ContextCompat
import com.br_technology.securitytrain_master.R
import com.br_technology.securitytrain_master.databinding.FragmentOnliveCourseBinding
import com.br_technology.securitytrain_master.expand.addItemDecoration2
... ... @@ -10,7 +8,6 @@ import com.br_technology.securitytrain_master.ui.home.adapter.VideoCourseAdapter
import com.br_technology.securitytrain_master.ui.home.pojo.VideoCourse
import com.br_technology.securitytrain_master.ui.home.viewmodel.OnLiveCourseFragmentViewModel
import com.br_technology.securitytrain_master.view.listener.OnItemClickListener
import com.br_technology.securitytrain_master.view.listener.ToolBarClickListener
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleFragment
/**
... ...
package com.br_technology.securitytrain_master.view
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.text.TextUtils
import android.util.AttributeSet
import android.widget.ImageView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import com.br_technology.securitytrain_master.R
import com.br_technology.securitytrain_master.expand.loadPic
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
/**
* createTime:2021/8/2 8:57
* auth:张继
* des:
*/
class MyVideoPlayer : StandardGSYVideoPlayer,LifecycleObserver {
private var isPlay = false
private var isPause = false
private var orientationUtils: OrientationUtils? = null
constructor(context: Context) : super(context)
constructor(context: Context, fullFlag: Boolean) : super(context, fullFlag)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
override fun getLayoutId(): Int {
return R.layout.layout_video_player
}
/**
* 选择普通模式
*/
private fun initVideo(activity: Activity) {
//外部辅助的旋转,帮助全屏
orientationUtils = OrientationUtils(activity, this, orientationOption)
//初始化不打开外部的旋转
orientationUtils!!.isEnable = false
if (this.fullscreenButton != null) {
this.fullscreenButton.setOnClickListener {
showFull()
}
}
}
private fun showFull() {
if (orientationUtils!!.isLand != 1) {
//直接横屏
orientationUtils!!.resolveByClick()
}
//第一个true是否需要隐藏actionbar,第二个true是否需要隐藏statusbar
this.startWindowFullscreen(
context,
true,
true
)
}
/**
* 选择builder模式
*/
fun initVideoBuilderMode(
pic: String,
mp4: String,
activity: Activity,
lifecycle: Lifecycle
) {
// 添加生命周期管理
lifecycle.addObserver(this)
initVideo(activity)
getGSYVideoOptionBuilder(pic, mp4).setVideoAllCallBack(object : GSYSampleCallBack() {
override fun onPrepared(url: String?, vararg objects: Any?) {
super.onPrepared(url, *objects)
//开始播放了才能旋转和全屏
orientationUtils!!.isEnable = true
isPlay = true
}
override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
super.onQuitFullscreen(url, *objects)
orientationUtils?.backToProtVideo();
}
}).build(this)
}
private fun getGSYVideoOptionBuilder(pic: String, mp4: String): GSYVideoOptionBuilder {
val imageView = ImageView(context)
imageView.scaleType = ImageView.ScaleType.CENTER_CROP
if (TextUtils.isEmpty(pic)) {
imageView.setImageResource(R.mipmap.mask)
}else{
// 展位图
imageView.loadPic(pic)
}
return GSYVideoOptionBuilder()
.setThumbImageView(imageView)
.setUrl(mp4)
.setCacheWithPlay(true)
.setVideoTitle("")
.setIsTouchWiget(true)
.setRotateViewAuto(false)
.setLockLand(false)
.setShowFullAnimation(false)//打开动画
.setNeedLockFull(true)
.setSeekRatio(1f)
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun onResume() {
this.currentPlayer.onVideoResume(false)
isPause = false
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun onPause() {
this.currentPlayer.onVideoPause()
isPause = true
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private fun onDestroy() {
if (isPlay) {
this.currentPlayer.release()
}
if (orientationUtils != null) orientationUtils!!.releaseListener()
}
fun onBackPressed() {
if (orientationUtils != null) {
orientationUtils!!.backToProtVideo()
}
}
fun onConfigurationChanged(newConfig: Configuration, activity: Activity) {
//如果旋转了就全屏
if (isPlay && !isPause) {
this.onConfigurationChanged(
activity,
newConfig,
orientationUtils,
true,
true
)
}
}
}
... ...
... ... @@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.RelativeLayout
import androidx.appcompat.widget.Toolbar
import com.br_technology.securitytrain_master.R
import com.br_technology.securitytrain_master.databinding.BarToolViewBinding
import com.br_technology.securitytrain_master.view.listener.ToolBarClickListener
... ...
... ... @@ -52,25 +52,12 @@
android:textColor="@color/color_32"
android:textSize="17sp" />
<FrameLayout
<com.br_technology.securitytrain_master.view.MyVideoPlayer
android:id="@+id/video_player"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_height="192dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/mask" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/paly" />
</FrameLayout>
android:layout_marginEnd="16dp" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
... ... @@ -90,8 +77,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:scrollbars="none"
android:layout_marginBottom="40dp" />
android:layout_marginBottom="40dp"
android:scrollbars="none" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/pdf"
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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"
... ... @@ -11,32 +11,31 @@
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/status_bar"
android:visibility="visible"
app:toolTitle="课程详情" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
android:id="@+id/video_player"
android:layout_width="match_parent"
android:layout_height="210dp" />
<com.br_technology.securitytrain_master.view.MyVideoPlayer
android:id="@+id/video_player"
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_below="@id/tool_bar" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
style="@style/SearchTab"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:overScrollMode="never"
app:tabMode="auto"
app:tabSelectedTextColor="@color/color_252"
app:tabTextColor="@color/color_96" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
style="@style/SearchTab"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_below="@id/video_player"
android:overScrollMode="never"
app:tabMode="auto"
app:tabSelectedTextColor="@color/color_252"
app:tabTextColor="@color/color_96" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tab_layout" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
</RelativeLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<RelativeLayout
android:id="@+id/surface_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
</RelativeLayout>
<RelativeLayout
android:id="@+id/thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="#000000"
android:scaleType="fitCenter" />
<LinearLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#99000000"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="invisible">
<TextView
android:id="@+id/current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="00:00"
android:textColor="#ffffff" />
<SeekBar
android:id="@+id/progress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:background="@null"
android:max="100"
android:maxHeight="4dp"
android:minHeight="4dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:progressDrawable="@drawable/video_seek_progress"
android:thumb="@drawable/video_seek_thumb" />
<TextView
android:id="@+id/total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:text="00:00"
android:textColor="#ffffff" />
<ImageView
android:id="@+id/fullscreen"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingRight="16dp"
android:scaleType="center"
android:src="@drawable/video_enlarge" />
</LinearLayout>
<ProgressBar
android:id="@+id/bottom_progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="1.5dp"
android:layout_alignParentBottom="true"
android:max="100"
android:progressDrawable="@drawable/video_progress" />
<ImageView
android:id="@+id/back_tiny"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginLeft="6dp"
android:layout_marginTop="6dp"
android:visibility="gone" />
<LinearLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/video_title_bg"
android:gravity="center_vertical">
<ImageView
android:id="@+id/back"
android:layout_width="48dp"
android:layout_height="48dp"
android:paddingLeft="10dp"
android:scaleType="centerInside"
android:src="@drawable/video_back" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textColor="@android:color/white"
android:textSize="18sp" />
</LinearLayout>
<ProgressBar
android:id="@+id/loading"
style="?android:attr/progressBarStyleLarge"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="invisible" />
<ImageView
android:id="@+id/start"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:src="@mipmap/play" />
<ImageView
android:id="@+id/small_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:scaleType="centerInside"
android:src="@drawable/video_small_close"
android:visibility="gone" />
<ImageView
android:id="@+id/lock_screen"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="50dp"
android:scaleType="centerInside"
android:src="@drawable/unlock"
android:visibility="gone" />
</RelativeLayout>
... ...