Android多解析度適配框架(3)— 使用指南

Android多解析度適配框架(3)— 使用指南

探索Android軟鍵盤的疑難雜症
深入探討Android非同步精髓Handler
詳解Android主流框架不可或缺的基石
站在原始碼的肩膀上全解Scroller工作機制


Android多解析度適配框架(1)— 核心基礎
Android多解析度適配框架(2)— 原理剖析
Android多解析度適配框架(3)— 使用指南


自定義View系列教程00–推翻自己和過往,重學自定義View
自定義View系列教程01–常用工具介紹
自定義View系列教程02–onMeasure原始碼詳盡分析
自定義View系列教程03–onLayout原始碼詳盡分析
自定義View系列教程04–Draw原始碼分析及其實踐
自定義View系列教程05–示例分析
自定義View系列教程06–詳解View的Touch事件處理
自定義View系列教程07–詳解ViewGroup分發Touch事件
自定義View系列教程08–滑動衝突的產生及其處理


PS:Android多解析度適配框架視訊教程同步更新啦


在上一篇文章中,我們分析了Android多解析度適配框架的原理和程式碼實現。

在此,結合例項展示該框架的使用。

在展示的過程中,為了對照適配的效果,準備兩部測試手機:

華為P7,解析度為1920*1080,dpi為480
HTC T392,解析度為800*480,dpi為240

嗯哼,開始吧。


Hello World

我們先通過一個簡單的示例來了解該框架的基本使用

第一步:編寫佈局程式碼

<?xml version="1.0" encoding="utf-8"?>
<!--原創作者:谷哥的小弟-->
<!--部落格地址:http://blog.csdn.net/lfdfhl-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cc.displayutil2.MainActivity">
<Button
android:id="@ id/button"
android:layout_width="460px"
android:layout_height="200px"
android:textSize="50px"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:textColor="@android:color/holo_red_dark"
android:text="BUTTON" />
<LinearLayout
android:layout_below="@id/button"
android:layout_marginTop="100px"
android:background="@android:color/holo_green_dark"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="800px">
<TextView
android:id="@ id/textView"
android:textSize="40px"
android:layout_width="620px"
android:layout_height="300px"
android:layout_marginTop="50px"
android:layout_marginLeft="50px"
android:paddingLeft="20px"
android:paddingRight="20px"
android:background="@android:color/white"
android:gravity="left|center_vertical"
android:text="谷歌和白度,都是做搜尋的..."/>
<ImageView
android:background="@android:color/white"
android:layout_width="300px"
android:layout_height="300px"
android:layout_marginLeft="150px"
android:layout_marginTop="140px"
android:scaleType="centerCrop"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
</RelativeLayout>

該佈局檔案比較簡單,包括了幾個常用的控制元件比如:Button,TextView以及ImageView,並且使用了padding和margin為控制元件指定位置和尺寸。

第二步:呼叫框架實現UI的縮放

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View rootView=findViewById(android.R.id.content);
SupportMultipleScreensUtil.init(getApplication());
SupportMultipleScreensUtil.scale(rootView);
}

在Activity的onCreate( )中找到該介面的根佈局,即id為android.R.id.content的View。
在初始化SupportMultipleScreensUtil後傳入rootView,框架就會將該根佈局下的所有子View按照比例縮放。

第三步:檢視適配的效果

先看該UI在P7上的顯示:

這裡寫圖片描述

再看該UI在T392上的顯示:

這裡寫圖片描述

嗯哼,看到了吧:View的大小和字型的大小均按照比例進行了縮放,而且圖片沒有失真


動態縮放

有時候,我們可能需要利用程式碼來動態新增一個View,此時又該如何使用SupportMultipleScreensUtil縮放這個新新增的View呢?

請看下面的示例:
利用程式碼為LinearLayout動態新增TextView和ImageView

/**
* 原創作者:
* 谷哥的小弟
*
* 部落格地址:
* http://blog.csdn.net/lfdfhl
*/
private void addViewToLinearLayout(){
mContext=this;
int match_parent=ViewGroup.LayoutParams.MATCH_PARENT;
int wrap_content=ViewGroup.LayoutParams.WRAP_CONTENT;
mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout);
mLayoutParams=new LinearLayout.LayoutParams(match_parent,wrap_content);
TextView textView=new TextView(mContext);
mLayoutParams.width=1000;
mLayoutParams.height=160;
textView.setText("女朋友的照片");
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,60);
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.BLUE);
textView.setPadding(10,10,10,10);
textView.setGravity(Gravity.CENTER);
mLayoutParams.setMargins(35,35,35,35);
mLayoutParams.gravity=Gravity.CENTER;
textView.setLayoutParams(mLayoutParams);
SupportMultipleScreensUtil.scale(textView);
mLinearLayout.addView(textView);
ImageView imageView=new ImageView(mContext);
mLayoutParams=new LinearLayout.LayoutParams(match_parent,wrap_content);
mLayoutParams.width=600;
mLayoutParams.height=600;
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Drawable drawable=getResources().getDrawable(R.drawable.girl);
imageView.setImageDrawable(drawable);
imageView.setLayoutParams(mLayoutParams);
SupportMultipleScreensUtil.scale(imageView);
mLinearLayout.addView(imageView);
}

在這段程式碼中先完成對於View的寬高,顏色,文字等屬性的設定,然後呼叫SupportMultipleScreensUtil.scale()方法縮放該View再新增進LinearLayout即可。

檢視適配的效果

先看該UI在P7上的顯示:

這裡寫圖片描述

再看該UI在T392上的顯示:

這裡寫圖片描述

再次提醒,在此過程中務必使用px作為尺寸單位。

除此以外,有時候還需要利用LayoutInflater生成一個View,對於該View我們同樣需要對其進行類似的操作:

View view=LayoutInflater.from(mContext).inflate();

SupportMultipleScreensUtil.scale(view);


綜合示例

看了剛才這兩個例子,大家可能覺得比較簡單,還是不能夠領會到利用SupportMultipleScreensUtil實現多解析度適配的簡潔與魅力。好吧,再來看一個熟悉的頁面,比如APP的首頁,它常常包括一個展示圖片的ViewPager、一個包含多個條目的list列表。嗯哼,我們再來瞅瞅它的實現和適配。

第一步:完成UI佈局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@ id/viewPagerRelativeLayout"
android:layout_width="match_parent"
android:layout_height="600px">
<android.support.v4.view.ViewPager
android:id="@ id/guide_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@ id/dotsLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50px"
android:orientation="horizontal">
</LinearLayout>
</RelativeLayout>
<TextView
android:id="@ id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/viewPagerRelativeLayout"
android:background="@android:color/holo_green_dark"
android:gravity="center"
android:text="新聞概要"
android:textColor="@android:color/white"
android:textSize="100px"
android:textStyle="normal" />
<ListView
android:id="@ id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/textView">
</ListView>
</RelativeLayout>

在該Activity的佈局檔案中主要包括了:ViewPager,Indicator佈局,TextView,以及一個ListView。和之前強調的一樣,在佈局中使用的尺寸單位均是px,就不再贅述了。
關於ListView的item的佈局亦於此類似,故不再提及。

第二步:實現ListView的Adapter

LayoutInflater inflater = LayoutInflater.from(context);

convertView = inflater.inflate(R.layout.item, null);

SupportMultipleScreensUtil.scale(convertView);

在使用LayoutInflater生成item的View之後,利用SupportMultipleScreensUtil.scale( )對其縮放。

第三步:完成Activity程式碼的編寫

private void initDots() {
dotImageViews = new ImageView[mViewPagerAdapter.getCount()];
for (int i = 0; i < dotImageViews.length; i  ) {
LinearLayout layout = new LinearLayout(mContext);
ImageView imageView = new ImageView(mContext);
imageView.setLayoutParams(new ViewGroup.LayoutParams(20, 20));
if (i == 0) {
imageView.setBackgroundResource(white);
} else {
layout.setPadding(20, 0, 0, 0);
imageView.setBackgroundResource(black);
}
dotImageViews[i] = imageView;
layout.addView(imageView);
SupportMultipleScreensUtil.scale(layout);
mDotsLinearLayout.addView(layout);
}
}

一般而言,指示器Indicator的小圓點個數都是根據ViewPager中圖片的個數而動態生成的。所以在這個過程中,務必對每個小圓進行縮放。

先看該UI在P7上的顯示:

這裡寫圖片描述

再看該UI在T392上的顯示:

這裡寫圖片描述


總結

通過這幾個示例我們可以發現利用SupportMultipleScreensUtil適配多解析度是完全可行和有效的。在專案中使用該框架可以解放UI設計師的勞力,只需提供一套UI圖即可。對於Android工程師而言,則免去了適配的繁瑣與痛苦:不用再去寫多個dimens檔案,不用擔心把切圖放到了錯誤的資料夾,不用再看著設計師用px作出的標註去換算在佈局中到底該使用多少dp,不用再根據不同的解析度一套一套地去做適配了。而且,由於只採用了一套切圖,所以生成的APK檔案的體積較之以前亦大幅減小。


PS:Android多解析度適配框架視訊教程同步更新啦