บังคับโหมดการวางแนว "แนวตั้ง"


298

ฉันพยายามบังคับให้โหมด "แนวตั้ง" สำหรับแอปพลิเคชันของฉันเพราะแอปพลิเคชันของฉันไม่ได้ออกแบบมาสำหรับโหมด "แนวนอน" อย่างแน่นอน

หลังจากอ่านฟอรัมฉันได้เพิ่มบรรทัดเหล่านี้ในไฟล์ Manifest:

<application 
  android:debuggable="true"
  android:icon="@drawable/icon" 
  android:label="@string/app_name"
  android:screenOrientation="portrait">

แต่มันใช้ไม่ได้กับอุปกรณ์ของฉัน (HTC Desire) มันสลับจาก "แนวตั้ง" lo "แนวนอน" โดยไม่สนใจบรรทัดจากไฟล์รายการ

หลังจากอ่านฟอรัมเพิ่มเติมฉันพยายามเพิ่มสิ่งนี้ในไฟล์รายการ:

<application 
  android:debuggable="true"
  android:icon="@drawable/icon" 
  android:label="@string/app_name"
  android:configChanges="orientation"       
  android:screenOrientation="portrait">

และฟังก์ชั่นนี้ในชั้นเรียนกิจกรรมของฉัน:

public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

แต่โชคไม่ดีอีกครั้ง

คำตอบ:


531

อย่าใช้การวางแนวกับองค์ประกอบของแอปพลิเคชันแต่คุณควรใช้แอททริบิวกับองค์ประกอบของกิจกรรมและคุณต้องตั้งค่าconfigChangesตามที่ระบุไว้ด้านล่าง

ตัวอย่าง:

<activity
   android:screenOrientation="portrait"
   android:configChanges="orientation|keyboardHidden">
</activity>

สิ่งนี้นำไปใช้ในไฟล์AndroidManifest.xmlรายการ


26
configChanges มีไว้เพื่ออะไร
Dror

71
@Orchestrator, configChanges หมายความว่าการเปลี่ยนแปลงการกำหนดค่าได้รับการจัดการโดยตัวกิจกรรมเอง กิจกรรมนี้จะเริ่มต้นใหม่หากไม่มีการเปลี่ยนแปลงการวางแนว คุณอาจถามว่าคุณได้ระบุว่าการวางแนวนั้นเป็น "แนวตั้ง" มันจะเปลี่ยนไปอย่างไร มันสามารถเปลี่ยนแปลงได้หากคุณเริ่มต้นกิจกรรมอื่นที่เปลี่ยนแปลงการวางแนวจากนั้นกิจกรรมใหม่จะจบลงและกลับสู่กิจกรรมของคุณ ตัวอย่างเช่นเจตนาจับภาพเริ่มต้นบน Samsung Galaxy S3 ทำเช่นนั้นในทิศทางที่แน่นอน
Gordon McCreight

2
@GordonMcCreight คุณช่วยอธิบายสิ่งนี้ด้วยตัวอย่างจริง ๆ "คุณอาจถามว่าคุณระบุว่าการวางแนวนั้นเป็น" แนวตั้ง "หรือไม่มันจะเปลี่ยนไปได้อย่างไรถ้าเปลี่ยนกิจกรรมอื่นที่เปลี่ยนทิศทางแล้ว ออกจากกิจกรรมใหม่แล้วนำคุณกลับสู่กิจกรรม "
Tushar Pandey

3
แน่นอน @TusharPandey ถ้าฉันจำได้ถูกต้องสถานที่แห่งนี้ทำให้เราเศร้าโศกคือเมื่อกิจกรรมของเราเปิดตัวเจตนาจับภาพเริ่มต้นบน Samsung Galaxy S3 โดยพื้นฐานแล้วเราแค่ต้องการถ่ายรูปและรับผลลัพธ์ อย่างไรก็ตามเมื่อความตั้งใจของกล้องกลับมามันทำให้เกิดการเปลี่ยนทิศทางที่ลบล้างสถานะในกิจกรรมของเราเนื่องจากเราไม่เชื่อว่าเราจำเป็นต้องป้องกันสิ่งนั้น (เนื่องจากแอปทั้งหมดของเราเป็นเพียงแนวตั้ง "แนวตั้ง") Galaxy S3 ทำสิ่งนี้ได้อย่างไรและเกินความเข้าใจของฉัน
Gordon McCreight

8
เหตุใดจึงมี "keyboardHidden" รวมอยู่ด้วย
gonzobrains

24

สังเกตได้ว่า

android:screenOrientation="portrait"     
android:configChanges="orientation|keyboardHidden"

ถูกเพิ่มในไฟล์รายการ - ที่มีการกำหนดกิจกรรม


13

ฉันคิดว่าandroid:screenOrientation="portrait"สามารถใช้สำหรับกิจกรรมของแต่ละบุคคล ดังนั้นใช้คุณลักษณะนั้นใน<activity>แท็กเช่น:

<activity android:name=".<Activity Name>"
    android:label="@string/app_name" 
    android:screenOrientation="portrait">
   ...         
</activity>

13

หากคุณมีกิจกรรมมากมายเช่นของฉันในแอปพลิเคชันของคุณหรือถ้าคุณไม่ต้องการป้อนรหัสสำหรับแต่ละแท็กของกิจกรรมในรายการคุณสามารถทำได้

ในคลาส Application Base ของคุณคุณจะได้รับวงจรการโทรกลับ

ดังนั้นโดยทั่วไปสิ่งที่เกิดขึ้นในแต่ละกิจกรรมเมื่อสร้างในการสร้างใน Application Class ได้รับการเรียกที่นี่เป็นรหัส ..

public class MyApplication extends Application{

@Override
    public void onCreate() {
        super.onCreate();  

  registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
                activity.setRequestedOrientation(
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


// for each activity this function is called and so it is set to portrait mode


            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
}

ฉันหวังว่านี่จะช่วยได้.


1
คำตอบที่มีประสิทธิภาพ! นี่ควรเป็นคำตอบที่ถูกต้องโดยเฉพาะอย่างยิ่งสำหรับผู้ที่กำลังพัฒนาแอพที่ซับซ้อนซึ่งขึ้นอยู่กับกิจกรรมจำนวนมาก
FEBRYAN ASA PERDANA

10

ตั้งค่าโหมดบังคับแนวตั้งหรือแนวนอนเพิ่มบรรทัดตามลำดับ

นำเข้าบรรทัดด้านล่าง:

import android.content.pm.ActivityInfo;

เพิ่มบรรทัดด้านล่างด้านบน setContentView(R.layout.activity_main);

สำหรับแนวตั้ง :

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//Set Portrait

สำหรับLandscap :

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//Set Landscape

นี้จะทำงานได้อย่างแน่นอน


1
สิ่งนี้ล้มเหลวด้วย Android 9 ในบางอุปกรณ์ - การเปลี่ยนการหมุนหน้าจอจะปรากฏให้เห็นในช่วงเวลาสั้น ๆ แม้ว่าคุณจะใช้ PORTRAIT เท่านั้น
Igor Wojda

คุณช่วยกรุณาระบุข้อมูลอุปกรณ์ที่คุณมีใบหน้านี้ถ้าเป็นไปได้
Parth Patel

4

ตามเอกสารของ Android คุณมักจะรวมถึงscreenSizeการเปลี่ยนแปลงการกำหนดค่าที่เป็นไปได้

android:configChanges="orientation|screenSize"

หากแอปพลิเคชันของคุณกำหนดเป้าหมาย API ระดับ 13 หรือสูงกว่า (ตามที่ประกาศโดยแอตทริบิวต์ minSdkVersion และ targetSdkVersion) คุณควรประกาศการกำหนดค่า "screenSize" เนื่องจากจะเปลี่ยนเมื่ออุปกรณ์สลับระหว่างแนวตั้งและแนวนอน

นอกจากนี้ถ้าคุณทั้งหมดรวมมูลค่าkeyboardHiddenในตัวอย่างของคุณคุณไม่ควรแล้วยังพิจารณาlocale, mcc, fontScale, keyboardและอื่น ๆ ..


3

ฉันมีบรรทัดนี้ใน AndroidManifest.xml ของฉัน

<activity 
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
    android:label="@string/app_name" android:name="Project Name"
    android:theme="@android:style/Theme.Black.NoTitleBar">

ซึ่งฉันเปลี่ยนเป็น (เพิ่งเพิ่มandroid:screenOrientation="portrait")

<activity 
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
    android:label="@string/app_name" android:name="Project Name"
    android:screenOrientation="portrait"
    android:theme="@android:style/Theme.Black.NoTitleBar">

สิ่งนี้คงที่สำหรับฉัน


2

สิ่งที่ต้องเสริม: ฉันเพิ่งปรับปรุงแอพเมื่อเร็ว ๆ นี้ก่อนหน้านี้ทำงานได้ทั้งในแนวนอนและแนวตั้งและฉันต้องการให้เวอร์ชันที่อัปเดตควรทำงานในโหมดแนวตั้งดังนั้นฉันจึงเพิ่ม

android:screenOrientation="portrait"

ไปที่กิจกรรมที่เกี่ยวข้องและมันก็พังเมื่อฉันทดสอบการปรับปรุง จากนั้นฉันก็เพิ่ม

android:configChanges="orientation|keyboardHidden"

เกินไปและมันก็ใช้งานได้


1
หากนี่ไม่ใช่คำตอบสำหรับคำถามอาจเพิ่มได้เนื่องจากความคิดเห็นจะช่วยได้
JPReddy

ตรวจสอบว่าคุณเพิ่มลงในกิจกรรมที่ไม่ใช้สำหรับบล็อกแอปพลิเคชัน
Waran-

1

ฉันคิดว่าคุณต้องการที่จะเพิ่มandroid:configChanges="orientation|keyboardHidden"ในกิจกรรมของคุณ? มิฉะนั้นกิจกรรมจะเริ่มต้นใหม่เมื่อ config-change onConfigurationChangedจะไม่ถูกเรียกแล้วเท่านั้นonCreate


1

หากคุณต้องการสนับสนุนทิศทางที่แตกต่างกันในdebugและreleaseสร้างเขียน (ดูhttps://developer.android.com/studio/build/gradle-tips#share-properties-with-the-manifest )

ในโฟลเดอร์build.gradleของคุณappเขียน:

android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // Creates a placeholder property to use in the manifest.
            manifestPlaceholders = [orientation: "fullSensor"]
        }
        release {
            debuggable true
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // Creates a placeholder property to use in the manifest.
            manifestPlaceholders = [orientation: "portrait"]
        }
    }
}

จากนั้นAndroidManifestคุณสามารถใช้ตัวแปร "การวางแนว" นี้ในใด ๆActivity:

<activity
    android:name=".LoginActivity"
    android:screenOrientation="${orientation}" />

คุณสามารถเพิ่ม android:configChanges :

manifestPlaceholders = [configChanges: "", orientation: "fullSensor"]ในการแก้ปัญหาและmanifestPlaceholders = [configChanges: "keyboardHidden|orientation|screenSize", orientation: "portrait"]ในการเปิดตัว

<activity
    android:name=".LoginActivity"
    android:configChanges="${configChanges}"
    android:screenOrientation="${orientation}" />

-8

คำตอบสั้น ๆ : อย่าทำ

ออกแบบแอปของคุณใหม่เพื่อให้สามารถทำงานได้ทั้งในโหมดแนวตั้งและแนวนอน ไม่มีสิ่งเช่น UI ที่ไม่สามารถออกแบบให้ทำงานได้ทั้งแนวตั้งและแนวนอน เฉพาะนักพัฒนาที่ขี้เกียจหรือไม่คิดอะไรเลย

เหตุผลว่าทำไมค่อนข้างง่าย คุณต้องการให้แอปของคุณสามารถใช้งานได้โดยผู้ชมในวงกว้างเท่าที่จะเป็นไปได้บนอุปกรณ์ที่แตกต่างกันให้มากที่สุด ด้วยการบังคับให้วางแนวหน้าจอเฉพาะคุณจะป้องกันไม่ให้แอปของคุณทำงาน (ใช้งานได้) บนอุปกรณ์ที่ไม่รองรับการวางแนวนั้น

ตัวอย่าง: คุณออกแบบแอปของคุณเพื่อบังคับโหมดแนวตั้ง ลูกค้าดาวน์โหลดแอปบนอุปกรณ์ 2-in-1 ซึ่งพวกเขาใช้ส่วนใหญ่ในโหมดแนวนอน
ผลที่ตามมา 1: แอปของคุณไม่สามารถใช้งานได้หรือลูกค้าของคุณถูกบังคับให้ปลดอุปกรณ์ออกจากอุปกรณ์ของพวกเขาหมุนและใช้งานในทิศทางที่ไม่คุ้นเคยหรือไม่สะดวกสบายสำหรับพวกเขา
ผลที่ตามมา 2: ลูกค้าได้รับความผิดหวังจากการออกแบบที่ไม่ใช้งานแอปของคุณและหาทางเลือกหรือทิ้งแอพทั้งหมด

ฉันกำลังต่อสู้กับสิ่งนี้ด้วยแอพทันทีและในฐานะผู้บริโภคและนักพัฒนาฉันเกลียดมัน มีประโยชน์อย่างที่แอพนี้ต่างจากคุณสมบัติที่มีให้ฉันเกลียดแอปอย่างมากเพราะบังคับให้ฉันใช้การวางแนวที่ตรงกันข้ามกับวิธีอื่นที่ฉันใช้อุปกรณ์ของฉัน

คุณไม่ต้องการให้ลูกค้าเกลียดแอปของคุณ


ฉันรู้ว่านี่ไม่ได้ตอบคำถามโดยตรงดังนั้นฉันต้องการอธิบายในรายละเอียดเพิ่มเติมเล็กน้อยสำหรับผู้ที่อยากรู้อยากเห็น

มีแนวโน้มที่นักพัฒนาจะเก่งในการเขียนโค้ดและออกแบบได้แย่มาก คำถามนี้แม้ว่าจะดูเหมือนคำถามรหัสและผู้ถามรู้สึกอย่างแน่นอนว่าเป็นคำถามรหัส แต่เป็นคำถามออกแบบ

คำถามคือ "ฉันควรล็อคการวางแนวหน้าจอในแอพของฉันหรือไม่" ผู้ถามเลือกที่จะออกแบบ UI ให้ทำงานและดูดีในโหมดแนวตั้งเท่านั้น ฉันสงสัยว่ามันคือการประหยัดเวลาในการพัฒนาหรือเพราะขั้นตอนการทำงานของแอพเอื้อต่อการจัดวางแนวตั้ง (โดยทั่วไปสำหรับเกมมือถือ) แต่ด้วยเหตุผลเหล่านั้นก็มองข้ามปัจจัยสำคัญที่ทำให้เกิดการออกแบบที่เหมาะสม

  1. การมีส่วนร่วมของลูกค้า - คุณต้องการให้ลูกค้ารู้สึกว่ามีส่วนร่วมในแอพของคุณไม่ใช่ผลักมันออกมา แอพควรเปลี่ยนจากสิ่งที่ลูกค้าทำก่อนเปิดแอพ (นี่คือเหตุผลที่แพลตฟอร์มส่วนใหญ่มีหลักการออกแบบที่สอดคล้องกันดังนั้นแอพส่วนใหญ่จึงดูเหมือนมากหรือน้อยแม้ว่าพวกเขาจะไม่ต้องการก็ตาม)

  2. การตอบสนองลูกค้า - คุณต้องการให้ลูกค้าตอบสนองเชิงบวกต่อแอพของคุณ พวกเขาควรสนุกกับการใช้มัน แม้ว่ามันจะเป็นแอพบัญชีเงินเดือนสำหรับการทำงานมันก็เป็นความสุขสำหรับพวกเขาที่จะเปิดมันและนาฬิกาแอพนี้ควรประหยัดเวลาของลูกค้าและลดความยุ่งยากในการเลือก (แอพที่สร้างความรำคาญให้ผู้ใช้สร้างความขุ่นเคืองกับแอพของคุณซึ่งกลายเป็นความแค้นต่อแบรนด์ของคุณ)

  3. การแปลงลูกค้า - คุณต้องการให้ลูกค้าของคุณสามารถย้ายจากการเรียกดูไปยังการโต้ตอบได้อย่างรวดเร็วและง่ายดาย นี่คือเป้าหมายสูงสุดของแอปใด ๆ เพื่อแปลงการแสดงผลเป็นรายได้ (แอพที่ไม่สร้างรายได้นั้นเป็นการเสียเวลาในการสร้างจากมุมมองทางธุรกิจ)

UI ที่ออกแบบมาไม่ดีช่วยลดความผูกพันของลูกค้าและการตอบสนองซึ่งส่งผลให้รายได้ลดลงในที่สุด ในโลกที่มีโทรศัพท์มือถือเป็นศูนย์กลาง (และโดยเฉพาะอย่างยิ่งในเรื่องของโหมดการแสดงผลแนวตั้ง / แนวนอน) สิ่งนี้อธิบายได้ว่าทำไมการออกแบบเว็บที่ตอบสนองได้นั้นเป็นเรื่องใหญ่ Walmart Canada นำเสนอการออกแบบที่ตอบสนองได้บนเว็บไซต์ของพวกเขาในเดือนพฤศจิกายน 2556 และเห็นการเปลี่ยนแปลงของลูกค้าเพิ่มขึ้น20% โอนีลเสื้อผ้าดำเนินการออกแบบที่ตอบสนองเว็บและรายได้จากลูกค้าที่ใช้อุปกรณ์ iOS ของคุณเพิ่มขึ้น101.25%และ591.42%จากลูกค้าที่ใช้อุปกรณ์ Androidจากลูกค้าที่ใช้อุปกรณ์

นอกจากนี้ยังมีแนวโน้มที่ผู้พัฒนาจะให้ความสำคัญกับการใช้งานโซลูชันเฉพาะอย่าง (เช่นการวางแนวการล็อกจอแสดงผล) และนักพัฒนาส่วนใหญ่ในเว็บไซต์นี้จะดีใจเกินไปที่จะช่วยให้การใช้งานโซลูชันนั้นโดยไม่ต้องสงสัยเลยว่า วิธีแก้ปัญหา

การล็อกการวางแนวหน้าจอของคุณคือการออกแบบ UI เทียบเท่ากับการใช้ลูป do-while คุณเป็นจริงเหรอแน่ใจหรือว่าต้องการทำเช่นนั้นหรือมีทางเลือกอื่นที่ดีกว่า

อย่าบังคับให้แอปของคุณเข้าสู่โหมดการแสดงผลเดียว ลงทุนเวลาพิเศษและความพยายามเพื่อให้ตอบสนองได้


2
ฉันเข้าใจและเห็นด้วยกับคุณเกี่ยวกับการเป็น UI ที่ออกแบบมาไม่ดี แต่นั่นไม่ได้เปลี่ยนความจริงที่ว่าคุณอาจจำเป็นต้องทำเช่นนั้นและกรอบการทำงานควรมีความสามารถเหล่านั้นโดยทั่วไป คุณไม่มีทางรู้ว่าแอปในอนาคตจะเป็นอย่างไรและจำเป็นต้องทำอะไรดังนั้นคำถามนี้ยังคงใช้ได้
Z. Khullah

1
คุณไม่ผิด ฉันคิดว่าคำตอบของฉันส่วนหนึ่งมาจากความคับข้องใจที่ฉันมีกับแอพไม่กี่ตัวที่ทำสิ่งนี้โดยไม่จำเป็นและมันก็ทำลายประสบการณ์โดยสิ้นเชิง ฉันจะบอกว่าจำนวนกรณีที่ถูกต้องตามกฎหมายสำหรับการล็อคโหมดการแสดงผลนั้นมีขนาดเล็กมาก (และยังคงเป็นไปได้และเป็นที่นิยมมากกว่าไม่อยู่ในงบประมาณ) สิ่งนี้ทำให้นึกถึงปัญหาอื่น ๆ เพราะการเขียนโค้ดกลายเป็นเรื่องง่ายอย่างที่มันมีนักพัฒนาสมัครเล่นจำนวนมากเขียนแอพเพราะพวกเขารู้รหัส แต่ไม่ต้องเรียนรู้วิธีการทำ UI หรือการออกแบบหรือแม้แต่แนวปฏิบัติพื้นฐานที่ดีที่สุด (แอพ Java ที่ติดตั้งใน \ AppData - EWWWW)
โธมัส

1
ฉันกำลังสร้างแอป VR การวางแนวจะต้องเป็นแนวนอนสำหรับแว่นตาที่จะใช้เวทมนตร์ นี่เป็นตัวอย่างหนึ่งของ UI ที่ไม่สามารถออกแบบให้ทำงานได้ทั้งแนวตั้งและแนวนอน เกมอาจต้องบังคับทิศทางที่แน่นอน ฉันพนันได้เลยว่ามีหลายคดีที่ถูกกฎหมาย
Raslanove

1
ในขณะที่ StackExchange มีอยู่เพื่อตอบคำถามเฉพาะควรเขียนคำตอบเพื่อนำไปใช้โดยทั่วไปเท่าที่จะทำได้เพื่อให้คำตอบเหล่านั้นมีประโยชน์ต่อผู้อื่น การพัฒนาเป็นมากกว่าการเขียนโค้ดและเหตุผลที่มีแอปพลิเคชั่นขยะจำนวนมากในโลกเพราะนักพัฒนาจำนวนมากลืม - หรือไม่เคยเรียนรู้ - หลักการที่สำคัญนี้ ฉันจะเพิ่มเองเป็นการส่วนตัวว่าหากคุณกำลังทำ VR บนโทรศัพท์ที่คุณทำผิด VR - แต่ค่าใช้จ่ายได้ผลักดันให้ความต้องการ VR เข้าสู่แพลตฟอร์มที่ไม่ควรสนับสนุน
โทมัส

1
ฉันไม่เห็นด้วยกับคำตอบนี้ แต่เป็นการตอบคำถามที่ไม่ได้ถาม
bmovement
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.