Обнаружение вращения главного экрана Android
У меня есть App Widget, который при его обновлении извлекает изображение с размерами в соответствии с виджетами и помещает это изображение в ImageView
(через RemoteViews
). Он отлично работает.
Но для устройств, поддерживающих вращение главного экрана (и я не говорю о вращении, например, Activity
на основе ориентации устройства, а о вращении самого домашнего экрана) размеры и соотношение сторон виджета немного меняется при переходе от пейзажа к портрету и наоборот... т.е. фиксированный размер не поддерживается.
Итак, мой виджет должен иметь возможность обнаруживать, когда главный экран вращается, и извлекать новое изображение (или, по крайней мере, загружать другое предварительно загруженное изображение).
Я не могу для жизни меня разобраться, возможно ли и как это возможно. Любые подсказки?
Ответы
Ответ 1
Используйте код ниже для определения ориентации: -
View view = getWindow().getDecorView();
int orientation = getResources().getConfiguration().orientation;
if (Configuration.ORIENTATION_LANDSCAPE == orientation) {
relativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.log_landscape));
imageview_Logo.setImageResource(R.drawable.log_landscape_2);
Log.d("Landscape", String.valueOf(orientation));
//Do SomeThing; // Landscape
} else {
relativeLayout.setBackgroundDrawable( getResources().getDrawable(R.drawable.login_bg) );
imageview_Logo.setImageResource(R.drawable.logo_login);
//Do SomeThing; // Portrait
Log.d("Portrait", String.valueOf(orientation));
}
Ответ 2
Использовать метод Activity onConfigurationChanged. См. Следующий код:
@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();
}
}
Итак, для виджетов мы должны добавить наш класс приложения, как показано ниже, и не забудьте также объявить его в манифесте, этот метод в основном отправляет обновление для всех экземпляров вашего виджета.
public class MyApplication extends Application {
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// create intent to update all instances of the widget
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class);
// retrieve all appWidgetIds for the widget & put it into the Intent
AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(this);
ComponentName cm = new ComponentName(this, MyWidget.class);
int[] appWidgetIds = appWidgetMgr.getAppWidgetIds(cm);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
// update the widget
sendBroadcast(intent);
}
}
и в манифесте...
<application
android:name="yourpackagename.MyApplication"
android:description="@string/app_name"
android:label="@string/app_name"
android:icon="@drawable/app_icon">
<!-- here go your Activity definitions -->
Ответ 3
Проверьте этот код:
myButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int rotation = getWindowManager().getDefaultDisplay()
.getRotation();
// DisplayMetrics dm = new DisplayMetrics();
// getWindowManager().getDefaultDisplay().getMetrics(dm);
int orientation;
CharSequence text;
switch (rotation) {
case Surface.ROTATION_0:
text = "SCREEN_ORIENTATION_PORTRAIT";
break;
case Surface.ROTATION_90:
text = "SCREEN_ORIENTATION_LANDSCAPE";
break;
case Surface.ROTATION_180:
text = "SCREEN_ORIENTATION_REVERSE_PORTRAIT";
break;
case Surface.ROTATION_270:
text = "SCREEN_ORIENTATION_REVERSE_LANDSCAPE";
break;
default:
text = "SCREEN_ORIENTATION_PORTRAIT";
break;
}
// CharSequence text = String.valueOf(orientation);
Toast toast = Toast.makeText(getApplicationContext(), text,
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER | Gravity.CENTER, 10, 0);
toast.show();
}
});
Ответ 4
Возможно, вы можете создать изображение с прозрачным фоном. Если изображение достаточно маленькое, чтобы оно соответствовало также при повороте, вам не нужно будет его повторно извлекать.
Ответ 5
Вы можете прослушивать трансляцию ACTION_CONFIGURATION_CHANGED, которая отправляется системой Android, когда изменилась текущая конфигурация устройства (ориентация, локаль и т.д.).
Согласно документации:
ACTION_CONFIGURATION_CHANGED:
Трансляция: текущее устройство Конфигурация (ориентация, язык и т.д.). Когда такое изменение происходит, пользовательский интерфейс (вид иерархия) необходимо будет перестроить на основе этой новой информации; для в основном, приложениям не нужно об этом беспокоиться, потому что система позаботится о том, чтобы остановить и перезапустить приложение чтобы убедиться, что он видит новые изменения. Некоторый системный код, который не может быть перезагружен должен будет следить за этим действием и обрабатывать его соответственно.
Вы не можете получить это через компоненты, объявленные в манифесте, только путем явной регистрации для него с помощью Context.registerReceiver().
Это защищенный замысел, который может быть отправлен системой.
public class YourWidgetProvider extends AppWidgetProvider {
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
context.registerReceiver(mOrientationChangeReceiver,new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
@Override
public void onDisabled(Context context) {
context.unregisterReceiver(mOrientationChangeReceiver);
super.onDisabled(context);
}
public BroadcastReceiver mOrientationChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent myIntent) {
if ( myIntent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
// landscape orientation
//write logic for building remote view here
// buildRemoteViews();
}
else {
//portrait orientation
//write logic for building remote view here
// buildRemoteViews();
}
}
}
};
}
Ответ 6
Вы можете проверить его с помощью ширины и высоты виджетов, как это сделано в следующем фрагменте кода:
WindowManager wm;
Display ds;
public boolean portrait;
public void checkOrientation() {
wm = getWindowManager();
ds=wm.getDefaultDisplay();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkOrientation();
if (ds.getWidth() > ds.getHeight()) {
// ---landscape mode---
portrait = false;
} else if (ds.getWidth() < ds.getHeight()) {
// ---portrait mode---
portrait = true;
}
}
Ответ 7
View view = getWindow().getDecorView();
int orientation = getResources().getConfiguration().orientation;
if (Configuration.ORIENTATION_LANDSCAPE == orientation) {
relativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.log_landscape));
imageview_Logo.setImageResource(R.drawable.log_landscape_2);
Log.d("Landscape", String.valueOf(orientation));
//Do SomeThing; // Landscape
} else {
relativeLayout.setBackgroundDrawable( getResources().getDrawable(R.drawable.login_bg) );
imageview_Logo.setImageResource(R.drawable.logo_login);
//Do SomeThing; // Portrait
Log.d("Portrait", String.valueOf(orientation));
}