タブレットを縦向きと横向き(sw600dp以上)で表示できるようにしたいのですが、電話は縦向きのみに制限されます。オリエンテーションを条件付きで選択する方法が見つかりません。助言がありますか?
resources および size qualifiers を使用する良い方法があります。
このboolリソースを、bools.xmlまたは何でもres/valuesに入れます(ファイル名はここでは関係ありません):
<?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ラージのデバイスは、通常のように動作します センサーおよびユーザーロック回転などに基づいて 。他のすべて(電話、ほとんど)はポートレートのみになります。
この方法を試して、最初にデバイスの画面サイズを取得できます
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);
ここに私がそれをした方法があります( 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;
}
および:(このメソッドをオーバーライドしない場合、アプリは向きを変更するときに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
}
私が理解できないと思われる唯一のことは、横から縦に、またはその逆に切り替えるときに、アプリでレイアウトファイルを変更する方法です。私は答えが上記のリンクと同じようなことをしていると思いますが、私のためにそれを機能させることができませんでした-それはすべてのデータを削除しました。ただし、ポートレートとランドスケープで同じレイアウトファイルを使用できるほどシンプルなアプリがある場合は、これで機能するはずです。
Android Studioで次の手順を実行して、res/values-sw600dp
およびres/values-large
ディレクトリとそれらのbools.xml
ファイルを追加できます。
まず、[プロジェクト]タブから、ナビゲーターの[プロジェクト(Androidではなく)]フィルターを選択します。
次に、app/src/main/res
ディレクトリを右クリックします。 New>Android Resource Directoryを選択します。
Smallest Widthを選択し、>>ボタンを押します。
最小画面幅の600
を入力します。ディレクトリ名は自動的に生成されます。 OKと言ってください。
次に、新しく作成されたvalues-sw600dp
ファイルを右クリックします。 New>Valuesリソースファイルを選択します。名前にbools
と入力します。
values-large
ディレクトリの追加は、Android 3.2以前(APIレベル13)をサポートしている場合にのみ必要です。それ以外の場合は、この手順をスキップできます。 values-large
ディレクトリはvalues-sw600dp
に対応しています。 (values-xlarge
はvalues-sw720dp
に対応します。)
values-large
ディレクトリを作成するには、上記と同じ手順に従いますが、この場合、最小画面幅ではなくSizeを選択します。 Largeを選択します。ディレクトリ名は自動的に生成されます。
前と同じようにディレクトリを右クリックして、bools.xml
ファイルを作成します。
Ginny's answer に従って、最も信頼できる方法は次のとおりだと思います。
here で説明したように、リソース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 //....
重要:BaseActivity
から拡張する場合でも、_Android:configChanges="orientation|screenSize"
行を各Activity
に追加する必要がありますAndroidManifest.xml:
<activity
Android:name=".login.LoginActivity"
Android:configChanges="orientation|screenSize">
</activity>
さて、これは少し遅いですが、ここではXML-Onlyですが、アクティビティをsetRequestedOrientation
として再作成しないハックソリューションです向きを変更する必要がある場合:
他のソリューションは私にとってはうまくいきませんでした。私はまだダイアログとレクリエーションの問題で奇妙なオリエンテーションの問題を抱えていました。私の解決策は、アクティビティを拡張して、マニフェストのポートレートとして強制することでした。
例:
public class MainActivityPhone extends MainActivity {}
manifest.xml:
<activity
Android:screenOrientation="portrait"
Android:name=".MainActivityPhone"
Android:theme="@style/AppTheme.NoActionBar" />
splashcreenアクティビティで:
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);
私が知っている古い質問。 (タブレットなど)向きが入れ替わる場合でもアプリを常にポートレートモードで実行するために、ポートレートとランドスケープの方法を知らなくてもデバイスを正しい向きに設定するために使用されるこの機能を設計しました機能はデバイス上で整理されています。
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
を削除してください;-)
反対のことをしたい場合は、コードをランドスケープに変更する必要があります(ただし、これを行う方法は明確だと思います)。
残念ながら、メソッド setRequestedOrientation(...) を使用するとアクティビティが再起動されるため、onCreateメソッドでこれを呼び出してもアクティビティライフサイクルを経てから同じアクティビティが再作成されます要求された向きで。したがって、@ Brian Christensenの回答では、アクティビティコードが2回呼び出される可能性があることを考慮する必要があります(視覚的だけでなく、ネットワークリクエスト、分析などでも)悪影響が生じる可能性があります。
さらに、マニフェストでconfigChanges属性を設定することは、私の意見では大きなトレードオフであり、大きなリファクタリングコストがかかる可能性があります。 Androidデベロッパーはその属性を変更することを推奨していません 。
最後に、screenOrientationを何らかの方法で(再起動の問題を回避するために)設定しようとすることは不可能です。変更できない静的マニフェストのために静的に不可能です。
要約:私の意見では、@ Brian Christensenの提案は最良のトレードオフですが、アクティビティの再開の問題に注意してください。