Détecter la rotation de L'écran D'accueil Android
j'ai un App Widget qui, lorsqu'elle est mise à jour, récupère une image ayant des dimensions pour correspondre au widget, et place cette image dans un ImageView
(via RemoteViews
). Il fonctionne très bien.
sauf pour les dispositifs qui supportent la rotation de la écran d'accueil (et je ne parle pas de rotation, par exemple, une Activity
basé sur l'orientation de l'appareil, mais à propos de la rotation de la écran d'accueil lui-même) les dimensions et le rapport d'aspect du widget change un peu quand on passe du paysage au portrait et vice versa... c'est à dire une taille fixe n'est pas maintenu.
alors, mon widget doit être capable de détecter quand le écran d'accueil tourne, et récupère une nouvelle image (ou au moins charge une image pré-compilée différente).
Je ne peux pas, pour ma vie, déterminer si et comment c'est possible. Des indices?
7 réponses
Utilisez le code ci-dessous pour détecter l'orientation: -
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));
}
Vérifier ce code, il fonctionne:
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();
}
});
utilisez la méthode d'activité onConfigurationChanged. Voir le code suivant:
@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();
}
}
Ok donc pour les widgets nous devons ajouter notre classe d'application comme ci-dessous et n'oubliez pas de le déclarer dans manifest aussi, la méthode envoie essentiellement un message de mise à jour à toutes les instances de votre widget.
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);
}
}
et dans le manifeste...
<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 -->
peut-être pourriez-vous encadrer votre image avec un fond transparent. Si l'image est assez petite pour s'adapter aussi lors de la rotation, vous n'aurez pas besoin de le récupérer.
Vous pouvez écouter pour broadcast ACTION_CONFIGURATION_CHANGED qui est envoyé par le système android lorsque la Configuration actuelle du périphérique (orientation, locale, etc) a changé. Selon la documentation :
ACTION_CONFIGURATION_CHANGED :
action de diffusion: la Configuration actuelle du dispositif (orientation, paramètres régionaux, etc) a changé. Lorsqu'un tel changement se produit, l'ISU (voir hiérarchie) devront être reconstruits sur la base de cette information; pour la plupart des partie, les applications n'ont pas besoin de s'inquiéter à ce sujet, parce que le système se chargera d'arrêter et de redémarrer l'application pour s'assurer qu'il voit les nouveaux changements. Un code système qui ne peut pas être redémarré devra surveiller cette action et de gérer approprié.
Vous ne pouvez pas recevoir ceci à travers les composants déclarés dans les manifestes, seulement en l'enregistrant explicitement avec Contexte.registerReceiver ().
il s'agit d'une intention protégée qui peut uniquement envoyées par le système.
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();
}
}
}
};
}
Vous pouvez le vérifier en utilisant les widgets width et height comme fait dans l'extrait de code suivant:
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;
}
}
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));
}