现在,市场上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