मैं चित्र और परिदृश्य (sw600dp या अधिक) में प्रदर्शित करने में सक्षम होने के लिए गोलियाँ चाहूंगा, लेकिन फ़ोन केवल चित्र तक ही सीमित रहेंगे। मुझे सशर्त रूप से अभिविन्यास चुनने का कोई तरीका नहीं मिल रहा है। कोई सुझाव?
मैं चित्र और परिदृश्य (sw600dp या अधिक) में प्रदर्शित करने में सक्षम होने के लिए गोलियाँ चाहूंगा, लेकिन फ़ोन केवल चित्र तक ही सीमित रहेंगे। मुझे सशर्त रूप से अभिविन्यास चुनने का कोई तरीका नहीं मिल रहा है। कोई सुझाव?
जवाबों:
यहां संसाधनों और आकार क्वालिफायर का उपयोग करने का एक अच्छा तरीका है ।
इस बूल संसाधन को bools.xml या जो भी (फ़ाइल नाम यहाँ कोई फर्क नहीं पड़ता) के रूप में रेस / मान में रखें:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
इस एक को Res / मान-sw600dp और res / मान-xlarge में रखें:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
एंड्रॉइड स्टूडियो में इन निर्देशिकाओं और फ़ाइलों को जोड़ने में मदद के लिए यह पूरक उत्तर देखें ।
फिर, अपनी गतिविधियों के चालू तरीके से आप यह कर सकते हैं:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
डिवाइस जो कि छोटी चौड़ाई की दिशा में 600 डीपी से अधिक हैं, या प्री-एंड्रॉइड 3.2 डिवाइस (टैबलेट, मूल रूप से) पर एक्स-लार्ज, सेंसर और उपयोगकर्ता-लॉक किए गए रोटेशन के आधार पर , सामान्य की तरह व्यवहार करेंगे । बाकी सब कुछ (फोन, बहुत ज्यादा) केवल चित्र होगा।
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
है - डीपीआई। जबकि सवाल भौतिक डिवाइस स्क्रीन आकार - फोन वीएस टैबलेट से संबंधित है। मतलब, आपके पास एक हो सकता है Configuration.SCREENLAYOUT_SIZE_NORMAL
और यह एक एमडीपीआई टैबलेट होगा।
आप अपनी फ़ाइलों के साथ res/values-sw600dp
और res/values-large
निर्देशिकाओं को जोड़ने के लिए एंड्रॉइड स्टूडियो में निम्न चरण कर सकते हैं bools.xml
।
सबसे पहले, प्रोजेक्ट टैब से नेविगेटर में प्रोजेक्ट (एंड्रॉइड के बजाय) फ़िल्टर का चयन करें।
फिर 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 में, प्रत्येक गतिविधि के लिए जिसे आप पोर्ट्रेट और लैंडस्केप के बीच बदलने में सक्षम होना चाहते हैं (सुनिश्चित करें कि आप स्क्रीनसेज़ जोड़ते हैं - आपको इसकी आवश्यकता नहीं थी!) आपको यहां स्क्रीन ओरिएंटेशन सेट करने की आवश्यकता नहीं है। :
android:configChanges="keyboardHidden|orientation|screenSize"
प्रत्येक गतिविधि में जोड़ने के तरीके:
public static boolean isXLargeScreen(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
और: (यदि आप इस विधि को ओवरराइड नहीं करते हैं, तो ऐप ऑनक्रीट को कॉल करेगा) (जब ओरिएंटेशन बदलते हैं)
@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
}
प्रत्येक गतिविधि के चालू () में:
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 / मानों में- sw600dp / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
Res / मान / 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);
}
}
}
इसलिए प्रत्येक गतिविधि का विस्तार होगा आधार:
public class LoginActivity extends BaseActivity //....
महत्वपूर्ण : यहां तक कि अगर आप विस्तार करते हैं BaseActivity
, तो आपको अपने AndroidManifest.xml में android:configChanges="orientation|screenSize"
प्रत्येक पंक्ति को जोड़ना होगा Activity
:
<activity
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
खैर, यह थोड़ा देर से है लेकिन, यहां एक एक्सएमएल-ओनली है लेकिन एक हैक समाधान जो एक गतिविधि को फिर से नहीं setRequestedOrientation
करता है जैसे कि अभिविन्यास बदलना है:
स्वीकृत उत्तर के बाद , मैं कोटलिन फ़ाइल को इस उम्मीद के साथ जोड़ रहा हूं कि यह किसी की मदद करे
इस बूल संसाधन res/values
को बूलसेक्लेम या जो भी (फ़ाइल नाम यहां कोई फर्क नहीं पड़ता) के रूप में डालें :
<?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 (...) का उपयोग करने से गतिविधि फिर से शुरू हो जाएगी, इसलिए भले ही आप ऑनक्रिट विधि में इसे कॉल करते हैं, यह गतिविधि जीवनचक्र के माध्यम से जाएगा और फिर यह अनुरोधित अभिविन्यास में उसी गतिविधि को फिर से करेगा। तो @ ब्रायन क्रिस्टेंसन के जवाब पर आपको विचार करना चाहिए कि गतिविधि कोड को दो बार कहा जा सकता है, इसके बुरे प्रभाव हो सकते हैं (न केवल दृश्य, बल्कि नेटवर्क अनुरोध, विश्लेषिकी आदि पर भी)।
इसके अलावा, मैन्युफैक्चर की विशेषता को प्रकट करने के लिए सेट करना मेरी राय में एक बड़ा ट्रेड-ऑफ है, जो बड़े पैमाने पर रिफैक्टरिंग लागत ले सकता है। Android देवता उस विशेषता को बदलने की अनुशंसा नहीं कर रहे हैं ।
अंत में, स्क्रीनऑरिएशन को किसी भी तरह से अलग करने की कोशिश करना (पुनः आरंभ करने की समस्या से बचने के लिए) असंभव है, स्टेटिक मैनिफ़ेस्ट के कारण स्टेटिक रूप से असंभव है जिसे परिवर्तित नहीं किया जा सकता है, प्रोग्रामेटिक रूप से पहले से शुरू की गई गतिविधि में उस पद्धति को कॉल करना संभव है।
सारांश: मेरी राय में, @ ब्रायन क्रिस्टेंसन सुझाव सबसे अच्छा व्यापार-बंद है, लेकिन गतिविधि के फिर से शुरू होने के बारे में पता होना चाहिए।
layout-land
अंदरres
फ़ोल्डर का उपयोग करके ।