现在,市场上android的机型太多,如何让自己的应用更多的适配不同的机型,这是一个非常现实的并且是要处理解决的问题。android官方给出的解决文档是从三个方向来分析处理的。
(1)支持不同屏幕大小的设备(Supporting Different Screen Sizes)
1.1 合理使用wrap_content,match_parent
1.2 尽可能的使用 RelativeLayout
1.3 针对不同的机型,使用不同的布局文件(Use Size Qualifiers):
res/layout/main.xml
res/layout-large/main.xml
1.4 尽量使用点9图片(Use Nine-patch Bitmaps)
(2)支持不同屏幕密度的设备(Supporting Different Screen Densities)
2.1 使用与密度无关的相素单位(Use Density-independent Pixels)-----dp,sp
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clickme"
android:layout_marginTop="20dp" />
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
2.2 对不同的设备提供可选择的图片(Provide Alternative Bitmaps)
不同分辨率之间的比例关系:
xhdpi: 2.0
hdpi: 1.5
mdpi: 1.0 (baseline)
ldpi: 0.75
awesomeimage.png图片位置的放置:
MyProject/
res/
drawable-xhdpi/
awesomeimage.png
drawable-hdpi/
awesomeimage.png
drawable-mdpi/
awesomeimage.png
drawable-ldpi/
awesomeimage.png
(3)实现自适应用户界面流(Implementing Adaptative UI Flows)
3.1 识别当前的布局文件是那个(Determine the Current Layout):这个主要是采用标志位的方式来得到当前使用的布局文件
public class NewsReaderActivity extends FragmentActivity {
boolean mIsDualPane;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
View articleView = findViewById(R.id.article);
mIsDualPane = articleView != null &&
articleView.getVisibility() == View.VISIBLE;
}
}
针对当前布局文件没有的控件(eg:button),要对其进行判断是否为null:
Button catButton = (Button) findViewById(R.id.categorybutton);
OnClickListener listener = /* create your listener here */;
if (catButton != null) {
catButton.setOnClickListener(listener);
}
3.2 根据当前布局,使用不同的响应操作(React According to Current Layout)
public void onHeadlineSelected(int index) {
mArtIndex = index;
if (mIsDualPane) {
/* display article on the right pane */
mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
} else {
/* start a separate activity */
Intent intent = new Intent(this, ArticleActivity.class);
intent.putExtra("catIndex", mCatIndex);
intent.putExtra("artIndex", index);
startActivity(intent);
}
}
final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" };
public void onCreate(Bundle savedInstanceState) {
....
if (mIsDualPane) {
/* use tabs for navigation */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);
int i;
for (i = 0; i < CATEGORIES.length; i++) {
actionBar.addTab(actionBar.newTab().setText(
CATEGORIES[i]).setTabListener(handler));
}
actionBar.setSelectedNavigationItem(selTab);
}
else {
/* use list navigation (spinner) */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter adap = new ArrayAdapter(this,
R.layout.headline_item, CATEGORIES);
actionBar.setListNavigationCallbacks(adap, handler);
}
}
3.3 在其它的activity中复用Fragments(Reuse Fragments in Other Activities):
在这一部分,android提供了一个解决同一操作,不同响应的解决方案,就是在父类中提供一个interface,在子类中实现interface,以实现不同的操作:
public class HeadlinesFragment extends ListFragment {
...
OnHeadlineSelectedListener mHeadlineSelectedListener = null;
/* Must be implemented by host activity */
public interface OnHeadlineSelectedListener {
public void onHeadlineSelected(int index);
}
...
public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {
mHeadlineSelectedListener = listener;
}
}
public class HeadlinesFragment extends ListFragment {
...
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
if (null != mHeadlineSelectedListener) {
mHeadlineSelectedListener.onHeadlineSelected(position);
}
}
...
}
原始资料:
1.Designing for Multiple Screens:
http://developer.android.com/training/multiscreen/index.html
2.Supporting Different Screen Sizes:
http://developer.android.com/training/multiscreen/screensizes.html
3.Supporting Different Screen Densities:
http://developer.android.com/training/multiscreen/screendensities.html
4.Implementing Adaptative UI Flows:
http://developer.android.com/training/multiscreen/adaptui.html
参考资料:
1.
http://blog.csdn.net/hfreeman2008/article/details/9351687