Android:タブレットでは縦向きと横向きを許可しますが、スマートフォンでは強制的に縦向きにしますか?


191

タブレットを縦向きと横向き(sw600dp以上)で表示できるようにしたいのですが、電話は縦向きのみに制限されています。条件付きで向きを選択する方法が見つかりません。助言がありますか?


1つの方法は、フォルダlayout-land内を使用する場合のように、電話の横長のレイアウトを設計しないことresです。
ゴースト

12
これにより、縦向きのレイアウトのみが横向きに表示されます。スマートフォンが横向きになるのを妨げることはありません。
ラドリー2013

回答:


446

リソースサイズ修飾子を使用する良い方法は次のとおりです。

このboolリソースをres / valuesにbools.xmlまたは何でも入れます(ファイル名はここでは関係ありません)。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <bool name="portrait_only">true</bool>
    </resources>

これをres / values-sw600dpおよびres / values-xlargeに入れます。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <bool name="portrait_only">false</bool>
    </resources>

Android Studioでこれらのディレクトリとファイルを追加する方法については、この補足回答をご覧ください。

次に、アクティビティのonCreateメソッドでこれを行うことができます。

    if(getResources().getBoolean(R.bool.portrait_only)){
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

最小の幅方向が600 dpを超えるデバイス、またはAndroid 3.2より前のデバイス(基本的にはタブレット)のx-largeは、センサーやユーザーがロックした回転など基づいて、通常のように動作します。それ以外のすべて(電話など)はポートレートのみになります。


1
私も使用する必要がありxlargeますsw600dpか、それとも使用できますか?最近、3.2未満を実行しているタブレットはおそらくないでしょう。
theblang 2014年

7
まあ、これはランドスケープで開始されるとアクティビティを再開する可能性があります
。developer.android.com/ reference / android / app /…を

1
@Bondaxそのコメントは「アクティビティが現在フォアグラウンドにあるか、それ以外の場合は画面の向きに影響を与える場合」にのみ適用されます。この時点ではonCreateにいるため、これは当てはまりません。
ブライアンクリステンセン

1
@BrianChristensenリクエストされた向きをで設定したときにアクティビティの再開を観察しましたonCreate()。通話をsetRequestedOrientation()時間とコンテキストの別の位置に移動したところ、再起動が行われなくなりました。
Bondax

8
アプリを横向きモードで起動しても、しばらくの間横向きモードが表示されます。
最白目

29

この方法を試すと、まずデバイスの画面サイズを取得できます

if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {     
    Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show();

}
else if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {     
    Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show();

} 
else if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {     
    Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show();
}
else {
    Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show();
}

それに従って方向を設定します

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

4
setRequestedOrientation()メソッドはどのメソッドに配置する必要がありますか?onCreateが開始されると、必要な方向がすでに選択されています。
ケニーワイランド

私はそれはあなたが役立つかもしれないと思うこれをチェックケニーstackoverflow.com/questions/2833474/...
アビ・クマールManku

この回答は賛成されたと思いますが、問題が解決するかどうかはわかりません。情報をConfiguration提供しscreenLayoutます-DPI。一方、質問は物理デバイスの画面サイズに関連しています-電話VSタブレット。つまり、Configuration.SCREENLAYOUT_SIZE_NORMALMDPIタブレットになります。
2016年


10

受け入れられた回答の補足

Android Studioで次の手順を実行して、res/values-sw600dpおよびres/values-largeディレクトリとそれらのbools.xmlファイルを追加できます。

values-sw600dp

まず、[プロジェクト]タブから、ナビゲーターで(Androidではなく)プロジェクトフィルターを選択します。

ここに画像の説明を入力してください

次に、app/src/main/resディレクトリを右クリックします。[ New] > [ Android Resource Directory]を選択します。

[ 最小画面幅]を選択し、>>ボタンを押します。

ここに画像の説明を入力してください

入力し600、最小画面幅のために。ディレクトリ名は自動的に生成されます。大丈夫。

ここに画像の説明を入力してください

次に、新しく作成したvalues-sw600dpファイルを右クリックします。[ New] > [ Values resource file]を選択しますbools名前を入力します。

値が大きい

values-largeディレクトリの追加は、Android 3.2(APIレベル13)以前をサポートしている場合にのみ必要です。それ以外の場合は、このステップをスキップできます。values-largeディレクトリがに対応しますvalues-sw600dp。(にvalues-xlarge対応しvalues-sw720dpます。)

values-largeディレクトリを作成するには、上記と同じ手順に従いますが、この場合は最小画面幅ではなくサイズを選択します。大を選択します。ディレクトリ名は自動的に生成されます。

ここに画像の説明を入力してください

以前と同じようにディレクトリを右クリックして、bools.xmlファイルを作成します。


2
これが機能しない場合はお知らせください。修正します。それは私のために働いた。私は1つの反対票を獲得しましたが、コメントがなかったため、何を修正すべきかわかりません。
Suragch 2016

9

ここに私がそれをした方法があります(http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.htmlに触発された):

AndroidManifest.xmlで、縦向きと横向きの間で変更できるようにするアクティビティごとに(必ずscreenSizeを追加してください-これは必要ありませんでした!)ここで画面の向きを設定する必要はありません。:

android:configChanges="keyboardHidden|orientation|screenSize"

各アクティビティに追加する方法:

public static boolean isXLargeScreen(Context context) {
    return (context.getResources().getConfiguration().screenLayout
    & Configuration.SCREENLAYOUT_SIZE_MASK)
    >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
} 

and:(このメソッドをオーバーライドしない場合、方向を変更するときにアプリがonCreate()を呼び出します)

@Override
public void onConfigurationChanged (Configuration newConfig)
{       
    super.onConfigurationChanged(newConfig);

    if (!isXLargeScreen(getApplicationContext()) ) {            
        return; //keep in portrait mode if a phone      
    }

    //I set background images for landscape and portrait here
}

各アクティビティのonCreate()で:

if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait; 
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);            
}
else {
  //I set background images here depending on portrait or landscape orientation 
}

私が理解できないように思える唯一のことは、横向きから縦向きに、またはその逆に切り替えるときに、アプリにレイアウトファイルを変更させる方法です。私は答えが上記のリンクと同じようなことをしていると思いますが、それを私のために働かせることができませんでした-それは私のデータをすべて削除しました。しかし、縦長と横長で同じレイアウトファイルを使用できる十分にシンプルなアプリがある場合、これは機能するはずです。


2
横向きのレイアウトをlayout-landフォルダーに配置します
radley

super onConfigurationChanged
RominaV

8

ジニーの答えに従って、私はそれを行う最も信頼できる方法は次のとおりだと思います:

ここで説明するように、ブール値をリソースsw600dpに配置します。接頭辞swが必要です。そうしないと、正しく機能しません。

res / values-sw600dp / dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isTablet">true</bool>
</resources>

res / values / dimens.xml内

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isTablet">false</bool>
</resources>

次に、そのブール値を取得するメソッドを作成します。

public class ViewUtils {
    public static boolean isTablet(Context context){
        return context.getResources().getBoolean(R.bool.isTablet);
    }
}

そして、この動作が必要なアクティビティから拡張する基本アクティビティ:

public abstract class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!ViewUtils.isTablet(this)) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
    }
}

したがって、各アクティビティはBaseActivityを拡張します。

public class LoginActivity extends BaseActivity //....

重要:から拡張する場合でも、AndroidManifest.xmlのそれぞれにBaseActivityandroid:configChanges="orientation|screenSize"を追加する必要がありActivityます。

    <activity
        android:name=".login.LoginActivity"
        android:configChanges="orientation|screenSize">
    </activity>

5

まあ、これは少し遅いですが、ここではXMLのみですが、setRequestedOrientation向きを変更する必要がある場合のようにアクティビティを再作成しないハッキングソリューションを示します。

https://stackoverflow.com/a/27015879/1281930


1
機能しません。タブレットは常にスマートフォンの向きをとります。どうやらandroid:screenOrientationは、リソース修飾子が適用される前に、マニフェストのすべてのアクティビティに対して1回だけ設定されます。
0101100101 2017年

2

受け入れられた回答に続いて、私はkotlinファイルをソリューションとともに追加しています

このboolリソースres/valuesbools.xmlまたは何としてでも入れます(ファイル名はここでは関係ありません)。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">true</bool>
</resources>

この1を入れてres/values-sw600dpres/values-sw600dp-land

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">false</bool>
</resources>

次に、アクティビティまたはフラグメントの以下の行に追加します

class MyActivity : Activity() {

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        if (resources.getBoolean(R.bool.portrait_only)) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
        super.onCreate(savedInstanceState)
    }

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onConfigurationChanged(newConfig: Configuration) {
        if (resources.getBoolean(R.bool.portrait_only)) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
        super.onConfigurationChanged(newConfig)
    }
}

1

他の解決策ではうまくいきませんでした。ダイアログとレクリエーションの問題で、まだ奇妙なオリエンテーションの問題がありました。私の解決策は、アクティビティを拡張し、マニフェストでポートレートとして強制することでした。

例:

public class MainActivityPhone extends MainActivity {}

manifest.xml:

        <activity
        android:screenOrientation="portrait"
        android:name=".MainActivityPhone"
        android:theme="@style/AppTheme.NoActionBar" />

スプラッシュクリーン活動:

    Intent i = null;
    boolean isTablet = getResources().getBoolean(R.bool.is_tablet);
    if (!isTablet)
        i = new Intent(this, MainActivityPhone.class);
    else
        i = new Intent(this, MainActivity.class);
    startActivity(i);

0

古い質問です。(タブレットなどで)向きが入れ替わったり、入れ替わったりする場合でも、常にアプリを縦向きモードで実行するために、縦向きと横向きを知らなくても、デバイスを正しい向きに設定するために使用するこの機能を設計しました機能はデバイス上で整理されています。

   private void initActivityScreenOrientPortrait()
    {
        // Avoid screen rotations (use the manifests android:screenOrientation setting)
        // Set this to nosensor or potrait

        // Set window fullscreen
        this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        DisplayMetrics metrics = new DisplayMetrics();
        this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

         // Test if it is VISUAL in portrait mode by simply checking it's size
        boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels ); 

        if( !bIsVisualPortrait )
        { 
            // Swap the orientation to match the VISUAL portrait mode
            if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
             { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
            else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
        }
        else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }

    }

魅力的な作品!

注意:this.activityアクティビティごとに変更するか、メインアクティビティに追加して削除してくださいthis.activity;-)

逆のことをしたい場合は、コードを横向きに変更する必要があります(ただし、これを行う方法は明らかだと思います)。


0

残念ながら、メソッドsetRequestedOrientation(...)を使用するとアクティビティが再起動するため、onCreateメソッドでこれを呼び出しても、アクティビティのライフサイクルが実行され、リクエストされた方向で同じアクティビティが再作成されます。@Brian Christensenの回答では、アクティビティコードが2回呼び出される可能性があることを考慮する必要があります。これは悪影響を与える可能性があります(視覚的なものだけでなく、ネットワーク要求、分析などでも)。

さらに、マニフェストでconfigChanges属性を設定することは、私の見解では大きなトレードオフであり、リファクタリングに多大なコストがかかる可能性があります。Android開発者は、この属性を変更することを推奨していません

最後に、screenOrientationを何らかの方法で(再起動の問題を回避するために)設定しようとすることは不可能であり、静的マニフェストを変更できないため静的には不可能です。

概要:私の意見では、@ Brian Christensenの提案は最良のトレードオフですが、再起動アクティビティの問題に注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.