当前位置: 首页 > 知识库问答 >
问题:

在Android中改变方向时布局中断

马博学
2023-03-14

我正在开发一个应用程序来显示一个频道的直播流,它在默认情况下以景观模式启动,我可以从我的选项菜单中将它改为肖像,反之亦然

现在我在manifest中使用这段代码,并将其放在活动android:configchanges=“keyboardkeyboardhiddenorientationscreensize”

当我启动应用程序,它的工作很好,但当我改变方向为肖像,应用程序是悬挂和选项菜单没有消失,像往常一样。

如果我从清单中删除了screensize部分,它可以正常工作,但layout-land不起作用,在两个方向上都使用了纵向布局。

package com.shadatv.shada;

import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;

import android.view.Menu;
import android.view.MenuItem;

import android.view.WindowManager;

import android.widget.VideoView;

public class LiveActivity extends Activity {
    VideoView videoView;

    private AlertDialog.Builder errorDialog;
    String httpLiveUrl = "http://38.96.148.147:1935/live/livestream/playlist.m3u8";

    // =============================================================================

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
        setContentView(R.layout.live);
        try {
            videoView = (VideoView) findViewById(R.id.myVideoView);
            videoView.setVideoURI(Uri.parse(httpLiveUrl));
            videoView.requestFocus();

            videoView
                    .setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            // TODO Auto-generated method stub

                            videoView.seekTo(1000);
                            videoView.start();

                        }
                    });

        } catch (Exception e) {
            errorDialog = new AlertDialog.Builder(this);
            errorDialog.setMessage("مشكلة في البث");
            errorDialog.setCancelable(true);
            errorDialog.setNeutralButton("Ok",
                    new DialogInterface.OnClickListener() {
                        // click listener on the alert box
                        public void onClick(DialogInterface arg0, int arg1) {

                        }
                    });
            AlertDialog errorStream = errorDialog.create();
            errorStream.show();
        }
    }

    // =============================================================================

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.activity_shada, menu);
        MenuItem fullItem = menu.findItem(R.id.fullScreen);
        MenuItem smallItem = menu.findItem(R.id.smallScreen);

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            fullItem.setVisible(false);
            smallItem.setVisible(true);
        } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            smallItem.setVisible(false);
            fullItem.setVisible(true);
        }
        return super.onPrepareOptionsMenu(menu);
    }

    // =============================================================================

    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
            // setContentView(R.layout.activity_shada);
        } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            // setContentView(R.layout.activity_shada1);
        }
    }

    // =============================================================================

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.about: {
            // TODO Auto-generated method stub
            startActivity(new Intent("com.shadatv.MainActivity"));
        }
            break;

        case R.id.smallScreen: {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
            break;

        case R.id.fullScreen: {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
            break;
        }
        return true;
    }

}

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shadatv.shada"
    android:versionCode="3"
    android:versionName="1.0.2" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/shada"
        android:label="@string/app_name"

        >       
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity
            android:name=".LiveActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:exported="false"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

            <intent-filter>
                <action android:name="com.shadatv.LiveActivity" />

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


</manifest>

共有1个答案

呼延聪
2023-03-14

我通过从oncreate中取出setcontentviewtry/catch块并将其放在onconfigchange来解决这个问题

package com.shadatv.shada;

import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;

import android.view.Menu;
import android.view.MenuItem;

import android.view.WindowManager;

import android.widget.VideoView;

public class LiveActivity extends Activity {
    VideoView videoView;

    private AlertDialog.Builder errorDialog;
    String httpLiveUrl = "http://38.96.148.147:1935/live/livestream/playlist.m3u8";

    // =============================================================================

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        // if (getResources().getConfiguration().orientation ==
        // Configuration.ORIENTATION_LANDSCAPE) {
        // getWindow().clearFlags(
        // WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        // WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // }
        // setContentView(R.layout.live);

    }

    // =============================================================================

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.activity_shada, menu);
        MenuItem fullItem = menu.findItem(R.id.fullScreen);
        MenuItem smallItem = menu.findItem(R.id.smallScreen);

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            fullItem.setVisible(false);
            smallItem.setVisible(true);
        } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            smallItem.setVisible(false);
            fullItem.setVisible(true);
        }
        return super.onPrepareOptionsMenu(menu);
    }

    // =============================================================================

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.live);
        try {
            videoView = (VideoView) findViewById(R.id.myVideoView);
            videoView.setVideoURI(Uri.parse(httpLiveUrl));
            videoView.requestFocus();

            videoView
                    .setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            // TODO Auto-generated method stub

                            videoView.seekTo(1000);
                            videoView.start();

                        }
                    });

        } catch (Exception e) {
            errorDialog = new AlertDialog.Builder(this);
            errorDialog.setMessage("مشكلة في البث");
            errorDialog.setCancelable(true);
            errorDialog.setNeutralButton("Ok",
                    new DialogInterface.OnClickListener() {
                        // click listener on the alert box
                        public void onClick(DialogInterface arg0, int arg1) {

                        }
                    });
            AlertDialog errorStream = errorDialog.create();
            errorStream.show();
        }

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);    
        } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }
    }

    // =============================================================================

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.about:
            // TODO Auto-generated method stub
            startActivity(new Intent("com.shadatv.MainActivity"));
            break;

        case R.id.smallScreen:
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            break;

        case R.id.fullScreen:
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            break;
        }
        return true;
    }

}

但我在OptionsMenu发现了另一个问题。当我按下about按钮退出此活动并运行MainActivity时,应用程序停止。怎么啦?

 类似资料:
  • 请看附件中的图片。我正在使用支持工具栏,并将其设置为支持actionbar。但工具栏内部的Textview并没有全宽(如布局边界所示)。因此,我无法将其水平居中。请帮忙。 app_barXML: 片段: 在play store中,我看到了居中的视图:

  • 我试过configChanges,但显然它没有改变我的布局。我试着在onConfigurationChanged的FrameLayout容器中填充肖像和景观布局并替换它们,但似乎也不起作用。 如何处理需要加载不同布局同时保持片段状态不变的情况?这有可能吗?对于这种事情,正确的做法是什么?

  • 我如何在配置更改时保留这个列表?我已经寻找了许多解决方案,但许多人建议在manifest中使用'Android:ConfigChanges',我完全反对使用。许多人建议,我也读到过--在Fragment中使用setRetaInstance(true)来保留这个片段。 我尝试实现它,但我失败了。许多教程在方向改变后使用findFragmentByTag检查片段,但在我的情况下,它总是返回null。有

  • 我有一个问题,正确的对话片段删除后,方向被改变。我想这是由于旧的上下文,因为在该活动被重新创建后,会创建一个新的活动和相应的上下文。我知道我可以在onSaveInstance中设置一些变量来保存对话框状态,如果必要的话重新创建对话框,或者只在清单“定向”中放置一个属性。但是,也许有更好的方法来做到这一点,不在manifest中硬编码,也不在onSaveIntance中手动保存?我还尝试在main片

  • 我是JavaFX的新手!!我试了一个非常非常简单的代码,结果卡住了。当我试图添加一个按钮到布局,它不工作。我知道这个问题可能太简单,但我真的不知道如何解决。如果你能帮助我,我将不胜感激。这是我的代码: 我得到了一个错误:

  • 所以我很确定这应该是一个快速简单的解决方案,但我似乎不明白。我试图改变我的GridView基于设备方向的布局,所有在Xaml。例如: 水平(水平滚动) item1 item2 item3 item4 item5 item6 垂直(垂直滚动) item1 item2 item3 item4 item5 item6