VideoView的转屏处理技巧

本文介绍了一种在Android应用中实现视频随屏幕旋转而全屏显示的方法。通过自定义VideoView的位置和尺寸,确保了视频在不同屏幕方向下都能全屏播放。文章详细讲解了布局文件的设计、Activity配置及关键代码实现。

当我们观看视频时,往往喜欢切换到横屏模式,那当屏幕旋转时,如何使视频全屏显示?效果如下:

这里写图片描述

要实现上述功能,需要告诉系统,转屏操作的处理过程由我们自己来完成。当屏幕旋转后,我们会更改VideoView的大小和位置。

首先,为Activity创建布局文件,XML文件如下:

<?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:background="@android:color/black">

    <LinearLayout
        android:id="@+id/main_portrait_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <ScrollView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1">

                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:text="@string/par_01"
                    android:textColor="@android:color/white"/>
            </ScrollView>

            <View
                android:id="@+id/main_portrait_position"
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_margin="2dp"
                android:layout_weight="1"
                android:background="#ffffff"/>

        </LinearLayout>

        <View
            android:layout_width="fill_parent"
            android:layout_height="2dp"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:background="#ffffff"/>

        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_marginTop="2dp"
            android:layout_weight="3">

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:text="@string/par_02"
                android:textColor="@android:color/white"/>

        </ScrollView>

    </LinearLayout>

    <VideoView
        android:id="@+id/main_videoview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone"/>

</RelativeLayout>

布局文件效果图如下:

这里写图片描述

在上述XML文件中,布局文件由上下两部分组成,并以一条横线分割这两部分。上面的部分左侧显示一个稍小的文本,右侧显示一个视频;下面的部分显示一长段描述信息。当创建显示视频的视图时,我们并没用使用VideoView控件,而是一个白色背景的控件代替。我们会使用这个控件的大小和位置来正确设置VideoView控件的位置。

在上述布局文件中,VideoView控件直接挂在根视图下,并且与ID为main_portrait_content的LinearLayout控件处于相同的层级,将VideoView控件放在这个位置的用意是:在屏幕旋转时,既不需要创建两个不同的布局,也不需要修改VideoView的父视图就可以更改VideoView的大小和位置。另外,那个白色背景的视图则被命名为main_portrait_position。

然后,要让Activity能够处理转屏操作,需要在AndroidManifest.xml文件中相应的Activity标签中添加android:configChanges=”orientation”属性。配置该属性后,当屏幕旋转时,系统不会重启Activity,而是调用该Activity的onConfigurationChanged()方法。

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

最后,实现相应的Activity类。

package com.example.huangfei.hack1;

import android.app.Activity;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.VideoView;

public class MainActivity extends Activity {

    private VideoView mVideoView;
    private View mPortraitPosition;
    private View mPortraitContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPortraitPosition = findViewById(R.id.main_portrait_position);
        mPortraitContent = findViewById(R.id.main_portrait_content);
        mVideoView = (VideoView) findViewById(R.id.main_videoview);
        mVideoView.setVisibility(View.VISIBLE);

        //使用post是由于会使用mPortraitPosition的宽高信息
        mVideoView.post(new Runnable() {
            @Override
            public void run() {
                initVideoView();
            }
        });
    }

    private void initVideoView() {
        mVideoView.setMediaController(new MediaController(this));
        Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bigbuck);
        mVideoView.setVideoURI(uri);
        setVideoViewPosition();
        mVideoView.start();
    }

    /**
     * 改变视频的大小和位置
     */
    private void setVideoViewPosition() {
        //判断当前横竖屏配置
        switch (getResources().getConfiguration().orientation) {
            case Configuration.ORIENTATION_LANDSCAPE: {//横屏
                mPortraitContent.setVisibility(View.GONE);

                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
                params.addRule(RelativeLayout.CENTER_IN_PARENT);
                mVideoView.setLayoutParams(params);//设置VideoView的布局参数
                break;
            }
            default: {//竖屏
                mPortraitContent.setVisibility(View.VISIBLE);

                //获取白色背景的位置信息
                int[] locationArry = new int[2];
                mPortraitPosition.getLocationOnScreen(locationArry);

                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                        mPortraitPosition.getWidth(), mPortraitPosition.getHeight());
                params.leftMargin = locationArry[0];
                params.topMargin = locationArry[1];
                mVideoView.setLayoutParams(params);//设置VideoView的布局参数
                break;
            }
        }

    }

    /**
     * 屏幕方向改变时被调用
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        setVideoViewPosition();
        super.onConfigurationChanged(newConfig);
    }
}

运行程序,你会发现效果不错。最后还请注意一点:当视频大小改变时,默认的VideoView类会维持屏幕宽高比,如果你想让视频填充整个可用控件,就需要覆盖自定义视图中的onMeasure()方法。

代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值