回答:
この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は、センサーやユーザーがロックした回転などに基づいて、通常のように動作します。それ以外のすべて(電話など)はポートレートのみになります。
xlarge
ますsw600dp
か、それとも使用できますか?最近、3.2未満を実行しているタブレットはおそらくないでしょう。
onCreate()
。通話をsetRequestedOrientation()
時間とコンテキストの別の位置に移動したところ、再起動が行われなくなりました。
この方法を試すと、まずデバイスの画面サイズを取得できます
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);
Configuration
提供しscreenLayout
ます-DPI。一方、質問は物理デバイスの画面サイズに関連しています-電話VSタブレット。つまり、Configuration.SCREENLAYOUT_SIZE_NORMAL
MDPIタブレットになります。
Android Studioで次の手順を実行して、res/values-sw600dp
およびres/values-large
ディレクトリとそれらのbools.xml
ファイルを追加できます。
まず、[プロジェクト]タブから、ナビゲーターで(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
ファイルを作成します。
ここに私がそれをした方法があります(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
}
私が理解できないように思える唯一のことは、横向きから縦向きに、またはその逆に切り替えるときに、アプリにレイアウトファイルを変更させる方法です。私は答えが上記のリンクと同じようなことをしていると思いますが、それを私のために働かせることができませんでした-それは私のデータをすべて削除しました。しかし、縦長と横長で同じレイアウトファイルを使用できる十分にシンプルなアプリがある場合、これは機能するはずです。
ジニーの答えに従って、私はそれを行う最も信頼できる方法は次のとおりだと思います:
ここで説明するように、ブール値をリソース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のそれぞれにBaseActivity
行android:configChanges="orientation|screenSize"
を追加する必要がありActivity
ます。
<activity
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
まあ、これは少し遅いですが、ここではXMLのみですが、setRequestedOrientation
向きを変更する必要がある場合のようにアクティビティを再作成しないハッキングソリューションを示します。
受け入れられた回答に続いて、私はkotlinファイルをソリューションとともに追加しています
このboolリソースres/values
をbools.xmlまたは何としてでも入れます(ファイル名はここでは関係ありません)。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
この1を入れてres/values-sw600dp
とres/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)
}
}
他の解決策ではうまくいきませんでした。ダイアログとレクリエーションの問題で、まだ奇妙なオリエンテーションの問題がありました。私の解決策は、アクティビティを拡張し、マニフェストでポートレートとして強制することでした。
例:
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);
古い質問です。(タブレットなどで)向きが入れ替わったり、入れ替わったりする場合でも、常にアプリを縦向きモードで実行するために、縦向きと横向きを知らなくても、デバイスを正しい向きに設定するために使用するこの機能を設計しました機能はデバイス上で整理されています。
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の提案は最良のトレードオフですが、再起動アクティビティの問題に注意してください。
layout-land
内を使用する場合のように、電話の横長のレイアウトを設計しないことres
です。