在这篇文章中进一步说明了我开发Android UI以满足各种屏幕尺寸的两种方法。在您询问我在多大程度上阅读/研究了针对各种屏幕尺寸的餐饮问题之前,我已经了解了涵盖here和here的主题以及更多有关支持屏幕的文章大小。此外,我已经通过几个涉及这两种方法的帖子。
使用这两种方法,我将屏幕布局类别划分为4,即小,正常,大和x大,如here所示。
我创建屏幕的第一种方法和过去的方法是创建属于小型,普通,大型和x大型类别的XML和相应的活动,然后在相应活动中的每个XML中充气和自定义视图。在我的欢迎屏幕中,我使用下面的代码确定将根据设备的分辨率和屏幕尺寸(以英寸为单位)显示哪些活动。
//!< splashScreenAnim() - Splash screen animation
public boolean splashScreenAnim() {
// For tracking purposes record in logcat SplashScreenThread() method has been called
Log.i(TAG + "onCreate()", "SplashScreenThread(); HAS STARTED");
// Thread for the display of the SplashScreen
splashScreenAnimThread = new Thread() {
@Override
public void run() {
try { //
int waited = 0;
while(_active && (waited < splashScreenAnimDelay)) {
sleep(100);
if(_active) {
waited += 100;
}
}
} catch(InterruptedException e) { //
Log.e(TAG + "SplashScreenThread()", "SplashScreenThread() ERROR IS AS FOLLOWS: " + e.toString());
} finally {
//
finish();
//
Log.w(TAG, "CHECK IF android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB");
//
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
Log.i(TAG, "CHECK IF android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB");
// Obtain the normal device display area
Display display = getWindowManager().getDefaultDisplay();
// Obtain the normal device display metrics
DisplayMetrics outMetrics = new DisplayMetrics();
Log.i(TAG, "outMetrics is " + outMetrics);
//
display.getMetrics(outMetrics);
// Obtain the logical density of the display
float density = getResources().getDisplayMetrics().density;
Log.i(TAG, "Logical density of the display is " + density);
// Obtain screen size in inches
ScreenInches screenInches = new ScreenInches(outMetrics, density);
double screenSizeInInches = screenInches.screenSizeInInches();
// Call the layout based on the screen dimensions
if(((int) outMetrics.widthPixels < 800 && (int) outMetrics.heightPixels < 480)) {
Intent underDevltScreenNormal800by480 = new Intent(SplashScreen.this, TempScreenNormal800by480.class);
startActivity(underDevltScreenNormal800by480);
Log.e(TAG, "UnderDevltScreenNormal800by480.java called.");
} else if(((int) outMetrics.widthPixels == 1440 && (int) outMetrics.heightPixels == 900) | (int) outMetrics.widthPixels == 1440) {
Intent tempScnXLarge = new Intent(SplashScreen.this, TempScnXLarge.class);
startActivity(tempScnXLarge);
Log.i(TAG, "tempScnXLarge.java called.");
} else if( (screenSizeInInches >= 3.00 && screenSizeInInches <= 5.50)
&& ((int) outMetrics.widthPixels >= 800 && (int)outMetrics.widthPixels <= 960)
&& ((int) outMetrics.heightPixels >= 480) && (int) outMetrics.heightPixels <= 540) {
Intent loginScreen = new Intent(SplashScreen.this, ScnNormal800by480.class);
startActivity(loginScreen);
Log.i(TAG, "scnNormal800by480.java called.");
} else if( (screenSizeInInches >= 3.00 && screenSizeInInches < 5.50)
&& ((int) outMetrics.widthPixels > 1024 && (int)outMetrics.widthPixels <= 1280)
&& ((int) outMetrics.heightPixels > 600) && (int) outMetrics.heightPixels <= 800) {
Intent loginScreen = new Intent(SplashScreen.this, ScnNormal.class);
startActivity(loginScreen);
Log.i(TAG, "scnNormal.java called.");
} else if( (screenSizeInInches >= 3.00 && screenSizeInInches < 5.50)
&& ((int) outMetrics.widthPixels > 1280 && (int)outMetrics.widthPixels <= 1920)
&& ((int) outMetrics.heightPixels > 768) && (int) outMetrics.heightPixels <= 1080) {
Intent loginScreen = new Intent(SplashScreen.this, ScnNormal1920by1080.class);
startActivity(loginScreen);
Log.i(TAG, "scnNormal1920by1080.java called.");
} else if( (screenSizeInInches >= 5.00 && screenSizeInInches < 10.1)
&& ((int) outMetrics.widthPixels > 960 && (int)outMetrics.widthPixels <= 1024)
&& ((int) outMetrics.heightPixels > 540) && (int) outMetrics.heightPixels <= 768) {
Intent loginScreen = new Intent(SplashScreen.this, ScnLarge.class);
startActivity(loginScreen);
Log.i(TAG, "scnLarge.java called.");
} else if( (screenSizeInInches >= 6.0 && screenSizeInInches < 8.0)
&& ((int) outMetrics.widthPixels > 1024 && (int)outMetrics.widthPixels <= 1280)
&& ((int) outMetrics.heightPixels > 768) && (int) outMetrics.heightPixels <= 800) {
Intent loginScreen = new Intent(SplashScreen.this, ScnLarge1280by800.class);
startActivity(loginScreen);
Log.i(TAG, " scnLarge1280by800.java called.");
} else if( (screenSizeInInches >= 8.0 && screenSizeInInches < 10.5)
&& ((int) outMetrics.widthPixels > 1024 && (int)outMetrics.widthPixels <= 1280)
&& ((int) outMetrics.heightPixels > 600) && (int) outMetrics.heightPixels <= 800) {
Intent loginScreen = new Intent(SplashScreen.this, ScnXLarge.class);
startActivity(loginScreen);
Log.i(TAG, "scnXLarge.java called.");
} else if( (screenSizeInInches >= 7.0 && screenSizeInInches < 10.5)
&& ((int) outMetrics.widthPixels > 1280 && (int)outMetrics.widthPixels <= 2560)
&& ((int) outMetrics.heightPixels > 800) && (int) outMetrics.heightPixels <= 1600) {
Intent tempScnXLarge = new Intent(SplashScreen.this, TempScnXLarge.class);
startActivity(tempScnXLarge);
Log.i(TAG, "tempScnXLarge.java called.");
}
androidOSStatus = true;
} else {
androidOSStatus = false;
}
}
}
};
splashScreenAnimThread.start();
return androidOSStatus;
}
第一种方法在选择正确的活动方面起作用,但当选的活动并没有在没有缩放的情况下假设屏幕分辨率不完全匹配。
在我的第二种方法中,我采用了在要调用的活动中以编程方式构建UI的方法,而不是常规的扩展XML视图的方法。使用这种方法,我已经能够像我在下面的代码中为imageview和textview所做的那样缩放每个视图:
package com.example.test;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.InputType;
import android.text.format.Time;
import android.text.method.PasswordTransformationMethod;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.View.OnFocusChangeListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.inputmethod.EditorInfo;
public class ScnNormal800by480 extends Activity {
/** Pubic vars */
public String TAG = "ScnNormal800by480";
public TextView tvDealerSupport;
public InputMethodManager tmpImm;
public double normal800by480WScale, normal800by480HScale;
public Typeface officialBoldFont, officialRegularFont;
public ImageView ivLogo;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Obtain the normal device display area
Display display = getWindowManager().getDefaultDisplay();
// Obtain the normal device display metrics
DisplayMetrics outMetrics = new DisplayMetrics();
Log.w(TAG, "outMetrics is " + outMetrics);
display.getMetrics(outMetrics);
// Obtain the logical density of the display
float density = getResources().getDisplayMetrics().density;
Log.w(TAG, "Logical density of the display is " + density);
// Fetch W and H scaling factors
NormalScreenScaling800by480 normalScreenScaling800by480 = new NormalScreenScaling800by480(outMetrics, density);
normal800by480WScale = normalScreenScaling800by480.normalScaleW();
normal800by480HScale = normalScreenScaling800by480.normalScaleH();
Log.w(TAG + " - normal800by480WScale", "normal800by480WScale: " + normal800by480WScale);
Log.w(TAG + " - normal800by480HScale", "normal800by480HScale: " + normal800by480HScale);
//
ScreenInches screenInches = new ScreenInches(outMetrics, density);
float getHeightDpi = screenInches.getHeightDpi();
float getWidthDpi = screenInches.getWidthDpi();
double screenSizeInInches = screenInches.screenSizeInInches();
// Set official font
officialRegularFont = Typeface.createFromAsset(getAssets(), "square721extendedreg.ttf");
officialBoldFont = Typeface.createFromAsset(getAssets(), "square721extendedbold.ttf");
// Set imm for all the edittexts
tmpImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
Log.w(TAG, "- - - Main RL - - -");
// Create main RL params
RelativeLayout.LayoutParams rlMainlayoutParams
= new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
// Create main relative layout
RelativeLayout rlMain = new RelativeLayout(this);
rlMain.setLayoutParams(rlMainlayoutParams);
//rlMain.setBackgroundResource(R.drawable.bgndlogin);
rlMain.setBackgroundColor(Color.BLACK);
// Create layout paramaters
RelativeLayout.LayoutParams ivLogoParams =
new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ivLogoParams.width = (int) Math.round(208 * normal800by480WScale);
ivLogoParams.height = (int) Math.round(60 * normal800by480HScale);
ivLogoParams.topMargin = (int) Math.round(17 * normal800by480HScale);
ivLogoParams.leftMargin = (int) Math.round(16 * normal800by480WScale);
// Create the and customise the ImageView
ivLogo = new ImageView(this);
ivLogo.setLayoutParams(ivLogoParams);
ivLogo.setBackgroundResource(R.drawable.bgelogo);
// Set layout parameters
RelativeLayout.LayoutParams tvDealerSupportParams =
new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tvDealerSupportParams.topMargin = (int) Math.round(33 * normal800by480HScale);
tvDealerSupportParams.leftMargin = (int) Math.round(225 * normal800by480WScale);
tvDealerSupportParams.width = (int) Math.round(960 * normal800by480WScale);
// Create and customise the textview
tvDealerSupport = new TextView(this);
tvDealerSupport.setLayoutParams(tvDealerSupportParams);
tvDealerSupport.setText("DEALER SUPPORT ");
tvDealerSupport.setTextColor(Color.BLACK);
tvDealerSupport.setTypeface(officialBoldFont);
tvDealerSupport.setBackgroundColor(Color.parseColor("#FFCC00"));
tvDealerSupport.setGravity(Gravity.RIGHT);
// Set the text size based on the screen dimensions
if((int) outMetrics.widthPixels <= 854 && outMetrics.heightPixels <= 480) {
tvDealerSupport.setTextSize(9.7f);
} else if( ((int) outMetrics.widthPixels > 854 && (int)outMetrics.widthPixels <= 960)
&& ((int) outMetrics.heightPixels > 480) && (int) outMetrics.heightPixels <= 540) {
tvDealerSupport.setTextSize(11.7f);
}
// Add all view to the main relative layout
Log.w(TAG, "- - - Addition to main RL - - -");
rlMain.addView(ivLogo);
rlMain.addView(tvDealerSupport);
// Set the activity content to an explicit view.
setContentView(rlMain);
}
public class NormalScreenScaling800by480 {
/** Private vars */
private DisplayMetrics _outMetrics;
private float _density;
private String TAG = "NormalScreenScaling800by480";
/** Normal i.e. 800 by 480 screen scaling constructor
*/
public NormalScreenScaling800by480(DisplayMetrics outMetrics, float density) {
_outMetrics = outMetrics;
_density = density;
}
/** Returns width scaling factor for normal screen sizes i.e. 800 by 480
*/
public double normalScaleW() {
double dpWidth = _outMetrics.widthPixels / 1.5;
Log.i(TAG, "For NORMAL 800 by 480 screen scaling _outMetrics.widthPixels is: " + _outMetrics.widthPixels);
Log.i(TAG, "For NORMAL 800 by 480 screen scaling _density is: " + _density);
Log.i(TAG, "For NORMAL 800 by 480 screen scaling width dp is: " + dpWidth);
double scaleW = dpWidth/800;
Log.i(TAG, "Width scaling factor NORMAL 800 by 480 screens is: " + scaleW);
return scaleW;
}
/** Returns height scaling factor for normal screen sizes i.e. 800 by 480
*/
public double normalScaleH() {
double dpHeight = _outMetrics.heightPixels / 1.5;
Log.i(TAG, "For NORMAL 800 by 480 screen scaling _outMetrics.heightPixels is: " + _outMetrics.heightPixels);
Log.i(TAG, "For NORMAL 800 by 480 screen scaling _density is: " + _density);
Log.i(TAG, "For NORMAL 800 by 480 screen scaling height dp is: " + dpHeight);
double scaleH = dpHeight/480;
Log.i(TAG, "Height scaling factor NORMAL 800 by 480 screens is: " + scaleH);
return scaleH;
}
}
/*! Screen sizes in inches */
public class ScreenInches {
/** Private vars */
private DisplayMetrics _outMetrics;
private float _density;
private String TAG = "ScreenInches";
/** Screen inches calculation constructor
*/
public ScreenInches(DisplayMetrics outMetrics, float density) {
_outMetrics = outMetrics;
_density = density;
}
/** Returns screen inches
*/
public double screenSizeInInches() {
//
float widthDpi = _outMetrics.xdpi;
Log.i(TAG, "widthDpi = _outMetrics.xdpi; is: " + widthDpi);
float heightDpi = _outMetrics.ydpi;
Log.i(TAG, "heightDpi = _outMetrics.ydpi; is: " + heightDpi);
//
float widthPixels = _outMetrics.widthPixels;
Log.i(TAG, "_outMetrics.widthPixels is: " + _outMetrics.widthPixels);
float heightPixels = _outMetrics.heightPixels ;
Log.i(TAG, "_outMetrics.heightPixels is: " + _outMetrics.heightPixels);
//
float widthInches = widthPixels / widthDpi;
Log.i(TAG, "widthInches = widthPixels / widthDpi is: " + widthInches);
float heightInches = heightPixels / heightDpi;
Log.i(TAG, "heightInches = heightPixels / heightDpi is: " + heightInches);
// The size of the diagonal in inches is equal to the square root of the height in inches squared plus the width in inches squared.
double diagonalInches = Math.sqrt(
(widthInches * widthInches)
+ (heightInches * heightInches));
Log.i(TAG, " diagonalInches is: " + diagonalInches);
//
double diagonalInches2 = Math.sqrt((widthPixels * widthPixels) + (heightPixels * heightPixels));
double inchDiag = diagonalInches2/_density;
//
return diagonalInches;
//return inchDiag;
}
//
public float getWidthDpi() {
//
float widthDpi = _outMetrics.xdpi;
Log.i(TAG, "widthDpi = _outMetrics.xdpi; is: " + widthDpi);
return widthDpi;
}
//
public float getHeightDpi() {
float heightDpi = _outMetrics.ydpi;
Log.i(TAG, "heightDpi = _outMetrics.ydpi; is: " + heightDpi);
return heightDpi;
}
}
}
根据您对各种屏幕尺寸(即小尺寸,普通尺寸,大尺寸和X尺寸)的体验以及每种尺寸下的各种屏幕分辨率的经验,我将如何进一步改进第二种方法?我问,因为我打算在片段的UI设计中使用编程方法。
感谢。