自定义组件—LoadingProcessView
2016-09-23 09:18
232 查看
注:该文章为(男人应似海)原创,如需转载请注明出处!
当我们使用WebView加载网页时,我们会希望在网页加载过程中有个进度提示,这样用户体验会更好些。实现这样的功能有两种方法:
1. 通过调用相应方法,使用系统自带的组件来完成。进度条颜色和位置固定不可修改。
效果图如下(顶部绿色为进度条)
2. 通过自定义组件,根据自己的需要或喜好来实现。进度条颜色和位置可以自由安排。
效果图如下(底部红色为进度条)
显然,我们更喜欢第二种方法。下面是两种方法的具体实现:
1.第一种实现方式:
布局文件webview_progress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<WebView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="@+id/web_body"
android:background="#ffffffff">
</WebView>
</RelativeLayout>
代码:
package doudou.android.webview.progress;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewProgressActivity extends Activity {
/** Called when the activity is first created. */
private WebView webView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.webview_progress_layout);
webView=(WebView) findViewById(R.id.web_body);
this.webView.setWebViewClient(new MyWebViewClient());
this.webView.setWebChromeClient(new MyWebChromeClient());
// 设置支持JavaScript
WebSettings settings = this.webView.getSettings();
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setPluginsEnabled(true);
settings.setSaveFormData(true);
settings.setLoadsImagesAutomatically(true);
// Enable zooming
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
// 加载网页
this.webView.loadUrl("http://www.baidu.com");
}
class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 重写此方法表明点击网页里的链接还是在当前的WebView里打开而不跳到浏览器
view.loadUrl(url);
return true;
}
}
class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
WebViewProgressActivity.this.getWindow().setFeatureInt(
Window.FEATURE_PROGRESS, newProgress * 100);
super.onProgressChanged(view, newProgress);
}
}
}
2.第二种方法
这是一个自定义的显示加载进度的组件。
package doudou.android.webview.progress;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/******************************************************************
* 文 件 名:LoadingProcessView.java
* 文件描述 : 显示加载时的进度条
* 作 者:wader
* 创建时间:2011-8-23下午17:26:06
* 修改时间:2011-8-23下午17:26:06
******************************************************************/
public class LoadingProcessView extends View {
/**
* 用于绘制进度条
*/
private final float STATRTX = 0.0f;
private final float STATRTY = 0.0f;
private final int PERCENT = 100;
/**
* 进度条的进度百分比
*/
private int precent;
/**
* 加载状态
*/
private boolean isShow;
/**
* 下载进度条颜色
*/
private final int PROGRESS_COLOR = 0xFFB70C0C;
/**
* 进度条的背景颜色
*/
private final int PROCESS_BACKGROUD = 0xFFBDBDBD;
/**
* 进度条的宽度
*/
private int processWidth = 320;
/**
* 进度条的高度
*/
private int processHeight = 20;
/**
* 画笔对象
*/
private Paint paint;
/**
* 构造方法
* @param context UI窗口上下文
*/
public LoadingProcessView(Context context) {
super(context);
}
/**
* 构造方法
* @param contextUI窗口上下文
* @param attrs 属性集
*/
public LoadingProcessView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 构造方法
* @param contextUI窗口上下文
* @param attrs属性集
* @param defStyle
*/
public LoadingProcessView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 绘图方法
* @param canvas画布
*/
@Override
protected void onDraw(Canvas canvas) {
Log.e("LoadingProcessView", "onDraw=" + precent);
super.onDraw(canvas);
if (paint == null) {
paint = new Paint();
// 设置绘制的进度条的颜色为红色
}
paint.setColor(PROCESS_BACKGROUD);
canvas.drawRect(STATRTX,STATRTY,(float)processWidth,processHeight,paint);
paint.setColor(PROGRESS_COLOR);
canvas.drawRect(STATRTX, STATRTY,
(float) (precent * processWidth / PERCENT), processHeight,
paint);
}
/**
* 设置进度条大小
* @param processWidth宽度
* @param processHeight高度
*/
public void setProgressSize(int processWidth, int processHeight) {
this.processWidth = processWidth;
this.processHeight = processHeight;
}
/**
* 设置进度条的进度
* @param precent当前下载进度
* @param isShow是否显示加载状态
*/
public void setProgress(int precent, boolean isShow) {
this.precent = precent;
this.isShow = isShow;
}
/**
* 获取是否正在加载的状态
* @return 是否正在加载
*/
public boolean getIsShow() {
return isShow;
}
}
布局文件webview_progress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<RelativeLayout android:id="@+id/widget_progress"
android:layout_width="fill_parent"
android:layout_height="20dip"
android:gravity="center"
android:orientation="horizontal"
android:background="#ffffffff" android:layout_alignParentBottom="true">
</RelativeLayout>
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/web_body"
android:background="#ffffffff" android:layout_above="@id/widget_progress">
</RelativeLayout>
</RelativeLayout>
代码:
package doudou.android.webview.progress;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
public class WebViewProgressActivity extends Activity {
/** Called when the activity is first created. */
private Timer timer = new Timer();
/*
* 显示WebView的布局
*/
private RelativeLayout webContent;
private WebView webView = null;
/*
* 显示加载进度条的布局和view
*/
private RelativeLayout processLayout = null;
private LoadingProcessView lpv = null;
/*
* 进度条默认高度
*/
private int processHeight = 20;
private TimerTask progressTask = null;
private int currentProgress = 0;
private static int realProgress = 0;
private static int increase = 5;
private boolean isProgressVisible = false;
private final int LOADFINISH = 0;
private final int ISLOADING = 1;
protected final int FINISH = 100;
protected final static long REFRESHTIME = 350;
private Handler processHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case ISLOADING:
if (lpv != null)
lpv.invalidate();
break;
case LOADFINISH:
if (processLayout != null)
processLayout.setVisibility(View.GONE);
break;
}
super.handleMessage(msg);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.webview_progress_layout);
lpv = new LoadingProcessView(this);
processLayout = (RelativeLayout) findViewById(R.id.widget_progress);
processLayout.getLayoutParams().height = processHeight;
// 将进度条添加到显示页面当中
processLayout.addView(lpv, 0, new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
webContent = (RelativeLayout) findViewById(R.id.web_body);
this.webView = new WebView(this);
webView.setLayoutParams(new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
this.webView.setWebViewClient(new MyWebViewClient());
this.webView.setWebChromeClient(new MyWebChromeClient());
// 设置支持JavaScript
WebSettings settings = this.webView.getSettings();
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setPluginsEnabled(true);
settings.setSaveFormData(true);
settings.setLoadsImagesAutomatically(true);
// Enable zooming
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
// 加载网页
this.webView.loadUrl("http://www.google.com");
}
class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 重写此方法表明点击网页里的链接还是在当前的WebView里打开而不跳到浏览器
view.loadUrl(url);
return true;
}
}
class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress > 30) {
processHandler.sendMessage(processHandler
.obtainMessage(ISLOADING));
}
if (progressTask == null) {
progressTask = new TimerTask() {
@Override
public void run() {
currentProgress += increase;
if (currentProgress < realProgress && lpv != null) {
System.out.println("currentProgress: "
+ currentProgress);
lpv.setProgress(currentProgress, true);
processHandler.sendMessage(processHandler
.obtainMessage(ISLOADING));
} else {
currentProgress -= increase;
}
}
};
}
if (!isProgressVisible) {
isProgressVisible = true;
if (processLayout != null) {
processLayout.setVisibility(View.VISIBLE);
}
timer.schedule(progressTask, 20, REFRESHTIME);
}
realProgress = (newProgress + 300) >> 2;
if (currentProgress >= 95 || realProgress == FINISH) {
closeTimer();
if (newProgress == FINISH) {
// 刷新进度条显示的进度,并且给界面发送消息通知界面刷新页面
if (lpv != null) {
lpv.setProgress(newProgress, false);
}
processHandler.sendMessage(processHandler
.obtainMessage(LOADFINISH));
}
webContent.removeAllViews();
webContent.addView(webView);
webView.requestFocus();
}
super.onProgressChanged(view, newProgress);
}
}
private void closeTimer() {
if (progressTask != null) {
progressTask.cancel();
}
if (lpv != null) {
lpv.setProgress(FINISH, false);
}
currentProgress = 0;
isProgressVisible = false;
progressTask = null;
}
}
由于代码不是很难,就不做过多解释了,相信大家都能看得懂。
当我们使用WebView加载网页时,我们会希望在网页加载过程中有个进度提示,这样用户体验会更好些。实现这样的功能有两种方法:
1. 通过调用相应方法,使用系统自带的组件来完成。进度条颜色和位置固定不可修改。
效果图如下(顶部绿色为进度条)
2. 通过自定义组件,根据自己的需要或喜好来实现。进度条颜色和位置可以自由安排。
效果图如下(底部红色为进度条)
显然,我们更喜欢第二种方法。下面是两种方法的具体实现:
1.第一种实现方式:
布局文件webview_progress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<WebView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="@+id/web_body"
android:background="#ffffffff">
</WebView>
</RelativeLayout>
代码:
package doudou.android.webview.progress;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewProgressActivity extends Activity {
/** Called when the activity is first created. */
private WebView webView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.webview_progress_layout);
webView=(WebView) findViewById(R.id.web_body);
this.webView.setWebViewClient(new MyWebViewClient());
this.webView.setWebChromeClient(new MyWebChromeClient());
// 设置支持JavaScript
WebSettings settings = this.webView.getSettings();
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setPluginsEnabled(true);
settings.setSaveFormData(true);
settings.setLoadsImagesAutomatically(true);
// Enable zooming
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
// 加载网页
this.webView.loadUrl("http://www.baidu.com");
}
class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 重写此方法表明点击网页里的链接还是在当前的WebView里打开而不跳到浏览器
view.loadUrl(url);
return true;
}
}
class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
WebViewProgressActivity.this.getWindow().setFeatureInt(
Window.FEATURE_PROGRESS, newProgress * 100);
super.onProgressChanged(view, newProgress);
}
}
}
2.第二种方法
这是一个自定义的显示加载进度的组件。
package doudou.android.webview.progress;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/******************************************************************
* 文 件 名:LoadingProcessView.java
* 文件描述 : 显示加载时的进度条
* 作 者:wader
* 创建时间:2011-8-23下午17:26:06
* 修改时间:2011-8-23下午17:26:06
******************************************************************/
public class LoadingProcessView extends View {
/**
* 用于绘制进度条
*/
private final float STATRTX = 0.0f;
private final float STATRTY = 0.0f;
private final int PERCENT = 100;
/**
* 进度条的进度百分比
*/
private int precent;
/**
* 加载状态
*/
private boolean isShow;
/**
* 下载进度条颜色
*/
private final int PROGRESS_COLOR = 0xFFB70C0C;
/**
* 进度条的背景颜色
*/
private final int PROCESS_BACKGROUD = 0xFFBDBDBD;
/**
* 进度条的宽度
*/
private int processWidth = 320;
/**
* 进度条的高度
*/
private int processHeight = 20;
/**
* 画笔对象
*/
private Paint paint;
/**
* 构造方法
* @param context UI窗口上下文
*/
public LoadingProcessView(Context context) {
super(context);
}
/**
* 构造方法
* @param contextUI窗口上下文
* @param attrs 属性集
*/
public LoadingProcessView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 构造方法
* @param contextUI窗口上下文
* @param attrs属性集
* @param defStyle
*/
public LoadingProcessView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 绘图方法
* @param canvas画布
*/
@Override
protected void onDraw(Canvas canvas) {
Log.e("LoadingProcessView", "onDraw=" + precent);
super.onDraw(canvas);
if (paint == null) {
paint = new Paint();
// 设置绘制的进度条的颜色为红色
}
paint.setColor(PROCESS_BACKGROUD);
canvas.drawRect(STATRTX,STATRTY,(float)processWidth,processHeight,paint);
paint.setColor(PROGRESS_COLOR);
canvas.drawRect(STATRTX, STATRTY,
(float) (precent * processWidth / PERCENT), processHeight,
paint);
}
/**
* 设置进度条大小
* @param processWidth宽度
* @param processHeight高度
*/
public void setProgressSize(int processWidth, int processHeight) {
this.processWidth = processWidth;
this.processHeight = processHeight;
}
/**
* 设置进度条的进度
* @param precent当前下载进度
* @param isShow是否显示加载状态
*/
public void setProgress(int precent, boolean isShow) {
this.precent = precent;
this.isShow = isShow;
}
/**
* 获取是否正在加载的状态
* @return 是否正在加载
*/
public boolean getIsShow() {
return isShow;
}
}
布局文件webview_progress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<RelativeLayout android:id="@+id/widget_progress"
android:layout_width="fill_parent"
android:layout_height="20dip"
android:gravity="center"
android:orientation="horizontal"
android:background="#ffffffff" android:layout_alignParentBottom="true">
</RelativeLayout>
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/web_body"
android:background="#ffffffff" android:layout_above="@id/widget_progress">
</RelativeLayout>
</RelativeLayout>
代码:
package doudou.android.webview.progress;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
public class WebViewProgressActivity extends Activity {
/** Called when the activity is first created. */
private Timer timer = new Timer();
/*
* 显示WebView的布局
*/
private RelativeLayout webContent;
private WebView webView = null;
/*
* 显示加载进度条的布局和view
*/
private RelativeLayout processLayout = null;
private LoadingProcessView lpv = null;
/*
* 进度条默认高度
*/
private int processHeight = 20;
private TimerTask progressTask = null;
private int currentProgress = 0;
private static int realProgress = 0;
private static int increase = 5;
private boolean isProgressVisible = false;
private final int LOADFINISH = 0;
private final int ISLOADING = 1;
protected final int FINISH = 100;
protected final static long REFRESHTIME = 350;
private Handler processHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case ISLOADING:
if (lpv != null)
lpv.invalidate();
break;
case LOADFINISH:
if (processLayout != null)
processLayout.setVisibility(View.GONE);
break;
}
super.handleMessage(msg);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.webview_progress_layout);
lpv = new LoadingProcessView(this);
processLayout = (RelativeLayout) findViewById(R.id.widget_progress);
processLayout.getLayoutParams().height = processHeight;
// 将进度条添加到显示页面当中
processLayout.addView(lpv, 0, new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
webContent = (RelativeLayout) findViewById(R.id.web_body);
this.webView = new WebView(this);
webView.setLayoutParams(new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
this.webView.setWebViewClient(new MyWebViewClient());
this.webView.setWebChromeClient(new MyWebChromeClient());
// 设置支持JavaScript
WebSettings settings = this.webView.getSettings();
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setPluginsEnabled(true);
settings.setSaveFormData(true);
settings.setLoadsImagesAutomatically(true);
// Enable zooming
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
// 加载网页
this.webView.loadUrl("http://www.google.com");
}
class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 重写此方法表明点击网页里的链接还是在当前的WebView里打开而不跳到浏览器
view.loadUrl(url);
return true;
}
}
class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress > 30) {
processHandler.sendMessage(processHandler
.obtainMessage(ISLOADING));
}
if (progressTask == null) {
progressTask = new TimerTask() {
@Override
public void run() {
currentProgress += increase;
if (currentProgress < realProgress && lpv != null) {
System.out.println("currentProgress: "
+ currentProgress);
lpv.setProgress(currentProgress, true);
processHandler.sendMessage(processHandler
.obtainMessage(ISLOADING));
} else {
currentProgress -= increase;
}
}
};
}
if (!isProgressVisible) {
isProgressVisible = true;
if (processLayout != null) {
processLayout.setVisibility(View.VISIBLE);
}
timer.schedule(progressTask, 20, REFRESHTIME);
}
realProgress = (newProgress + 300) >> 2;
if (currentProgress >= 95 || realProgress == FINISH) {
closeTimer();
if (newProgress == FINISH) {
// 刷新进度条显示的进度,并且给界面发送消息通知界面刷新页面
if (lpv != null) {
lpv.setProgress(newProgress, false);
}
processHandler.sendMessage(processHandler
.obtainMessage(LOADFINISH));
}
webContent.removeAllViews();
webContent.addView(webView);
webView.requestFocus();
}
super.onProgressChanged(view, newProgress);
}
}
private void closeTimer() {
if (progressTask != null) {
progressTask.cancel();
}
if (lpv != null) {
lpv.setProgress(FINISH, false);
}
currentProgress = 0;
isProgressVisible = false;
progressTask = null;
}
}
由于代码不是很难,就不做过多解释了,相信大家都能看得懂。
相关文章推荐
- 自定义组件—LoadingProcessView
- 自定义组件—LoadingProcessView
- Android自定义加载loading view动画组件
- 几个经常需要自定义的组件:UIScrollview、UItextView、UIButton
- 自定义组件之【柱状图】详解 已封装成View
- 自定义Android组件之带图像的TextView
- 自定义组件之【柱状图】详解 已封装成View
- 自定义Android组件之带图像的TextView(转)
- 开源组件:DEMO学习-DWinterTabDemo:自定义tab+viewpager
- 几个经常需要自定义的组件:UIScrollview、UItextView、UIButton
- Android: web view loading process dialog
- 自定义图片缩放组件—ImageZoomView
- Android自定义View设定到FrameLayout布局中实现多组件显示
- 关于自定义组件-以apidemo中的LabelView进行讲解
- 几个经常需要自定义的组件:UIScrollview、UItextView、UIButton
- 几个经常需要自定义的组件:UIScrollview、UItextView、UIButton
- (转)自定义Android组件之带图像的TextView
- 新书内容连载(1):自定义Android组件之带图像的TextView
- Android开发中自定义View设定到FrameLayout布局中实现多组件显示
- 新书内容连载(1):自定义Android组件之带图像的TextView