답변:
다음은 resources 및 size 한정자를 사용하는 좋은 방법 입니다.
이 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);
}
최소 너비 방향으로 600dp 이상인 기기 또는 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
디렉토리를 마우스 오른쪽 단추로 클릭하십시오 . 새로 작성 > Android 자원 디렉토리를 선택하십시오 .
선택 작은 화면 폭을 한 후 누르 >> 버튼을 누릅니다.
입력 600
작은 화면 폭. 디렉토리 이름이 자동으로 생성됩니다. 네라고하세요.
그런 다음 새로 만든 values-sw600dp
파일을 마우스 오른쪽 버튼으로 클릭하십시오 . 새로 작성 > 값 자원 파일을 선택 하십시오 . 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;
}
및 : (이 방법을 재정의하지 않으면 방향을 변경할 때 앱이 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>
이것에 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의 답변에서 활동 코드가 두 번 호출 될 수 있다는 것을 고려해야합니다. 이는 시각적뿐만 아니라 네트워크 요청, 분석 등에 나쁜 영향을 줄 수 있습니다.
또한 매니페스트에서 configChanges 속성을 설정하는 것은 큰 절충점이며 막대한 리팩토링 비용이 발생할 수 있습니다. Android 개발자는 해당 속성을 변경하지 않는 것이 좋습니다 .
마지막으로 screenOrientation을 (다시 시작 문제를 피하기 위해) 다르게 설정하려고 시도하는 것은 불가능합니다. 변경 할 수없는 정적 매니페스트로 인해 정적으로 불가능합니다. 프로그래밍 방식으로 이미 시작된 활동에서 해당 메소드를 호출하는 것만 가능합니다.
요약 : @Brian Christensen 제안은 최선의 절충이지만 다시 시작하는 활동 문제를 알고 있어야합니다.
layout-land
내부res
폴더 를 사용할 때와 같이 전화의 가로 레이아웃을 디자인하지 않는 것 입니다.