Nullable
является структурой, в основном она не может удерживать значение null
.
Ваше назначение, фактически скомпилировано во что-то, что выглядит так:
Nullable ndate = new Nullable();
В другом примере выражение:
int? a = null;
Генерирует следующий IL:
.locals init (valuetype [mscorlib]System.Nullable`1 V_0)
IL_0000: ldloca.s V_0
IL_0002: initobj valuetype [mscorlib]System.Nullable`1
Вызов операции initobj
, который инициализирует каждое поле типа значения по указанному адресу нулевой ссылке или 0 соответствующего примитивного типа.
В заключение, что здесь происходит, это инициализация struct по умолчанию .
Текущая конфигурация, используемая для определения того, какие ресурсы следует извлечь, доступна из объекта «112» ресурсов:
getResources().getConfiguration().orientation;
Вы можете проверить ориентацию, посмотрев на ее значение:
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// In landscape
} else {
// In portrait
}
Дополнительную информацию можно найти в Android Developer .
Вы можете использовать это (на основе здесь ):
public static boolean isPortrait(Activity activity) {
final int currentOrientation = getCurrentOrientation(activity);
return currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT || currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
public static int getCurrentOrientation(Activity activity) {
//code based on https://www.captechconsulting.com/blog/eric-miles/programmatically-locking-android-screen-orientation
final Display display = activity.getWindowManager().getDefaultDisplay();
final int rotation = display.getRotation();
final Point size = new Point();
display.getSize(size);
int result;
if (rotation == Surface.ROTATION_0
|| rotation == Surface.ROTATION_180) {
// if rotation is 0 or 180 and width is greater than height, we have
// a tablet
if (size.x > size.y) {
if (rotation == Surface.ROTATION_0) {
result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
} else {
// we have a phone
if (rotation == Surface.ROTATION_0) {
result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else {
result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
}
} else {
// if rotation is 90 or 270 and width is greater than height, we
// have a phone
if (size.x > size.y) {
if (rotation == Surface.ROTATION_90) {
result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
} else {
// we have a tablet
if (rotation == Surface.ROTATION_90) {
result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
} else {
result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
}
}
return result;
}
Стоит также отметить, что в настоящее время есть меньше веских причин проверять явную ориентацию с помощью getResources().getConfiguration().orientation
, если вы делаете это по причинам компоновки, как Поддержка многооконности , представленная в Android 7 / API 24+ может немного испортить ваши макеты в любой ориентации. Лучше рассмотреть возможность использования <ConstraintLayout>
и альтернативных макетов в зависимости от доступной ширины или высоты , а также других приемов для определения того, какой макет используется, например, наличие или отсутствие определенных фрагментов, прикрепленных к вашей деятельности.
Используйте этот способ,
int orientation = getResources().getConfiguration().orientation;
String Orintaion = "";
switch (orientation)
{
case Configuration.ORIENTATION_UNDEFINED: Orintaion = "Undefined"; break;
case Configuration.ORIENTATION_LANDSCAPE: Orintaion = "Landscrape"; break;
case Configuration.ORIENTATION_PORTRAIT: Orintaion = "Portrait"; break;
default: Orintaion = "Square";break;
}
в строке у вас есть Oriantion
, так что это наложение всех телефонов, таких как oneplus3
public static boolean isScreenOriatationPortrait(Context context) {
return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}
правильный код следующим образом:
public static int getRotation(Context context){
final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180){
return Configuration.ORIENTATION_PORTRAIT;
}
if(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270){
return Configuration.ORIENTATION_LANDSCAPE;
}
return -1;
}
Есть много способов сделать это, этот кусок кода работает для меня
if (this.getWindow().getWindowManager().getDefaultDisplay()
.getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
// portrait mode
} else if (this.getWindow().getWindowManager().getDefaultDisplay()
.getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
// landscape
}
Я думаю, что это решение легко
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
user_todat_latout = true;
} else {
user_todat_latout = false;
}
Старый пост я знаю. Независимо от того, какая ориентация может быть или поменялась местами и т. Д. Я разработал эту функцию, которая используется для установки устройства в правильную ориентацию без необходимости знать, как на устройстве организованы портретные и альбомные функции.
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); }
}
Работает как шарм!
Протестировано в 2019 году на API 28, независимо от того, установил ли пользователь книжную ориентацию или нет, и с минимальным кодом по сравнению с другим устаревшим ответом , следующее обеспечивает правильную ориентацию:
/** @return The {@link Configuration#ORIENTATION_SQUARE}, {@link Configuration#ORIENTATION_PORTRAIT}, {@link Configuration#ORIENTATION_LANDSCAPE} constants based on the current phone screen pixel relations. */
private int getScreenOrientation()
{
DisplayMetrics dm = context.getResources().getDisplayMetrics(); // Screen rotation effected
if(dm.widthPixels == dm.heightPixels)
return Configuration.ORIENTATION_SQUARE;
else
return dm.widthPixels < dm.heightPixels ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
}
Я думаю, что этот код может работать после того, как изменение ориентации вступит в силу
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
переопределить функцию Activity.onConfigurationChanged (Configuration newConfig) и использовать newConfig, direction, если вы хотите получать уведомление о новой ориентации перед вызовом setContentView.
Есть еще один способ сделать это:
public int getOrientation()
{
if(getResources().getDisplayMetrics().widthPixels>getResources().getDisplayMetrics().heightPixels)
{
Toast t = Toast.makeText(this,"LANDSCAPE",Toast.LENGTH_SHORT);
t.show();
return 1;
}
else
{
Toast t = Toast.makeText(this,"PORTRAIT",Toast.LENGTH_SHORT);
t.show();
return 2;
}
}
Некоторое время прошло с тех пор, как большинство из этих ответов были опубликованы, и некоторые из них теперь не рекомендуются методами и константами.
Я обновил код Ярека , чтобы больше не использовать эти методы и константы:
protected int getScreenOrientation()
{
Display getOrient = getWindowManager().getDefaultDisplay();
Point size = new Point();
getOrient.getSize(size);
int orientation;
if (size.x < size.y)
{
orientation = Configuration.ORIENTATION_PORTRAIT;
}
else
{
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
return orientation;
}
Обратите внимание, что режим Configuration.ORIENTATION_SQUARE
больше не поддерживается.
Я обнаружил, что это надежно на всех устройствах, на которых я тестировал, в отличие от метода, предлагающего использовать getResources().getConfiguration().orientation
Проверьте ориентацию экрана во время выполнения.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
Используйте getResources().getConfiguration().orientation
, это правильный путь.
Вам просто нужно следить за различными типами ландшафта, ландшафтом, который обычно использует устройство, и другим.
Все еще не понимаю, как с этим справиться.
int ot = getResources().getConfiguration().orientation;
switch(ot)
{
case Configuration.ORIENTATION_LANDSCAPE:
Log.d("my orient" ,"ORIENTATION_LANDSCAPE");
break;
case Configuration.ORIENTATION_PORTRAIT:
Log.d("my orient" ,"ORIENTATION_PORTRAIT");
break;
case Configuration.ORIENTATION_SQUARE:
Log.d("my orient" ,"ORIENTATION_SQUARE");
break;
case Configuration.ORIENTATION_UNDEFINED:
Log.d("my orient" ,"ORIENTATION_UNDEFINED");
break;
default:
Log.d("my orient", "default val");
break;
}
Вот демонстрационный пример кода, как получить ориентацию экрана, было рекомендовано hackbod и Martijn :
❶ Триггер при изменении ориентации:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int nCurrentOrientation = _getScreenOrientation();
_doSomeThingWhenChangeOrientation(nCurrentOrientation);
}
❷ Получить текущую ориентацию, как hackbod рекомендует:
private int _getScreenOrientation(){
return getResources().getConfiguration().orientation;
}
❸Есть альтернативное решение для получения текущей ориентации экрана ❷ следуйте Martijn решение:
private int _getScreenOrientation(){
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
return display.getOrientation();
}
★ Примечание : я попробовал как реализовать ❷ & amp; ❸, но в RealDevice (NexusOne SDK 2.3) ориентация возвращает неправильную ориентацию.
★ Итак, я рекомендую использовать решение ❷, чтобы получить ориентацию экрана, которая имеет больше преимуществ: четко, просто и работает как шарм.
★ Тщательно проверяйте возвращаемость ориентации, чтобы гарантировать правильность, как мы ожидали (может быть ограничено в зависимости от спецификации физических устройств)
Надеюсь, это поможет,
Полный способ указать текущую ориентацию телефона:
public String getRotation(Context context){
final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
switch (rotation) {
case Surface.ROTATION_0:
return "portrait";
case Surface.ROTATION_90:
return "landscape";
case Surface.ROTATION_180:
return "reverse portrait";
default:
return "reverse landscape";
}
}
Chear Binh Nguyen
Другим способом решения этой проблемы является не полагаться на правильное возвращаемое значение с дисплея, а полагаться на разрешение ресурсов Android.
Создайте файл layouts.xml
в папках res/values-land
и res/values-port
со следующим содержимым:
res / values-land / layouts.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_landscape">true</bool>
</resources>
res / values-port / layouts.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_landscape">false</bool>
</resources>
Теперь в своем исходном коде вы можете получить доступ к текущей ориентации следующим образом:
context.getResources().getBoolean(R.bool.is_landscape)
Если вы используете ориентацию getResources (). GetConfiguration (). На некоторых устройствах, вы ошибетесь. Мы использовали этот подход первоначально в http://apphance.com . Благодаря удаленному ведению журнала Apphance мы могли видеть его на разных устройствах и увидели, что фрагментация играет здесь свою роль. Я видел странные случаи: например, чередование портрета и квадрата (?!) в HTC Desire HD:
CONDITION[17:37:10.345] screen: rotation: 270 orientation: square
CONDITION[17:37:12.774] screen: rotation: 0 orientation: portrait
CONDITION[17:37:15.898] screen: rotation: 90
CONDITION[17:37:21.451] screen: rotation: 0
CONDITION[17:38:42.120] screen: rotation: 270 orientation: square
или отсутствие изменения ориентации вообще:
CONDITION[11:34:41.134] screen: rotation: 0
CONDITION[11:35:04.533] screen: rotation: 90
CONDITION[11:35:06.312] screen: rotation: 0
CONDITION[11:35:07.938] screen: rotation: 90
CONDITION[11:35:09.336] screen: rotation: 0
С другой стороны, width () и height () всегда корректны (они используются оконным менеджером, так что должно быть лучше). Я бы сказал, что лучшая идея - ВСЕГДА проверять ширину / высоту. Если вы подумаете о моменте, это именно то, что вы хотите - узнать, если ширина меньше высоты (портрет), наоборот (пейзаж) или они одинаковы (квадрат).
Тогда это сводится к этому простому коду:
public int getScreenOrientation()
{
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = Configuration.ORIENTATION_UNDEFINED;
if(getOrient.getWidth()==getOrient.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
} else{
if(getOrient.getWidth() < getOrient.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else {
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
return orientation;
}
Android SDK может сказать вам это прекрасно:
getResources().getConfiguration().orientation
Просто простые два линейных кода
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// do something in landscape
} else {
//do in potrait
}