introduce
Recently, I have to use the player to do a simple video playback function and start learning VideoView. I encountered some trouble when switching horizontal and vertical screens, but after checking the information, it finally solved it. When writing VideoView to play videos, the code that defines the control is written in Activity. After writing, I saw that the code was so messy, so I wrote a custom player control, which supports the specified size, can switch horizontally and vertically, and manually slide left and right to quickly forward and backward. OK, let's start now.
The renderings are a bit stuck, and I don't know why. . . . .
VideoView Introduction
This is the most important control for us to realize video playback. If you introduce it in detail, you can go to Baidu. Here are a few commonly used methods.
Used to play video files. The VideoView class can read images from different sources (such as resource files or content providers), calculate and maintain the video's picture size to suit any layout manager, and provides some display options such as scaling, shading, etc.
Several common methods for VideoView
public int getDuration ()
Get the total time of the video being played
public int getCurrentPosition ()
Get the current position, we can use it to set the display of playback time
public int getCurrentPosition ()
Get the current position, we can use it to set the display of playback time
public int pause ()
Pause playback
public int seekTo ()
Set the playback position, which we can use when we use it for the total fast forwarding.
public int setOnCompletionListener( l)
Register the callback function called when the media file is played.
public int setOnErrorListener ( l)
Register a callback function called when an error occurs during setup or playback. If the callback function is not specified, or the callback function returns false, a dialog will be popped and prompted that the user cannot play it
public void setOnPreparedListener ( l)
Register the callback function that can be called when the media file is loaded and can be played.
public void setVideoURI (Uri uri)
Set the video source to play, or use setVideoPath to specify the local file
public void start ()
Start playing
getHolder().setFixedSize(width,height);
Set the resolution of the VideoView. If our VideoView is on a vertical screen when it starts playing, and when it is on a horizontal screen, we need to reset its resolution by changing the layout size of the VideoView. Otherwise, you will find that the video part inside the VideoView is still the original size after changing. Pay attention to this point.
Custom player ideas
To be custom, it is actually nothing more than combining these VideoViews with other controls used to display, and then processing their event interactions internally. What we need to do is the following steps: 1. Write the layout of the entire space. 2. Get the small controls inside the entire control inside the custom control and set some initialization events for them. 3. Write your own event processing based on your own logic and the effect you want to achieve. If you need to interact with the outside, you can provide methods and interfaces. Finally, use the test effect. Okay, let’s follow the 4 steps mentioned here to achieve it!
Specific implementation
1. The first step is to write your own layout file
The desired effect is to place a status bar at the bottom to display time and other information, play progress, enter the full screen, and place a fast forward and rewind state in the middle. The layout code is as follows:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:andro android: android:layout_width="match_parent" android:layout_height="wrap_content" android:descendantFocusability="beforeDescendants"> < android: android:layout_width="match_parent" android:layout_height="match_parent"/> //Bottom Status Bar<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#CC282828" android:padding="3dip" android: android:gravity="center" android:layout_gravity="bottom"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android: android:paddingRight="10dip" android:paddingLeft="10dp"> <ImageView android:layout_width="22dp" android:layout_height="22dp" android: /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" android:paddingRight="0dip"> <SeekBar android:layout_width="fill_parent" android: android:layout_weight="1" style="@android:style/" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center" android:text="00:00" android:textSize="12dp" android: android:textColor="#FFF" /> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:textSize="12dp" android:textColor="#FFF" android:text="/"/> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center" android:text="00:00" android:textSize="12dp" android: android:textColor="#FFF" android:layout_marginRight="10dp" /> </LinearLayout> <LinearLayout android: android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center"> <ImageView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/iconfont_enter_32"/> </LinearLayout> </LinearLayout> //The start button and progress bar in the middle of VideoVIEW and the prompts for fast forwarding and rewinding<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android: style="@android:style/"/> <ImageView android:layout_width="30dip" android:layout_height="30dip" android: android:layout_gravity="center" android:src="@mipmap/video_box_play"/> <LinearLayout android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="center" android:visibility="invisible" android:paddingLeft="15dp" android:paddingRight="15dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:background="#000"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:/> <TextView android: android:layout_width="wrap_content" android:text="25:00/59:00" android:textSize="12sp" android:textColor="#fff" android:layout_height="wrap_content"/> </LinearLayout> </FrameLayout>
The above layout is very simple. VideoView uses customization because when the layout changes, you need to let the VideoView re-get the layout position and set its resolution to full screen. The code of VideoView is as follows
public class MyVideoView extends VideoView { public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyVideoView(Context context, AttributeSet attrs) { super(context, attrs); } public MyVideoView(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = getDefaultSize(0, widthMeasureSpec); int height = getDefaultSize(0, heightMeasureSpec); ().setFixedSize(width,height);//Set resolutionsetMeasuredDimension(width, height); } }
OK, after the layout is written, I will take the second step to get the internal control initialization event
2. The second step is to get the internal control in onFinishInflate() and do the initialization work
The onFinishInflate method will call back the method when the XML parses. It is generally used most often when making combination controls.
@Override protected void onFinishInflate() { (); initView(); } private void initView() { View view = (context).inflate(.common_video_view,null); viewBox = (FrameLayout) (); videoView = (MyVideoView) (); videoPauseBtn = (LinearLayout) (); screenSwitchBtn = (LinearLayout) (.screen_status_btn); videoControllerLayout = (LinearLayout) (); touchStatusView = (LinearLayout) (.touch_view); touchStatusImg = (ImageView) (); touchStatusTime = (TextView) (.touch_time); videoCurTimeText = (TextView) (); videoTotalTimeText = (TextView) (); videoSeekBar = (SeekBar) (); videoPlayImg = (ImageView) (); (GONE); videoPauseImg = (ImageView) (); progressBar = (ProgressBar) (); (this); (this); (this); (this); (this); (this); (this); //Register the callback function called when an error occurs during setup or playback. If the callback function is not specified, or the callback function returns false, VideoView will notify the user of an error.(this); (this); (this); addView(view); }
It is very simple to initialize the code and register the videoView playback event. The events here will be processed later. We need to write the effect of sliding left and right fast forward and fast reversing, (this); handle dragging seekbar fast forward and fast reversing.
3. The third step is event and effect processing
(this);
1. Fast forward and fast backward implementation in onTouch
@Override public boolean onTouch(View v, MotionEvent event) { switch (()){ case MotionEvent.ACTION_DOWN: //Not to deal with it when it is not playedif (!()){ return false; } float downX = (); touchLastX = downX; ("FilmDetailActivity", "downX" + downX); //Save the current playback location and display it with events = (); break; case MotionEvent.ACTION_MOVE: //Not to deal with it when it is not playedif (!()){ return false; } float currentX = (); float deltaX = currentX - touchLastX; float deltaXAbs = (deltaX); if (deltaXAbs>1){//Move forward, fast forwardif (()!=){ (); //Show fast forward time view} touchLastX = currentX; ("FilmDetailActivity","deltaX"+deltaX); if (deltaX > 1) { position += touchStep; if (position > duration) { position = duration; } touchPosition = position; (.ic_fast_forward_white_24dp); int[] time = getMinuteAndSecond(position); (("%02d:%02d/%s", time[0], time[1],formatTotalTime)); } else if (deltaX < -1) {//Retreat quicklyposition -= touchStep; if (position < 0) { position = 0; } touchPosition = position; (.ic_fast_rewind_white_24dp); int[] time = getMinuteAndSecond(position); (("%02d:%02d/%s", time[0], time[1],formatTotalTime)); //(position); } } break; case MotionEvent.ACTION_UP: if (touchPosition!=-1){ (touchPosition); // When you let go of your finger, fast forward or rewind to the time position determined by sliding ();touchPosition = -1; if (videoControllerShow){ return true; } } break; } return false; }
2. Handle the drag event of seekBar
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int[] time = getMinuteAndSecond(progress); (("%02d:%02d", time[0], time[1])); //Set the bottom time display} @Override public void onStartTrackingTouch(SeekBar seekBar) { (); } @Override public void onStopTrackingTouch(SeekBar seekBar) { (()); (); (); (.icon_video_pause); //Drag to the specified time position}
3. VideoView callback event
@Override public void onPrepared(MediaPlayer mp) { duration = (); int[] time = getMinuteAndSecond(duration); (("%02d:%02d", time[0], time[1])); formatTotalTime = ("%02d:%02d", time[0], time[1]); (duration); (); (); (true); (true); (.icon_video_pause); (timerTask, 0, 1000); //Some interface displays such as the total initialization time, and use timer to modify the time progress textView at the same time.} @Override public void onCompletion(MediaPlayer mp) { (0); (0); (.icon_video_play); (); }
There are also some other click time that will not be played, and they are all events such as pausing, playing, clicking to show hidden bottom status bar, switching full screen, etc. Here we have completed the process of the incident. How do we play the video next? To play we provide a method for external
//Start playbackpublic void start(String url){ (false); (false); ((url)); (); } //Called when entering full screenpublic void setFullScreen(){ (.iconfont_exit); (new (.MATCH_PARENT, .MATCH_PARENT)); (); } //Called when exiting full screenpublic void setNormalScreen(){ (.iconfont_enter_32); (new (.MATCH_PARENT,400)); (); }
The setFullScreen() and setNormalScreen() provided above need to be called in the callback method of the onConfigurationChanged(Configuration newConfig) horizontal and vertical screen of the Activity. It should also be noted that I am writing about LinearLayout's LayoutParams, so if the parent space of our custom view is LinearLayout, of course you can also modify it.
4. Use of controls
We just need to call the start method in the obtain space, and then call setFullScreen and setNormalScreen in the onConfigurationChanged method.
layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro xmlns:app="/apk/res-auto" xmlns:tools="/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=""> <. android: android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/"/> < android: android:layout_width="match_parent" android:layout_height="300dp" /> </LinearLayout>
activity code
public class MainActivity extends AppCompatActivity { CommonVideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.content_main); Toolbar toolbar = (Toolbar) findViewById(); setSupportActionBar(toolbar); videoView = (CommonVideoView) findViewById(.common_videoView); ("Your server video address"); } @Override public void onConfigurationChanged(Configuration newConfig) { (newConfig); if ( == Configuration.ORIENTATION_LANDSCAPE) { (); }else { (); } } }
Finally, in order to prevent your activity from being recreated when switching horizontally and vertically, don't forget to configure it in the file.
android:configChanges=”orientation|screenSize|screenLayout”, if you have any questions here, you can refer to my article->In-depth understanding of Activity-Life Cycle
<activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/" android:configChanges="orientation|screenSize|screenLayout"> <intent-filter> <action android:name="" /> <category android:name="" /> </intent-filter> </activity>
The above is the relevant knowledge about Android custom player control VideoView shared by the editor. I hope it will be helpful to everyone.