Resize video to fit the VideoView - android

I'm positioning a VideoView with AbsoluteLayout (I need to display it on several places into the screen at specific positions).
public void showVideo(RectF bounds, final String videoUrl) {
AbsoluteLayout.LayoutParams params = (AbsoluteLayout.LayoutParams) video.getLayoutParams();
params.width = (int) bounds.width();
params.height = (int) bounds.height();
params.x = (int) bounds.left;
params.y = (int) bounds.top;
video.requestLayout();
video.setVisibility(View.VISIBLE);
video.setFocusable(true);
video.setFocusableInTouchMode(true);
video.requestFocus();
File file = new File(videoUrl);
video.setVideoPath(file.getAbsolutePath());
video.start();
}
But the Video ins't getting resized to the bounds I specified.
Any tips?
Another related question is, how to make the MediaController show over the VideoView?

this is very close to what you are trying. if you are willing to subclass the videoview and override onMeasure here is the solution. you need to
MyVideoView extends VideoView
https://stackoverflow.com/questions/4434027/android-videoview-orientation-change-with-buffered-video/4452597#4452597
as for showing MediaController over VidowView
Declare
private MediaController controller = null;
OnCreate
controller = new MediaController(this);
controller.setMediaPlayer(mcEvents);
controller.setAnchorView(findViewById(R.id.wrapper));
Activity
#Override
public boolean onTouchEvent(MotionEvent event) {
//the MediaController will hide after 3 seconds - tap the screen to make it appear again
controller.show();
return false;
}
Media Controller events
private MediaController.MediaPlayerControl mcEvents = new MediaController.MediaPlayerControl() {
public void start() {
player.start();
}
public void seekTo(int pos) {
player.seekTo(pos);
}
public void pause() {
player.pause();
}
public boolean isPlaying() {
return player.isPlaying();
}
public int getDuration() {
return player.getDuration();
}
public int getCurrentPosition() {
return player.getCurrentPosition();
}
public int getBufferPercentage() {
return pBuffer;
}
public boolean canSeekForward() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canPause() {
return true;
}
};
a sample layout file
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/wrapper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.my.views.MyViedoView
android:id="#+id/player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</FrameLayout>

You can only change the layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView android:id="#+id/videoViewRelative"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</VideoView>
</RelativeLayout>

After you change your LayoutParams I think you will need to call setLayoutParams so the layout can be updated with the new params. After the call to setLayoutParams you may have to call the method reqestLayout to invalidate the layout and trigger a redraw of the view.
You will need to create a new instance of the MediaController and use the method setMediaController on the VideoView object.

Related

android-black screen on displaying video by using VideoView

this is my layout :
<LinearLayout 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" >
<FrameLayout
android:id="#+id/frameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" >
<VideoView
android:id="#+id/geoloc_anim"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="top|center"
android:visibility="visible" />
<FrameLayout
android:id="#+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
</FrameLayout>
</LinearLayout>
this is my activity code:
public class MainActivity extends ActionBarActivity implements OnPreparedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
VideoView mVideoView = (VideoView) findViewById(R.id.videoview);
Uri uri = Uri.parse("android.resource://" + getPackageName()+"/raw/lst2");
mVideoView.setVideoURI(uri);
mVideoView.requestFocus();
mVideoView.setZOrderOnTop(true);
mVideoView.start();
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
View placeholder = (View) findViewById(R.id.placeholder);
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
// video started; hide the placeholder.
placeholder.setVisibility(View.GONE);
return true;
}
return false;
}
});
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
It works fine on android 4.2 but it doesn't work properly on android 2.3 . on android 2.3 , the first time it opens it works find but when close the app and open it again ,a black screen comes , something like this :
and after one minute or so , it goes from a black screen to a white screen but still nothing plays .
Could you help me to solve this problem ?
Very late answer. But surely it helps anyone.
set videoView.setZOrderOnTop(true) before start().
https://developer.android.com/reference/android/view/SurfaceView.html#setZOrderOnTop(boolean)
videoView.setVideoURI(Uri.parse(uriString));
videoView.setZOrderOnTop(true);//this line solve the problem
videoView.start();
I resolved this with toggling alpha for VideoView:
public class VideoPlayer extends VideoView {
....
public VideoPlayer(Context context) {
super(context);
init();
}
public void init() {
setAlpha(0); // hides view
setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
setAlpha(1); // shows view
return true;
}
return false;
}
});
}
});
I guess you can do the same if you have external VideoView and have access to it.
This code works for me, code tested on android nougat.
No require additional code in your java file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
tools:context=".SecondaryDisplay"
android:background="#color/black">
<VideoView
android:id="#+id/videoView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
you need in onPrepared change the Window content! like show toask or other,e.g
#Override
public void onPrepared(final MediaPlayer mp) {
Toast.makeText(getApplicationContext(),"onPrepared",ToasLENGTH_SHORT).show();
mVideoView.setZOrderOnTop(false);
mVideoView.setBackgroundColor(Color.TRANSPARENT);
}
remove the mVideoView.start() and change your onPrepared to start your video,
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
..............
I do not have a device with android less than 4.2 to test with, but this is how I start videos with my application
Maybe to late, but I found a solution that worked for me. I combined answers from Sagar Limbani and faljbour
videoView.setVideoURI(Uri.parse(path));
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
mp.start();
new Handler().post(new Runnable() {
#Override
public void run() {
if(mp.getCurrentPosition() != 0){
View placeholder = findViewById(R.id.placeholder);
placeholder.setVisibility(View.GONE);
} else {
new Handler().postDelayed(this, 50);
}
}
});
}
});
It worked for android 5.1, 5.0 and 4.0
I had the same issue. I found that the main reason for that was the use of FrameLayout as the parent layout. Use RelativeLayout as the parent layout of the VideoView
<LinearLayout 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" >
<RelativeLayout
android:id="#+id/frameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" >
<VideoView
android:id="#+id/geoloc_anim"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="top|center"
android:visibility="visible" />
<FrameLayout
android:id="#+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
</RelativeLayout>
</LinearLayout>
You can solve this by using custom VideoPlayer extends VideoView
public class VideoPlayer extends VideoView {
public VideoPlayer(Context context) {
super(context);
init();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
TyrooLog.i(TAG, "onMeasure");
int width = getDefaultSize(videoWidth, widthMeasureSpec);
int height = getDefaultSize(videoHeight, heightMeasureSpec);
if (videoWidth > 0 && videoHeight > 0) {
if (videoWidth * height > width * videoHeight) {
TyrooLog.i(TAG, "video too tall, correcting");
height = width * videoHeight / videoWidth;
} else if (videoWidth * height < width * videoHeight) {
TyrooLog.i(TAG, "video too wide, correcting");
width = height * videoWidth / videoHeight;
} else {
TyrooLog.i(TAG, "aspect ratio is correct: " + width+"/"+height+"="+mVideoWidth+"/"+mVideoHeight);
}
}
TyrooLog.i(TAG, "setting size: " + width + 'x' + height);
setMeasuredDimension(width, height);
}
}
I faced a similar issue and found that adding mp.seekTo(1); in the onPrepared(MediaPlayer mp) method fixed it.

Using surfaceview and fragments to display video. Video doesn't show but I have sound,

I have seen several posts with the same issue, but I still can't fix my issue. I am using surfaceview, fragments and mediaplayer to play a mp4 video. I get audio, but no video. The video does play with no issues outside of the application. I have tried different formats, but no luck. I am not using an emulator. I am using a Samsung Galaxy Tab2 to test. What am I missing to show video?
Here is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SurfaceView
android:id="#+id/video_surfaceView"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</SurfaceView>
<Button
android:id="#+id/playvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY "/>
<Button
android:id="#+id/pausevideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PAUSE"/>
<Button
android:id="#+id/stopvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- STOP"/>
</LinearLayout>
Here is my code:
public class ChapterVideoFragment extends Fragment {
private static final String TAG = "ChapterVideoFragment";
private static final boolean VERBOSE = true;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaPlayer mp = null;
private Button mPlayVideo,
mPauseVideo,
mStopVideo;
private boolean mPausing = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
if (VERBOSE) Log.v(TAG, "+++ onCreateView +++");
View v = inflater.inflate(R.layout.fragment_video, parent, false);
mSurfaceView = (SurfaceView)v.findViewById(R.id.video_surfaceView);
mPlayVideo = (Button)v.findViewById(R.id.playvideoplayer);
mPauseVideo = (Button)v.findViewById(R.id.pausevideoplayer);
mStopVideo = (Button)v.findViewById(R.id.stopvideoplayer);
mp = MediaPlayer.create(getActivity(), R.raw.improvisation);
mPlayVideo.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
//Get the dimensions of the video
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get the width of the screen
int screenWidth =
getActivity().getWindowManager().getDefaultDisplay().getWidth();
//Get the SurfaceView layout parameters
android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
//Set the width of the SurfaceView to the width of the screen
lp.width = screenWidth;
//Set the height of the SurfaceView to match the aspect ratio of the video
//be sure to cast these as floats otherwise the calculation will likely be
0
lp.height = (int) (((float)videoHeight / (float)videoWidth) *
(float)screenWidth);
//Commit the layout parameters
mSurfaceView.setLayoutParams(lp);
//mp.setDisplay(mSurfaceView.getHolder());
mp.start();
}
});
Here is the code for SurfaceView:
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
if (VERBOSE) Log.v(TAG, "+++ surfaceCreated +++");
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
});
try using videoview - it is possible that the device you are using to display the video, does not support the format in mediaplayer object, i solved this problem with videoview

VideoView Full screen in android application

i have a videoview in my application. the code is like this.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/opsbuds"
android:orientation="vertical">
<TextView
android:id="#+id/adtxt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"></TextView>
<VideoView
android:id="#+id/videoView11"
android:layout_width="300dip"
android:layout_height="250dip"
android:layout_marginLeft="30dip"></VideoView>
<LinearLayout
android:id="#+id/llv11"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"></LinearLayout>
<Button
android:id="#+id/button1211"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:background="#drawable/button"
android:text=" Continue "
android:textColor="#800080"
android:textSize="20dp"
android:textStyle="bold"></Button>
</LinearLayout>
</ScrollView>
the video view width and hieght is mentioned in xml file. What i want is , once i press a button the videoview should come on full screen and once i press back button the videoview should go back to its mentioned size. please help?
I had to make my VideoView sit in a RelativeLayout in order to make the chosen answer work.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView android:id="#+id/videoViewRelative"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</VideoView>
</RelativeLayout>
As given here: Android - How to stretch video to fill VideoView area Toggling between screen sizes would be as simple as changing the layout parameters as given in the chosen answer.
Set full screen this way,
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
android.widget.LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) videoView.getLayoutParams();
params.width = metrics.widthPixels;
params.height = metrics.heightPixels;
params.leftMargin = 0;
videoView.setLayoutParams(params);
And back to original size, this way.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
android.widget.LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) videoView.getLayoutParams();
params.width = (int)(300*metrics.density);
params.height = (int)(250*metrics.density);
params.leftMargin = 30;
videoView.setLayoutParams(params);
I have done this way:
Check these reference screen shots.
Add class FullScreenVideoView.java:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;
public class FullScreenVideoView extends VideoView {
public FullScreenVideoView(Context context) {
super(context);
}
public FullScreenVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FullScreenVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
How to bind with xml:
<FrameLayout
android:id="#+id/secondMedia"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.my.package.customview.FullScreenVideoView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fullScreenVideoView"/>
</FrameLayout>
Hope this will help you.
First Method
when you want to open a video in full screen for that Activity you have to set the theme attribute in the Manifest. set this value that is
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
change theme programmatically here
Second Method
create another fullscreen.xml like below and setContentView(R.layout.fullscreen) on click of the button
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<VideoView android:id="#+id/myvideoview"
android:layout_width="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="fill_parent">
</VideoView>
</RelativeLayout>
On Button click start the native video player which will open in full screen:
Intent intent = new Intent(Intent.ACTION_VIEW );
intent.setDataAndType(Uri.parse(path), "video/*");
startActivity(intent);
The below code worked.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
Add this code before calling videoView.start(). With this the video activity runs in full screen mode in most of the cases. But if the title bar is still displayed then change your theme in your manifest to this.
android:theme="#style/Theme.AppCompat.NoActionBar">
you can achieve it by creating two separate activity.
Suppose first activity is halfScreen activity. In this activity your video view having small size. On button click of full screen video start another activity 'fullScreen activity'. In second activity the video view should be match parent to the parent layout.you can also start video in full screen from where it is paused in half screen.In my code i have implemented that.Also you can resume the video in half screen on the back press of fullscreen activity.
This is work for me.Hope it will work for you also.
Here is the code
half.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#aa99cc"
android:orientation="vertical" >
<VideoView
android:id="#+id/VideoViewhalf"
android:layout_width="match_parent"
android:layout_height="300dp" >
</VideoView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/btnfullScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fullscreen" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
HalfScreen activity
public class HalfScreen extends Activity {
Button btn;
VideoView videoView = null;
final int REQUEST_CODE = 5000;
final String videoToPlay = "http://bffmedia.com/bigbunny.mp4";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.half);
videoView = (VideoView) findViewById(R.id.VideoViewhalf);
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
btn = (Button) findViewById(R.id.btnfullScreen);
Uri video = Uri.parse(videoToPlay);
videoView.setVideoURI(video);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
progressBar.setVisibility(View.GONE);
videoView.requestFocus();
videoView.start();
}
});
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent videointent = new Intent(HalfScreen.this,
FullScreen.class);
videointent.putExtra("currenttime",
videoView.getCurrentPosition());
videointent.putExtra("Url", videoToPlay);
startActivityForResult(videointent, REQUEST_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("currenttime")) {
int result = data.getExtras().getInt("currenttime", 0);
if (result > 0) {
if (null != videoView) {
videoView.start();
videoView.seekTo(result);
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
}
}
}
}
}
}
full.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff99cc"
android:orientation="vertical" >
<VideoView
android:id="#+id/VideoViewfull"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</VideoView>
</LinearLayout>
FullScreen Activity
public class FullScreen extends Activity {
Button btn;
VideoView videoView = null;
int currenttime = 0;
String Url = "";
private static ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (null != extras) {
currenttime = extras.getInt("currenttime", 0);
Url = extras.getString("Url");
}
setContentView(R.layout.full);
progressDialog = ProgressDialog.show(this, "", "Loading...", true);
videoView = (VideoView) findViewById(R.id.VideoViewfull);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
Uri video = Uri.parse(Url);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer arg0) {
progressDialog.dismiss();
videoView.start();
videoView.seekTo(currenttime);
}
});
}
#Override
public void finish() {
Intent data = new Intent();
data.putExtra("currenttime", videoView.getCurrentPosition());
setResult(RESULT_OK, data);
super.finish();
}
}
I achieved it by switching to landscape orientation and setting layout params to MATCH_PARENT. Just before switching to fullscreen mode, we need to store current orientation mode and VideoView params indefaultScreenOrientationMode and defaultVideoViewParams variables correspondingly. So that we can use them when we exit from video fullscreen mode. Thus, when you want to open video in fullscreen mode, use makeVideoFullScreen() method, to exit - exitVideoFullScreen().
Please, note I used RelativeLayout for my VideoView, in your case it can be another layout type.
private RelativeLayout.LayoutParams defaultVideoViewParams;
private int defaultScreenOrientationMode;
// play video in fullscreen mode
private void makeVideoFullScreen() {
defaultScreenOrientationMode = getResources().getConfiguration().orientation;
defaultVideoViewParams = (LayoutParams) videoView.getLayoutParams();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
videoView.postDelayed(new Runnable() {
#Override
public void run() {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
videoView.setLayoutParams(params);
videoView.layout(10, 10, 10, 10);
}
}, 700);
}
// close fullscreen mode
private void exitVideoFullScreen() {
setRequestedOrientation(defaultScreenOrientationMode);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
videoView.postDelayed(new Runnable() {
#Override
public void run() {
videoView.setLayoutParams(defaultVideoViewParams);
videoView.layout(10, 10, 10, 10);
}
}, 700);
}
whether you want to keep the aspect ratio of a video or stretch it to fill its parent area, using the right layout manager can get the job done.
Keep the aspect ratio :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView
android:id="#+id/videoView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"/>
</LinearLayout>
!!! To fill in the field:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView android:id="#+id/videoViewRelative"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</VideoView>
</RelativeLayout>
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
android.widget.LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) mVideoView.getLayoutParams();
params.width = (int) metrics.widthPixels;
params.height = (int) metrics.heightPixels;
mVideoView.setLayoutParams(params);
playVideo();
aspectRatio = VideoInfo.AR_4_3_FIT_PARENT;
mVideoView.getPlayer().aspectRatio(aspectRatio);
Try code below here.
if (!isFullScreen())
{
Log.v("Full screen", "-----------is full screen------------");
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height=height;
params.setMargins(0, 0, 0, 0);
}
else{
Log.v("Full screen", "-----------small screen------------");
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height=height / 3;
params.setMargins(0, 0, 0, 0);
}
This code is for full screen landscape video
AndroidManifext.xml (Setting the orientation)
<activity
android:name=".Video1"
android:screenOrientation="landscape" />
Video1.java Code :
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager;
import android.widget.MediaController;
import android.widget.VideoView;
public class Video1 extends AppCompatActivity {
private VideoView videoView;
private MediaController mediaController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video1);
videoView = findViewById(R.id.videoView);
String fullScreen = getIntent().getStringExtra("fullScreenInd");
if("y".equals(fullScreen)){
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide();
}
Uri videoUri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.YOUR_VIDEO_NAME);
videoView.setVideoURI(videoUri);
mediaController = new FullScreenMediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.start();
}
}
FullScreenMediaControler.java Code :
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.MediaController;
public class FullScreenMediaController extends MediaController {
private ImageButton fullScreen;
private String isFullScreen;
public FullScreenMediaController(Context context) {
super(context);
}
#Override
public void setAnchorView(View view) {
super.setAnchorView(view);
//image button for full screen to be added to media controller
fullScreen = new ImageButton (super.getContext());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
params.rightMargin = 80;
addView(fullScreen, params);
//fullscreen indicator from intent
isFullScreen = ((Activity)getContext()).getIntent().
getStringExtra("fullScreenInd");
if("y".equals(isFullScreen)){
fullScreen.setImageResource(R.drawable.ic_fullscreen_exit);
}else{
fullScreen.setImageResource(R.drawable.ic_fullscreen);
}
//add listener to image button to handle full screen and exit full screen events
fullScreen.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(),Video1.class);
if("y".equals(isFullScreen)){
intent.putExtra("fullScreenInd", "");
}else{
intent.putExtra("fullScreenInd", "y");
}
((Activity)getContext()).startActivity(intent);
}
});
}
}
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".auth.fragments.SplashScreenFragment">
<VideoView
android:id="#+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Android onClick only works once

So I'm realy confused
I am having a View(R.layout.main) which includes a custom view (canvas)
this View contains a button which is overlayed over the canvas
but when I click the button the OnClicklistener fires the event but after that button is doing nothing when clicked
Activity :
public class RunActivity extends Activity implements OnTouchListener, OnClickListener {
static int width;
static int height;
static boolean reset=false;
//draw d;
View d;
Button jump_button;
//jump
float last_touchpos=0;
static boolean jump=false;
private static Context mContext;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//d = new draw(this);
d = getLayoutInflater().inflate(R.layout.main, null);
d.setOnTouchListener(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mContext = this;
//get screen size
WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
width = display.getWidth(); // deprecated
height = display.getHeight(); // deprecated
setContentView(d);
jump_button = (Button) findViewById(R.id.jump);
jump_button.setOnClickListener(this);
}
public static Context getContext(){
return mContext;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("touch","touched");
if (draw.end == true)
{
reset=true;
}
else
{
if(last_touchpos != 0)
{
if(last_touchpos < event.getY())
{
jump = true;
last_touchpos = 0;
}
}
else
{
last_touchpos = event.getY();
}
}
return false;
}
#Override
public void onClick(View arg0) {
jump = true;
}
}
Layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<run.alexander.fuchs.draw
android:id="#+id/canvasview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/jump"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Jump" />
</RelativeLayout>
static boolean jump=false;
remove static from this statement
boolean jump=false;
How can you sure your onClick is called once. Use a log print message within onClick method to make sure that it is called once. Your code is okay, and I hope your onClick works properly and check your rest of code.

Implementing a slider (SeekBar) in Android

I want to implement a slider, which is basically two lines, one vertical and one horizontal, crossing where the screen is touched. I have managed to make one but I have to issues:
The slider is not very smooth, there is a slight delay when I'm moving the finger
If I place two sliders it is not multitouch, and I'd like to use both of them simultaneously
Here is the code:
public class Slider extends View {
private Controller controller = new Controller();
private boolean initialisedSlider;
private int sliderWidth, sliderHeight;
private Point pointStart;
private Paint white;
private int mode;
final static int VERTICAL = 0, HORIZONTAL = 1, BOTH = 2;
public Slider(Context context) {
super(context);
setFocusable(true);
// TODO Auto-generated constructor stub
}
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
pointStart = new Point();
initialisedSlider = false;
mode = Slider.BOTH;
}
#Override
protected void onDraw(Canvas canvas) {
if(!initialisedSlider) {
initialisedSlider = true;
sliderWidth = getMeasuredWidth();
sliderHeight = getMeasuredHeight();
pointStart.x = (int)(sliderWidth/2.0);
pointStart.y = (int)(sliderHeight/2.0);
controller = new Controller(pointStart, 3);
white = new Paint();
white.setColor(0xFFFFFFFF);
}
canvas.drawLine(controller.getCoordX(),0,
controller.getCoordX(),sliderHeight,
white);
canvas.drawLine(0, controller.getCoordY(),
sliderWidth, controller.getCoordY(),
white);
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_MOVE:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_UP:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
}
invalidate();
return true;
}
private boolean isInBounds(int x, int y) {
return ((x<=(sliderWidth)) && (x>=(0))
&& (y<=(sliderHeight)) && (y>=(0)));
}
private void updateController(int x, int y) {
switch(mode) {
case Slider.HORIZONTAL:
controller.setCoordX(x);
break;
case Slider.VERTICAL:
controller.setCoordY(y);
break;
case Slider.BOTH:
controller.setCoordX(x);
controller.setCoordY(y);
break;
}
}
private class Controller {
private int coordX, coordY;
Controller() {
}
Controller(Point point, int width) {
setCoordX(point.x);
setCoordY(point.y);
}
public void setCoordX(int coordX) {
this.coordX = coordX;
}
public int getCoordX() {
return coordX;
}
public void setCoordY(int coordY) {
this.coordY = coordY;
}
public int getCoordY() {
return coordY;
}
}
}
And the XML file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
</LinearLayout>
How to implement a SeekBar
Add the SeekBar to your layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seekBar"
android:max="100"
android:progress="50"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Notes
max is the highest value that the seek bar can go to. The default is 100. The minimum is 0. The xml min value is only available from API 26, but you can just programmatically convert the 0-100 range to whatever you need for earlier versions.
progress is the initial position of the slider dot (called a "thumb").
For a vertical SeekBar use android:rotation="270".
Listen for changes in code
public class MainActivity extends AppCompatActivity {
TextView tvProgressLabel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// set a change listener on the SeekBar
SeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
int progress = seekBar.getProgress();
tvProgressLabel = findViewById(R.id.textView);
tvProgressLabel.setText("Progress: " + progress);
}
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// updated continuously as the user slides the thumb
tvProgressLabel.setText("Progress: " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// called when the user first touches the SeekBar
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// called after the user finishes moving the SeekBar
}
};
}
Notes
If you don't need to do any updates while the user is moving the seekbar, then you can just update the UI in onStopTrackingTouch.
See also
SeekBar Tutorial With Example In Android Studio
Android provides slider which is horizontal
http://developer.android.com/reference/android/widget/SeekBar.html
and implement OnSeekBarChangeListener
http://developer.android.com/reference/android/widget/SeekBar.OnSeekBarChangeListener.html
If you want vertical Seekbar then follow this link
http://hoodaandroid.blogspot.in/2012/10/vertical-seek-bar-or-slider-in-android.html
For future readers!
Starting from material components android 1.2.0-alpha01, you have slider component
ex:
<com.google.android.material.slider.Slider
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="20f"
android:valueTo="70f"
android:stepSize="10" />
Release notes
Material Design Spec
Docs

Categories

Resources