Jak uzyskać wymiary ekranu jako piksele w Androidzie
Stworzyłem kilka niestandardowych elementów i chcę je programowo umieścić w prawym górnym rogu (n
pikseli od górnej krawędzi i m
pikseli od prawej krawędzi). Dlatego muszę uzyskać szerokość i wysokość ekranu, a następnie ustawić pozycję:
int px = screenWidth - m;
int py = screenHeight - n;
Jak uzyskać screenWidth
i screenHeight
w głównej aktywności?
30 answers
Jeśli chcesz mieć wymiary wyświetlacza w pikselach możesz użyć getSize
:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Jeśli nie jesteś w Activity
możesz uzyskać domyślne Display
poprzez WINDOW_SERVICE
:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Jeśli znajdujesz się we fragmencie i chcesz to zakończyć, użyj aktywności.WindowManager (w Xamarin.Android) lub getActivity ().getWindowManager () (w Javie).
Przed wprowadzeniem getSize
(na poziomie API 13), można było użyć metod getWidth
i getHeight
, które są obecnie przestarzałe:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
Do użycia przypadek, który opisujesz, jednak margines/wypełnienie w układzie wydaje się bardziej odpowiedni.
Inny sposób to: DisplayMetrics
Struktura opisująca ogólne informacje o wyświetlaczu, takie jak jego rozmiar, gęstość i skalowanie czcionki. Aby uzyskać dostęp do elementów DisplayMetrics, zainicjuj obiekt w następujący sposób:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Możemy użyć widthPixels
, aby uzyskać informacje dla:
" absolutna szerokość wyświetlacza w pikseli."
Przykład:
Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Api poziom 30 update
final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
// Gets all excluding insets
final WindowInsets windowInsets = metrics.getWindowInsets();
Insets insets = windowInsets.getInsetsIgnoreVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.displayCutout());
int insetsWidth = insets.right + insets.left;
int insetsHeight = insets.top + insets.bottom;
// Legacy size that Display#getSize reports
final Rect bounds = metrics.getBounds();
final Size legacySize = new Size(bounds.width() - insetsWidth,
bounds.height() - insetsHeight);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-23 16:48:14
Jedna droga to:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Jest przestarzały i powinieneś wypróbować następujący kod. Pierwsze dwie linie kodu dają DisplayMetrics
objecs. Obiekty te zawierają pola takie jak heightPixels
, widthPixels
.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Api poziom 30 update
final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
// Gets all excluding insets
final WindowInsets windowInsets = metrics.getWindowInsets();
Insets insets = windowInsets.getInsetsIgnoreVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.displayCutout());
int insetsWidth = insets.right + insets.left;
int insetsHeight = insets.top + insets.bottom;
// Legacy size that Display#getSize reports
final Rect bounds = metrics.getBounds();
final Size legacySize = new Size(bounds.width() - insetsWidth,
bounds.height() - insetsHeight);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-23 16:48:49
Może nie odpowiada na twoje pytanie, ale przydałoby się wiedzieć (szukałem go sam, kiedy przyszedłem do tego pytania), że jeśli potrzebujesz wymiaru widoku, ale twój kod jest wykonywany, gdy jego układ nie został jeszcze ułożony (na przykład w onCreate()
), możesz ustawić ViewTreeObserver.OnGlobalLayoutListener
za pomocą View.getViewTreeObserver().addOnGlobalLayoutListener()
i umieścić tam odpowiedni kod, który potrzebuje wymiaru widoku. Wywołanie zwrotne słuchacza zostanie wywołane po rozplanowaniu układu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-06 21:23:00
(ODPOWIEDŹ na 2012, może być nieaktualna) jeśli chcesz obsługiwać Pre Honeycomb, musisz wprowadzić wsteczną kompatybilność przed API 13. Coś w stylu:
int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Point size = new Point();
w.getDefaultDisplay().getSize(size);
measuredWidth = size.x;
measuredHeight = size.y;
} else {
Display d = w.getDefaultDisplay();
measuredWidth = d.getWidth();
measuredHeight = d.getHeight();
}
Oczywiście przestarzałe metody zostaną ostatecznie usunięte z najnowszych zestawów SDK, ale chociaż nadal polegamy na większości naszych użytkowników posiadających Androida 2.1, 2.2 i 2.3, to właśnie nam pozostało.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-22 22:47:22
Próbowałem wszystkich możliwych "rozwiązań" bezskutecznie i zauważyłem, że aplikacja "Dalvik Explorer" Elliotta Hughesa zawsze pokazuje poprawny wymiar na dowolnym urządzeniu z Androidem/wersji systemu operacyjnego. Skończyłem patrząc na jego projekt open source, który można znaleźć tutaj: https://code.google.com/p/enh/
Oto cały odpowiedni kod:
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
// used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
// used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
EDIT: lekko ulepszona wersja (unikaj zwalniania WYJĄTKÓW w nieobsługiwanej wersji systemu operacyjnego):
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 06:30:31
Najprostszy sposób:
int screenHeight = getResources().getDisplayMetrics().heightPixels;
int screenWidth = getResources().getDisplayMetrics().widthPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-26 10:47:10
Aby uzyskać dostęp do wysokości paska stanu dla urządzeń z Androidem, preferujemy programowy sposób uzyskania go:
Przykładowy kod
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = getResources().getDimensionPixelSize(resId);
}
Zmienna result
podaje wysokość w pikselu.
Do szybkiego dostępu
Aby uzyskać więcej informacji o wysokości Title bar
, Navigation bar
i Content View
, uprzejmie spójrz na rozmiary ekranu urządzenia z systemem Android.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Pierwszy widok (np. przez findViewById()
), a następnie można użyć getWidth() na samym widoku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-12 11:27:47
Mam dwie funkcje, jedną do wysyłania kontekstu, a drugą do uzyskiwania wysokości i szerokości w pikselach:
public static int getWidth(Context mContext){
int width=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
width = size.x;
}
else{
width = display.getWidth(); // Deprecated
}
return width;
}
I
public static int getHeight(Context mContext){
int height=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
height = size.y;
}
else{
height = display.getHeight(); // Deprecated
}
return height;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-09 15:46:32
Do dynamicznego skalowania za pomocą XML istnieje atrybut o nazwie "android: layout_weight"
Poniższy przykład, zmodyfikowany z odpowiedzi synic na ten wątek , pokazuje przycisk, który zajmuje 75% ekranu (waga = .25) oraz widok tekstowy zajmujący pozostałe 25% ekranu (waga = .75).
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text="somebutton">
<TextView android:layout_width="fill_parent"
android:layout_height="Wrap_content"
android:layout_weight=".75">
</LinearLayout>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26
To jest kod, którego używam do zadania:
// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
display.getSize(screen);
} else {
screen.x = display.getWidth();
screen.y = display.getHeight();
}
Wydaje się wystarczająco czysty, a jednak zajmuje się deprecjacją.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-27 14:31:01
Czy to nie jest dużo lepsze rozwiązanie? DisplayMetrics zawiera wszystko, czego potrzebujesz i działa z API 1.
public void getScreenInfo(){
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
heightPixels = metrics.heightPixels;
widthPixels = metrics.widthPixels;
density = metrics.density;
densityDpi = metrics.densityDpi;
}
Można również uzyskać rzeczywisty wyświetlacz (w tym dekory ekranu, takie jak pasek stanu lub pasek nawigacji oprogramowania) za pomocą getRealMetrics , ale działa to tylko na 17+.
Czy coś przeoczyłem?Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-12 20:16:20
Dodaję tylko odpowiedź Francesco. Drugim obserwatorem, który jest bardziej trafny, jeśli chcesz dowiedzieć się o lokalizacji w oknie lub lokalizacji na ekranie jest ViewTreeObserver.OnPreDrawListener()
To również może być użyte do znalezienia innych atrybutów widoku, który jest w większości nieznany w czasie onCreate (), np. pozycja przewinięta, pozycja skalowana.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-16 07:15:23
Używając poniższego kodu w aktywności.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 14:58:56
Znajdź szerokość i wysokość ekranu:
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
Używając tego, możemy uzyskać najnowszy i wyższy SDK 13.
// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
Point size = new Point();
display.getSize(size);
width = size.x;
Log.i("width", "if =>" +width);
}
else {
width = display.getWidth();
Log.i("width", "else =>" +width);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 03:38:40
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 03:45:19
Znalazłem, że to załatwiło sprawę.
Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 19:35:27
Musisz powiedzieć, że jeśli nie jesteś w Activity
, ale w View
(lub masz zmienną typu View
w swoim zakresie), nie ma potrzeby używania WINDOW_SERVICE
. Następnie możesz użyć co najmniej dwóch sposobów.
Pierwszy:
DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();
Drugi:
DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);
Wszystkie te metody, które tutaj nazywamy, nie są przestarzałe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-16 02:21:42
public class AndroidScreenActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
String str_ScreenSize = "The Android Screen is: "
+ dm.widthPixels
+ " x "
+ dm.heightPixels;
TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
mScreenSize.setText(str_ScreenSize);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 03:40:46
Aby uzyskać wymiary ekranu użyj metryki wyświetlacza
DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null)
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display defaultDisplay = windowManager.getDefaultDisplay();
defaultDisplay.getRealMetrics(displayMetrics);
}
Uzyskaj wysokość i szerokość w pikselach
int width =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 10:33:08
To nie jest odpowiedź dla OP, ponieważ chciał wymiary wyświetlacza w rzeczywistych pikselach. Chciałem wymiary w "device-independent-pixels", i zestawianie odpowiedzi stąd https://stackoverflow.com/a/17880012/253938 i tutaj https://stackoverflow.com/a/6656774/253938 wymyśliłem to:
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:56
Możesz uzyskać Wysokość Rozmiar używając :
getResources().getDisplayMetrics().heightPixels;
I Szerokość Rozmiar za pomocą
getResources().getDisplayMetrics().widthPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-09 14:09:44
Istnieje Nieaktualny sposób, aby to zrobić za pomocą DisplayMetrics (API 1), który pozwala uniknąć bałaganu try/catch:
// initialize the DisplayMetrics object
DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();
// populate the DisplayMetrics object with the display characteristics
getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);
// get the width and height
screenWidth = deviceDisplayMetrics.widthPixels;
screenHeight = deviceDisplayMetrics.heightPixels;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 14:39:49
Owinąłbym kod getSize tak:
@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
Point size = new Point();
Display d = a.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
d.getSize(size);
} else {
size.x = d.getWidth();
size.y = d.getHeight();
}
return size;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-21 13:42:35
Dla tego, kto szuka użytecznego wymiaru ekranu Bez paska stanu i paska akcji (również dzięki odpowiedzi Swapnila):
DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
screen_h -= getResources().getDimensionPixelSize(resId);
}
TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-09 09:02:51
Najpierw Załaduj plik XML, a następnie napisz ten kod:
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());
Pokaż szerokość i wysokość zgodnie z rozdzielczością ekranu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-09 15:47:39
Postępuj zgodnie z poniższymi metodami:
public static int getWidthScreen(Context context) {
return getDisplayMetrics(context).widthPixels;
}
public static int getHeightScreen(Context context) {
return getDisplayMetrics(context).heightPixels;
}
private static DisplayMetrics getDisplayMetrics(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-01 19:52:58
Kotlin
fun getScreenHeight(activity: Activity): Int {
val metrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(metrics)
return metrics.heightPixels
}
fun getScreenWidth(activity: Activity): Int {
val metrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(metrics)
return metrics.widthPixels
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Są chwile, kiedy trzeba znać dokładne wymiary dostępnej przestrzeni dla układu, gdy w ćwiczeniu onCreate. Po pewnym namyśle wypracowałem ten sposób.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivityForResult(new Intent(this, Measure.class), 1);
// Return without setting the layout, that will be done in onActivityResult.
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -1);
// Width is now set to the precise available width, and a layout can now be created. ...
}
}
public final class Measure extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
Measure.this.setResult(Activity.RESULT_OK, data);
// Tell this activity to finish, so the result is passed back.
Measure.this.finish();
}
}
}
Jeśli z jakiegoś powodu nie chcesz dodawać kolejnej aktywności do manifestu Androida, możesz to zrobić w ten sposób:
public class MainActivity extends Activity {
static Activity measuringActivity;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras == null) {
extras = new Bundle();
}
int width = extras.getInt("Width", -2);
if (width == -2) {
// First time in, just start another copy of this activity.
extras.putInt("Width", -1);
startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
// Return without setting the layout, that will be done in onActivityResult.
return;
}
if (width == -1) {
// Second time in, here is where the measurement takes place.
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -3);
// Width is now set to the precise available width, and a layout can now be created.
...
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
// Tell the (second) activity to finish.
MainActivity.measuringActivity.finish();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-09 10:08:13
Jeśli nie chcesz mieć narzutu Okienmanagerów, punktów lub wyświetlaczy, możesz pobrać atrybuty wysokości i szerokości najwyższego elementu widoku w XML, pod warunkiem, że jego wysokość i szerokość są ustawione na match_parent. (Jest to prawdą, o ile układ zajmuje cały ekran.)
Na przykład, jeśli twój XML zaczyna się od czegoś takiego:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/entireLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
Następnie findViewById(R.id.entireLayout).getWidth()
zwróci szerokość ekranu, a findViewById(R.id.entireLayout).getHeight()
zwróci wysokość ekranu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-26 18:35:05