video_streaming draggable popup

merge-requests/745/head
mosazaid 5 years ago
parent 96f2de2c35
commit 6fca263109

@ -7,7 +7,7 @@ import androidx.annotation.NonNull
import com.google.gson.GsonBuilder
import com.hmg.hmgDr.Model.GetSessionStatusModel
import com.hmg.hmgDr.Model.SessionStatusModel
import io.flutter.embedding.android.FlutterFragment
import com.hmg.hmgDr.ui.fragment.VideoCallFragment
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
@ -22,7 +22,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler
private var call: MethodCall? = null
private val LAUNCH_VIDEO: Int = 1
private val flutterFragment: FlutterFragment? = null
lateinit var dialogFragment: VideoCallFragment
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
@ -78,7 +78,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler
// startActivityForResult(intent, LAUNCH_VIDEO)
val transaction = supportFragmentManager.beginTransaction()
// transaction.add()
dialogFragment = VideoCallFragment.newInstance(Bundle())
dialogFragment.isCancelable = false
dialogFragment.show(transaction, "dialog")
}

@ -411,10 +411,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi
finish();
}
public void onMinimizedClicked(View view) {
}
public void onSwitchCameraClicked(View view) {
if (mPublisher != null) {
isSwitchCameraClicked = !isSwitchCameraClicked;
@ -424,6 +420,14 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi
}
}
public void onCallClicked(View view) {
disconnectSession();
}
public void onMinimizedClicked(View view) {
}
public void onCameraClicked(View view) {
if (mPublisher != null) {
isCameraClicked = !isCameraClicked;
@ -433,15 +437,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi
}
}
public void onSpeckerClicked(View view) {
if (mSubscriber != null) {
isSpeckerClicked = !isSpeckerClicked;
mSubscriber.setSubscribeToAudio(!isSpeckerClicked);
int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled;
mspeckerBtn.setImageResource(res);
}
}
public void onMicClicked(View view) {
if (mPublisher != null) {
@ -452,8 +447,13 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi
}
}
public void onCallClicked(View view) {
disconnectSession();
public void onSpeckerClicked(View view) {
if (mSubscriber != null) {
isSpeckerClicked = !isSpeckerClicked;
mSubscriber.setSubscribeToAudio(!isSpeckerClicked);
int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled;
mspeckerBtn.setImageResource(res);
}
}
@Override

@ -3,24 +3,26 @@ package com.hmg.hmgDr.ui.fragment
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Point
import android.graphics.drawable.ColorDrawable
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.*
import android.widget.*
import androidx.fragment.app.Fragment
import androidx.annotation.Nullable
import androidx.fragment.app.DialogFragment
import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel
import com.hmg.hmgDr.Model.GetSessionStatusModel
import com.hmg.hmgDr.Model.SessionStatusModel
import com.hmg.hmgDr.R
import com.hmg.hmgDr.ui.VideoCallActivity
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView
import com.hmg.hmgDr.ui.VideoCallPresenterImpl
@ -31,10 +33,20 @@ import pub.devrel.easypermissions.AppSettingsDialog
import pub.devrel.easypermissions.EasyPermissions
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
import java.util.*
import kotlin.math.ceil
class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener,
class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener,
SubscriberKit.VideoListener, VideoCallView {
var isFullScreen: Boolean = true
private var x_init_cord = 0
private var y_init_cord:Int = 0
private var x_init_margin:Int = 0
private var y_init_margin:Int = 0
private val szWindow: Point = Point()
private lateinit var mWindowManager: WindowManager
private var isLeft = true
lateinit var videoCallPresenter: VideoCallPresenter
private var mSession: Session? = null
@ -61,11 +73,13 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
private var isSpeckerClicked = false
private var isMicClicked = false
private var mCallBtn: ImageView? = null
private var mCameraBtn: ImageView? = null
private var mSwitchCameraBtn: ImageView? = null
private var mspeckerBtn: ImageView? = null
private var mMicBtn: ImageView? = null
private lateinit var videoCallContainer: LinearLayout
private lateinit var mCallBtn: ImageView
private lateinit var btnMinimize: ImageView
private lateinit var mCameraBtn: ImageView
private lateinit var mSwitchCameraBtn: ImageView
private lateinit var mspeckerBtn: ImageView
private lateinit var mMicBtn: ImageView
private val progressBar: ProgressBar? = null
private val countDownTimer: CountDownTimer? = null
@ -84,6 +98,45 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
requestPermissions()
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
}
override fun getTheme(): Int {
return R.style.dialogTheme
}
override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog {
val dialog: Dialog = super.onCreateDialog(savedInstanceState)
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// This is done in a post() since the dialog must be drawn before locating.
requireView().post {
val dialogWindow = dialog!!.window
if (dialog != null && dialogWindow != null) {
dialogWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
}
// Make the dialog possible to be outside touch
dialogWindow!!.setFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
)
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
requireView().invalidate()
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -91,6 +144,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
Objects.requireNonNull(requireActivity().actionBar)!!.hide()
initUI(view)
handleDragDialog()
return view
}
@ -121,6 +175,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
@SuppressLint("ClickableViewAccessibility")
private fun initUI(view: View) {
videoCallContainer = view.findViewById<LinearLayout>(R.id.video_call_ll)
mPublisherViewContainer = view.findViewById<FrameLayout>(R.id.local_video_view_container)
mSubscriberViewContainer = view.findViewById<RelativeLayout>(R.id.remote_video_view_container)
@ -136,11 +191,29 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
controlPanel = view.findViewById<RelativeLayout>(R.id.control_panel)
videoCallPresenter = VideoCallPresenterImpl(this, baseUrl)
mCallBtn = view.findViewById<ImageView>(R.id.btn_call)
mCallBtn.setOnClickListener {
onCallClicked(it)
}
btnMinimize = view.findViewById<ImageView>(R.id.btn_minimize)
btnMinimize.setOnClickListener {
onMinimizedClicked(it)
}
mCameraBtn = view.findViewById<ImageView>(R.id.btn_camera)
mCameraBtn.setOnClickListener {
onCameraClicked(it)
}
mSwitchCameraBtn = view.findViewById<ImageView>(R.id.btn_switch_camera)
mSwitchCameraBtn.setOnClickListener {
onSwitchCameraClicked(it)
}
mspeckerBtn = view.findViewById<ImageView>(R.id.btn_specker)
mspeckerBtn.setOnClickListener {
onSpeckerClicked(it)
}
mMicBtn = view.findViewById<ImageView>(R.id.btn_mic)
mMicBtn.setOnClickListener {
onMicClicked(it)
}
// progressBarLayout=findViewById(R.id.progressBar);
// progressBar=findViewById(R.id.progress_bar);
// progressBarTextView=findViewById(R.id.progress_bar_text);
@ -316,6 +389,20 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
requireActivity().finish()
}
override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) {
if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) {
val returnIntent = Intent()
returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel)
requireActivity().setResult(Activity.RESULT_OK, returnIntent)
requireActivity().finish()
}
}
override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {}
override fun onFailure() {}
fun onSwitchCameraClicked(view: View?) {
if (mPublisher != null) {
isSwitchCameraClicked = !isSwitchCameraClicked
@ -325,6 +412,25 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
}
}
fun onCallClicked(view: View?) {
disconnectSession()
}
fun onMinimizedClicked(view: View?) {
if (isFullScreen) {
dialog?.window?.setLayout(
400,
600
)
} else {
dialog?.window?.setLayout(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
}
isFullScreen = !isFullScreen
}
fun onCameraClicked(view: View?) {
if (mPublisher != null) {
isCameraClicked = !isCameraClicked
@ -334,6 +440,15 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
}
}
fun onMicClicked(view: View?) {
if (mPublisher != null) {
isMicClicked = !isMicClicked
mPublisher!!.publishAudio = !isMicClicked
val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled
mMicBtn!!.setImageResource(res)
}
}
fun onSpeckerClicked(view: View?) {
if (mSubscriber != null) {
isSpeckerClicked = !isSpeckerClicked
@ -343,31 +458,144 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
}
}
fun onMicClicked(view: View?) {
if (mPublisher != null) {
isMicClicked = !isMicClicked
mPublisher!!.publishAudio = !isMicClicked
val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled
mMicBtn!!.setImageResource(res)
@SuppressLint("ClickableViewAccessibility")
fun handleDragDialog(){
mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager
getWindowManagerDefaultDisplay()
videoCallContainer.setOnTouchListener { _, event ->
//Get Floating widget view params
//Get Floating widget view params
val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
//get the touch location coordinates
val x_cord = event.rawX.toInt()
val y_cord = event.rawY.toInt()
val x_cord_Destination: Int
var y_cord_Destination: Int
when (event.action) {
MotionEvent.ACTION_DOWN -> {
x_init_cord = x_cord
y_init_cord = y_cord
//remember the initial position.
x_init_margin = layoutParams.x
y_init_margin = layoutParams.y
}
MotionEvent.ACTION_UP -> {
//Get the difference between initial coordinate and current coordinate
val x_diff: Int = x_cord - x_init_cord
val y_diff: Int = y_cord - y_init_cord
y_cord_Destination = y_init_margin + y_diff
val barHeight: Int = getStatusBarHeight()
if (y_cord_Destination < 0) {
// y_cord_Destination = 0
y_cord_Destination =
-(szWindow.y - (videoCallContainer.height /*+ barHeight*/))
} else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) {
y_cord_Destination =
szWindow.y - (videoCallContainer.height + barHeight)
}
layoutParams.y = y_cord_Destination
//reset position if user drags the floating view
resetPosition(x_cord)
}
MotionEvent.ACTION_MOVE -> {
val x_diff_move: Int = x_cord - x_init_cord
val y_diff_move: Int = y_cord - y_init_cord
x_cord_Destination = x_init_margin + x_diff_move
y_cord_Destination = y_init_margin + y_diff_move
layoutParams.x = x_cord_Destination
layoutParams.y = y_cord_Destination
dialog!!.window!!.attributes = layoutParams
}
}
true
}
}
fun onCallClicked(view: View?) {
disconnectSession()
/* Reset position of Floating Widget view on dragging */
private fun resetPosition(x_cord_now: Int) {
if (x_cord_now <= szWindow.x / 2) {
isLeft = true
moveToLeft(x_cord_now)
} else {
isLeft = false
moveToRight(x_cord_now)
}
}
override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) {
if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) {
val returnIntent = Intent()
returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel)
requireActivity().setResult(Activity.RESULT_OK, returnIntent)
requireActivity().finish()
}
/* Method to move the Floating widget view to Left */
private fun moveToLeft(current_x_cord: Int) {
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
mParams.x =
(szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt()
dialog!!.window!!.attributes = mParams
val x = szWindow.x - current_x_cord
object : CountDownTimer(500, 5) {
//get params of Floating Widget view
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
override fun onTick(t: Long) {
val step = (500 - t) / 5
// mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt()
mParams.x =
(szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt()
dialog!!.window!!.attributes = mParams
}
override fun onFinish() {
mParams.x = -(szWindow.x - videoCallContainer.width)
dialog!!.window!!.attributes = mParams
}
}.start()
}
override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {}
/* Method to move the Floating widget view to Right */
private fun moveToRight(current_x_cord: Int) {
// var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
// mParams.x =
// (szWindow.x + current_x_cord * current_x_cord - videoCallContainer.width).toInt()
//
// dialog!!.window!!.attributes = mParams
object : CountDownTimer(500, 5) {
//get params of Floating Widget view
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
override fun onTick(t: Long) {
val step = (500 - t) / 5
mParams.x =
(szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt()
dialog!!.window!!.attributes = mParams
}
override fun onFailure() {}
override fun onFinish() {
mParams.x = szWindow.x - videoCallContainer.width
dialog!!.window!!.attributes = mParams
}
}.start()
}
private fun getWindowManagerDefaultDisplay() {
mWindowManager.getDefaultDisplay()
.getSize(szWindow)
}
/* return status bar height on basis of device display metrics */
private fun getStatusBarHeight(): Int {
return ceil(
(25 * requireActivity().applicationContext.resources.displayMetrics.density).toDouble()
).toInt()
}
companion object {
@JvmStatic
@ -376,7 +604,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
arguments = args
}
private val TAG = VideoCallActivity::class.java.simpleName
private val TAG = VideoCallFragment::class.java.simpleName
private const val RC_SETTINGS_SCREEN_PERM = 123
private const val RC_VIDEO_APP_PERM = 124

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/video_call_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/text_color"
@ -115,7 +116,6 @@
android:layout_marginTop="@dimen/local_preview_margin_top"
android:layout_marginEnd="@dimen/local_preview_margin_right"
android:layout_alignParentEnd="true"
android:onClick="onSwitchCameraClicked"
android:scaleType="centerCrop"
android:src="@drawable/flip_enabled" />
@ -132,7 +132,6 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_alignParentEnd="true"
android:onClick="onCallClicked"
android:scaleType="centerCrop"
android:src="@drawable/call" />
@ -141,7 +140,6 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_alignParentStart="true"
android:onClick="onMinimizedClicked"
android:layout_marginEnd="@dimen/padding_space_small"
android:scaleType="centerCrop"
android:src="@drawable/ic_mini" />
@ -151,7 +149,6 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_toEndOf="@id/btn_minimize"
android:onClick="onCameraClicked"
android:scaleType="centerCrop"
android:layout_marginEnd="@dimen/padding_space_small"
android:src="@drawable/video_enabled" />
@ -161,7 +158,6 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_toEndOf="@id/btn_camera"
android:onClick="onMicClicked"
android:layout_marginEnd="@dimen/padding_space_small"
android:scaleType="centerCrop"
android:src="@drawable/mic_enabled" />
@ -171,7 +167,6 @@
android:layout_width="@dimen/video_icon_size"
android:layout_height="@dimen/video_icon_size"
android:layout_toEndOf="@id/btn_mic"
android:onClick="onSpeckerClicked"
android:scaleType="centerCrop"
android:layout_marginEnd="@dimen/padding_space_small"
android:src="@drawable/audio_enabled" />

@ -16,4 +16,21 @@
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="dialogTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<!-- title encapsulating main part (backgroud) of custom alertdialog -->
<item name="android:windowFrame">@null</item>
<!-- turn off any drawable used to draw a frame on the window -->
<item name="android:windowBackground">@null</item>
<!-- turn off any drawable used to draw a frame on the window -->
<item name="android:windowIsFloating">true</item>
<!-- float the window so it does not fill the screen -->
<item name="android:windowNoTitle">true</item>
<!-- remove the title bar we make our own-->
<item name="android:windowContentOverlay">@null</item>
<!-- remove the shadow from under the title bar -->
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
</style>
</resources>

Loading…
Cancel
Save