Android : 태블릿에 세로 및 가로를 허용하지만 휴대 전화에서 세로를 강제로 설정 하시겠습니까?


191

태블릿을 세로 및 가로 (sw600dp 이상)로 표시하고 싶지만 휴대 전화는 세로로만 제한됩니다. 조건부로 방향을 선택할 수있는 방법을 찾을 수 없습니다. 어떤 제안?


한 가지 방법은 layout-land내부 res폴더 를 사용할 때와 같이 전화의 가로 레이아웃을 디자인하지 않는 것 입니다.
고스트

12
그러면 세로 레이아웃 만 가로로 표시됩니다. 실제로 전화가 가로로 회전하는 것을 막지는 않습니다.
radley

답변:


446

다음은 resourcessize 한정자를 사용하는 좋은 방법 입니다.

이 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 는 센서 및 사용자 잠금 회전 등에 따라 정상적으로 작동합니다 . 다른 모든 것 (전화, 거의)은 초상화 일뿐입니다.


1
나도 xlarge사용해야 sw600dp합니까 아니면 그냥 사용할 수 있습니까? 요즘에는 <3.2를 실행하는 태블릿이 없을 것입니다.
theblang 2016 년

7
글쎄, 이것은 조경에서 시작될 때 활동을 다시 시작할 가능성이있다. developer.android.com/reference/android/app/…
Bondax

1
@Bondax이 의견은 "활동이 현재 포 그라운드에 있거나 화면 방향에 영향을 미치는 경우"에만 적용되며,이 시점에서 onCreate 상태이기 때문에 해당되지 않습니다.
Brian Christensen

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가 시작되면 원하는 방향을 이미 선택했습니다.
Kenny Wyland

kenny 이것을 확인하면 도움이 될 것 같습니다 stackoverflow.com/questions/2833474/…
Avi Kumar Manku

이 답변이 공표되었지만 문제가 해결되는지 확실하지 않습니다. 정보 Configuration제공 screenLayout-DPI. 질문은 실제 장치 화면 크기-전화 VS 태블릿과 관련이 있습니다. 의미, 당신은 가질 Configuration.SCREENLAYOUT_SIZE_NORMAL수 있으며 MDPI 태블릿이 될 것입니다.
9


10

허용 된 답변에 대한 보충

Android Studio에서 다음 단계를 수행 하여 파일에 res/values-sw600dpres/values-large디렉토리 를 추가 할 수 bools.xml있습니다.

값 -sw600dp

우선 프로젝트 탭의 탐색기에서 프로젝트 (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파일 을 작성 하십시오.


2
이것이 작동하지 않으면 알려 주시면 해결하겠습니다. 그것은 나를 위해 일했다. 하나의 downvote가 있지만 의견이 없으므로 수정해야 할 사항이 없습니다.
Suragch

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;
} 

및 : (이 방법을 재정의하지 않으면 방향을 변경할 때 앱이 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
가로 레이아웃을 레이아웃 랜드 폴더에
놓기

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은 리소스 수정자가 적용되기 전에 매니페스트의 모든 활동에 대해 정확히 한 번만 설정됩니다.
0101100101

2

허용 된 답변에 따라 , 나는 누군가를 도울 희망 솔루션과 함께 kotlin 파일을 추가하고 있습니다

이 bool 리소스 res/valuesbools.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)
    }
}

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의 답변에서 활동 코드가 두 번 호출 될 수 있다는 것을 고려해야합니다. 이는 시각적뿐만 아니라 네트워크 요청, 분석 등에 나쁜 영향을 줄 수 있습니다.

또한 매니페스트에서 configChanges 속성을 설정하는 것은 큰 절충점이며 막대한 리팩토링 비용이 발생할 수 있습니다. Android 개발자는 해당 속성을 변경하지 않는 것이 좋습니다 .

마지막으로 screenOrientation을 (다시 시작 문제를 피하기 위해) 다르게 설정하려고 시도하는 것은 불가능합니다. 변경 할 수없는 정적 매니페스트로 인해 정적으로 불가능합니다. 프로그래밍 방식으로 이미 시작된 활동에서 해당 메소드를 호출하는 것만 가능합니다.

요약 : @Brian Christensen 제안은 최선의 절충이지만 다시 시작하는 활동 문제를 알고 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.