項(xiàng)目介紹
在審核某些問題的時(shí)候會(huì)出現(xiàn)加載進(jìn)度展示的view。給用戶一個(gè)感官上的效果锉走,增強(qiáng)了APP與用戶之間的交互體驗(yàn)。自定義審核過渡頁純粹就只是一個(gè)自定義view,支持展示文字以及展示圖片和進(jìn)度加載的更換翰铡。也方便了大家的使用吧。
效果展示:
result.gif
功能實(shí)現(xiàn)
1.自定義屬性
<declare-styleable name="SmartLoadingView">
<!-- 是否開啟抗鋸齒 -->
<attr name="antiAlias" format="boolean" />
<!--整個(gè)view背景-->
<attr name="allBack" format="reference|color" />
<!--分割線上面部分進(jìn)度條以及提示字-->
<!--進(jìn)度條中間的圖片-->
<attr name="circleBitmap" format="reference" />
<!--展示icon的寬度-->
<attr name="circleBitmapWidth" format="dimension" />
<!--展示icon的高度-->
<attr name="circleBitmapHeight" format="dimension" />
<!--是否展示中間的圖片-->
<attr name="isShowIcon" format="boolean" />
<!--進(jìn)度條和圖片之間的距離-->
<attr name="circlePadding" format="dimension" />
<!--進(jìn)度條的寬度-->
<attr name="circleWidth" format="dimension" />
<!--進(jìn)度條距離外部周圍的距離-->
<attr name="circleMargin" format="dimension" />
<!--進(jìn)度條的背景顏色-->
<attr name="circleBgColor" format="color|reference" />
<!--進(jìn)度條的循環(huán)顏色-->
<attr name="circleColor" format="color|reference" />
<!--進(jìn)度條走完一圈需要時(shí)間-->
<attr name="circleShowTime" format="integer" />
<!--進(jìn)度條終止展示角度-->
<attr name="circleEndAngle" format="float" />
<!--進(jìn)度條循環(huán)起始角度-->
<attr name="circleStartAngle" format="float" />
<!--引導(dǎo)頁提示內(nèi)容-->
<attr name="hint" format="string" />
<!--引導(dǎo)提示字顏色-->
<attr name="hintColor" format="color|reference" />
<!--引導(dǎo)提示字大小-->
<attr name="hintSize" format="dimension" />
<!--引導(dǎo)提示字是否展示-->
<attr name="hintIsShow" format="boolean" />
<!--分割線-->
<!--分割線高度-->
<attr name="lineHeight" format="dimension" />
<!--分割線的顏色-->
<attr name="lineColor" format="color|reference" />
<!--分割線上下的間距-->
<attr name="lineMargin" format="dimension" />
<!--底部內(nèi)容-->
<!--未選中icon-->
<attr name="bottomUnSelectIcon" format="reference" />
<!--選中的的icon-->
<attr name="bottomSelectIcon" format="reference" />
<!--內(nèi)容icon的寬度-->
<attr name="bottomIconWidth" format="dimension" />
<!--內(nèi)容icon的高度-->
<attr name="bottomIconHeight" format="dimension" />
<!--默認(rèn)內(nèi)容展示顏色-->
<attr name="defaultColor" format="color" />
<!--選中內(nèi)容展示顏色-->
<attr name="chooseColor" format="color" />
<!--內(nèi)容標(biāo)題字體顏色-->
<attr name="titleColor" format="color" />
<!--展示標(biāo)題集合-->
<attr name="titles" format="reference" />
<!--默認(rèn)展示內(nèi)容集合-->
<attr name="contentUnSelect" format="reference" />
<!--選中展示內(nèi)容集合-->
<attr name="contentSelect" format="reference" />
<!--標(biāo)題字體大小-->
<attr name="titleSize" format="dimension" />
<!--內(nèi)容字體大小-->
<attr name="contentSize" format="dimension" />
<!--連接線寬度-->
<attr name="connectLineWidth" format="dimension"/>
</declare-styleable>
2.在view中繪制對(duì)應(yīng)view
- 繪制進(jìn)度條
private void drawProgress(Canvas canvas) {
if (isShowIcon) {
//創(chuàng)建指定大小的bitmap對(duì)象
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), circleBitmap);
canvas.drawBitmap(bitmap, null, new RectF(width / 2 - circleBitmapWidth / 2,
(int) (circlePadding + circleMargin), (int) width / 2 + circleBitmapWidth / 2,
(int) (circlePadding + circleMargin) + circleBitmapHeight), bitmapPaint);
bitmap.recycle();
bitmap = null;
}
//創(chuàng)建指定大小的circle元
canvas.drawCircle(width / 2, circlePadding + circleBitmapHeight / 2 + circleMargin, circleBitmapHeight / 2 + circlePadding, circleBgPaint);
canvas.drawArc(width / 2 - circleBitmapWidth / 2 - circlePadding,
circleMargin,
width / 2 + circleBitmapWidth / 2 + circlePadding
, circleBitmapHeight + circlePadding + circlePadding + circleMargin,
circleStartAngle,
circleEndAngle, false, circlePaint);
}
private int hintHeight = 0;
private void drawHint(Canvas canvas) {
String hints = TextUtils.isEmpty(hint) ? "正在努力評(píng)估中讽坏,請(qǐng)耐心等待..." : hint;
float textWidth = hintPaint.measureText(hints);
// 文本baseline在y軸方向的位置
float baseLineY = Math.abs(hintPaint.ascent() + hintPaint.descent()) / 2;
if (hintIsShow) {
canvas.drawText(hints, width / 2 - textWidth / 2, (circlePadding + circleMargin) * 2 + circleBitmapHeight + baseLineY, hintPaint);
hintHeight = (int) (hintPaint.density - hintPaint.ascent());
} else {
hintHeight = 0;
}
}
- 繪制下方文字
private void drawBottom(Canvas cavas) {
//剩下的距離锭魔,根據(jù)titles的標(biāo)致均分
remainingHeight = (int) (height - (circleMargin + circlePadding + lineMargin) * 2 - circleBitmapHeight - hintHeight - lineHeight);
int y = (int) ((circleMargin + circlePadding + lineMargin) * 2 + circleBitmapHeight + hintHeight + lineHeight);
int everyItem = remainingHeight / titles.size();
//配置當(dāng)前的一些常見屬性
//去左上角的點(diǎn)
Point iconPoint = new Point(dp2px(mContext, 40), y + everyItem * 3 / 11);
Point titlePoint = new Point(iconPoint.x+dp2px(mContext, 40), iconPoint.y);
Point contentPoint = new Point(iconPoint.x+dp2px(mContext, 41), iconPoint.y + dp2px(mContext, 30));
bottomBitmap(cavas, iconPoint, step);
titleCenter(titles, titlePaint, cavas, titlePoint, Paint.Align.CENTER, step);
contentCenter(contentSelect, contentUnSelect, contentPaint, cavas, contentPoint, Paint.Align.CENTER, step);
;
}
private void bottomBitmap(Canvas canvas, Point point, int step) {
Bitmap bitmapUnSelect = BitmapFactory.decodeResource(getResources(), bottomUnSelectIcon);
Bitmap bitmapSelect = BitmapFactory.decodeResource(getResources(), bottomSelectIcon);
for (int i = 0; i < titles.size(); i++) {
float yAxis = remainingHeight / titles.size();
if (i <= step) {
canvas.drawBitmap(bitmapSelect, null, new Rect(point.x,
point.y + (int) yAxis * i,
point.x + (int) bottomIconWidth,
point.y + (int) bottomIconHeight + (int) yAxis * i)
, bitmapPaint);
} else {
canvas.drawBitmap(bitmapUnSelect, null, new RectF(point.x,
point.y + (int) yAxis * i,
point.x + bottomIconWidth,
point.y + bottomIconHeight + (int) yAxis * i)
, bitmapPaint);
}
}
for (int i = 1; i < titles.size(); i++) {
if (i <= step) {
connectLinePaint.setColor(chooseColor);
} else {
connectLinePaint.setColor(defaultColor);
}
float yAxis = remainingHeight / titles.size();
canvas.drawLine(point.x + bottomIconWidth / 2, bottomIconHeight + point.y + yAxis * (i - 1)
, point.x + bottomIconWidth / 2, point.y + yAxis * i, connectLinePaint);
}
bitmapSelect.recycle();
bitmapSelect = null;
bitmapUnSelect.recycle();
bitmapUnSelect = null;
}
//繪制標(biāo)題
private void titleCenter(List<String> strings, Paint paint, Canvas canvas, Point point, Paint.Align aligin, int step) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float ascent = fontMetrics.ascent;
float descent = fontMetrics.descent;
float stringHeight = descent - ascent;
int length = strings.size();
for (int i = 0; i < length; i++) {
if (i <= step) {
titlePaint.setColor(chooseColor);
} else {
titlePaint.setColor(defaultColor);
}
float yAxis = remainingHeight / length;
canvas.drawText(strings.get(i) + "", point.x, point.y + yAxis * i + stringHeight, paint);
}
}
//繪制內(nèi)容
private void contentCenter(List<String> select, List<String> unselect, Paint paint, Canvas canvas, Point point, Paint.Align aligin, int step) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float ascent = fontMetrics.ascent;
float descent = fontMetrics.descent;
float stringHeight = descent - ascent;
for (int i = 0; i < titles.size(); i++) {
float yAxis = remainingHeight / titles.size();
if (i <= step) {
contentPaint.setColor(chooseColor);
canvas.drawText(select.get(i) + "", point.x, point.y + yAxis * i + stringHeight, paint);
} else {
contentPaint.setColor(defaultColor);
canvas.drawText(unselect.get(i) + "", point.x, point.y + yAxis * i + stringHeight, paint);
}
}
}
- 設(shè)置回調(diào)方法
public interface onViewCompleteFinshListener {
void complete();
}
public void setCompleteFinshListener(onViewCompleteFinshListener completeFinshListener) {
this.completeFinshListener = completeFinshListener;
}
public class MainActivity extends AppCompatActivity implements SmartLoadingView.onViewCompleteFinshListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SmartLoadingView loadingView = findViewById(R.id.smartView);
loadingView.setCompleteFinshListener(this);
}
@Override
public void complete() {
Toast.makeText(this, "進(jìn)度已經(jīng)加載完畢,該執(zhí)行對(duì)應(yīng)的跳轉(zhuǎn)方法了", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, NextActivity.class));
this.finish();
}
}
3.在xml文件中調(diào)用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<combudou.smartloadingview.view.SmartLoadingView
android:id="@+id/smartView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentSelect="@array/verify_content"
app:contentUnSelect="@array/default_content"
app:titles="@array/titles" />
</RelativeLayout>
實(shí)現(xiàn)思路
功能很簡單路呜,都是一些基本的canvas方法調(diào)用迷捧,實(shí)現(xiàn)這個(gè)算是對(duì)基礎(chǔ)知識(shí)的一個(gè)回顧吧。