2015-09-02 60 views
20

Mam App Widget, który po zaktualizowaniu pobiera obraz o wymiarach dopasowanych do widżetu i umieszcza ten obraz w postaci ImageView (przez RemoteViews). Działa dobrze.Wykryj obrót ekranu głównego Androida

Ale dla urządzeń obsługujących obrót ekranu domu (i nie mówię o rotacji np Activity względu na orientację urządzenia, ale o rotacji ekranu domu sama) stosunek wymiarów i aspektów widżetu zmienia się nieco podczas przechodzenia z krajobrazu do portretu i odwrotnie ... tzn. ustalony rozmiar nie jest zachowywany.

Tak więc, mój widget musi być w stanie wykryć, kiedy ekran główny obraca się i pobrać nowy obraz (lub przynajmniej załadować inny wstępnie pobrany obraz).

Nie mogę dla mojego życia określić, czy i jak jest to możliwe. Jakieś wskazówki?

+0

http://stackoverflow.com/questions/2435548/how-to-detect-orientation-change-in-home-screen-widget – codevscolor

+0

Dzięki za downvoting @andro_abc, ale nie widzę odpowiedzi, która działa w tym wątku – drmrbrewer

+0

okey..Nie obniżyłem go .. może b ktoś inny :) – codevscolor

Odpowiedz

1

Użyj metody działania onConfigurationChanged. Zobacz następujący kod:

@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(); 
} 
} 

Dobrze więc dla widżetów musimy dodać naszą klasę aplikacji, jak poniżej i nie zapomnij zadeklarować to w oczywisty również metoda zasadzie wysyła aktualizację transmitowany do wszystkich wystąpień widżetu .

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); 
} 
} 

iw oczywisty ...

<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 --> 

+0

Chodzi o to, mam na myśli raczej App Widget niż działanie – drmrbrewer

1

Sprawdź ten kod działa:

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(); 

    } 
    }); 
+0

Jakie jest znaczenie dla pytania o ustawienie OnClickListener dla przycisku? – drmrbrewer

+0

Wykryje on onclick, a nie zmiany konfiguracji onconfiguration, gdy obracamy się w czasie rzeczywistym, i ponowne uruchomienie działania. – Androider

1

Być może można wykadrować obraz z przezroczystym tłem. Jeśli obraz jest wystarczająco mały, aby zmieścić się również po obróceniu, nie trzeba go ponownie pobierać.

+0

Czy na pewno @ MZ6? Mam już overaged 'onAppWidgetOptionsChanged', ponieważ już reaguję na zmianę rozmiaru widżetu na ekranie głównym, aby określić nowy rozmiar i pobrać nowy obraz. Ale wydaje się, że nie jest to wywołane w odpowiedzi na zmiany w orientacji ekranu głównego ... robi to za Ciebie? – drmrbrewer

+0

Niestety, zła odpowiedź, 'onAppWidgetOptionsChanged' nie jest wywoływana podczas obracania ekranu. Mój widget nie reagował po obróceniu ekranu i wypróbował rozwiązanie 'onConfigurationChanged' bez radości, a następnie rozwiązałem poprawnie aktualizację aplikacji, dlatego się pomyliłem. Edytuję swoją odpowiedź i sugeruję nowe rozwiązanie. – MZ6

1

Możesz wysłuchać transmisji ACTION_CONFIGURATION_CHANGED wysyłanej przez system Android, kiedy zmieniła się bieżąca konfiguracja urządzenia (orientacja, ustawienia regionalne itp.). Zgodnie z dokumentacją:

ACTION_CONFIGURATION_CHANGED:

Broadcast Działanie: prąd konfiguracji urządzenia (orientacja, locale, etc) został zmieniony. Kiedy nastąpi taka zmiana, trzeba będzie przebudować UI (zobacz hierarchię ) na podstawie tych nowych informacji; w przypadku większości aplikacji aplikacje nie muszą się tym martwić, ponieważ system zadba o zatrzymanie i ponowne uruchomienie aplikacji, aby upewnić się, że widzi nowe zmiany. Niektóre kody systemowe, które nie mogą zostać ponownie uruchomione, będą musiały być uważnie obserwowane i obsłużyć je odpowiednio: .

Nie można tego odebrać za pomocą komponentów zadeklarowanych w manifestach, tylko pod warunkiem zarejestrowania się w tym celu za pomocą Context.registerReceiver().

Jest to chroniona funkcja, którą można wysłać tylko przez system.

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(); 
        } 
       } 
      } 
     }; 
    } 
+0

Dostawca może zostać zniszczony w dowolnym momencie - w takim przypadku odbiornik wycieknie. Prawdopodobnie później, w onDisabled, wystąpiłoby również w NPE, ponieważ mOrientationChangeReceiver ma wartość NULL dla nowej instancji dostawcy. Widżet aplikacji jest kontekstem tymczasowym, więc zarejestrowany odbiorca nie jest odpowiedni w tej sytuacji. – Tom

1

Można go sprawdzając za pomocą widgetów szerokość i wysokość, tak jak w poniższym fragmencie kodu:

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

skorzystać z poniższego kodu, aby wykryć orientację: -

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)); 
    } 
0
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)); 
}