波浪互動設計與技術實現
阿新 • • 發佈:2019-02-07
有時候為了吸引使用者聚焦某個圖示,我們可以給圖示新增一種波浪放射效果,這樣可以很好的做到聚焦使用者視覺的目的。比如地圖上定位到某個位置點時,我們可以在這個點新增一個Marker,然後讓Marker波浪式放射,再比如在社交APP中,如果發現你附近有多個好友,則可以在好友頭像上新增波浪式放射互動,以吸引使用者去關注他們等等。
設計效果:
技術實現:
(1)實現原理
主要是自定義了一個View,重寫onDraw()方法得到畫布,然後建立一支有顏色的畫筆,不斷的畫同心圓。因為每個同心圓不一樣大,所以要不斷改變同心圓半徑,因為波浪的效果設計成由中心出發,顏色不斷變淡,所以要不斷的改變畫筆的透明度。為了讓變化效果比較細膩,每次同心圓半徑增1,畫筆透明度減1。
(2)核心程式碼
1)自定義MyView,繼承於View。實現三個構造方法,重寫onDraw()方法
public classMyView extends View { publicMyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } publicMyView(Context context, AttributeSet attrs) { super(context, attrs); } publicMyView(Context context) { super(context); } @Override protected voidonDraw(Canvas canvas) { super.onDraw(canvas); } }
2)定義畫筆,同心圓最大半徑,透明度緩衝集合,半徑緩衝集合,並初始化畫筆、初始透明度、初始半徑。
public classMyView extends View { privatePaint mPaint;//1 定義畫筆 privateList<String> mAlphaList = newArrayList<String>();//2透明度緩衝集合 privateList<String> mWidthList = newArrayList<String>();//3半徑緩衝集合 private int mMaxWidth =255;//4 同心圓最大半徑 publicMyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } publicMyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } publicMyView(Context context) { super(context); init(); } /** * 5初始化畫筆,緩衝集合 */ private voidinit(){ mPaint = newPaint(); mPaint.setColor(Color.YELLOW); mAlphaList.add("255"); mWidthList.add("0"); } @Override protected voidonDraw(Canvas canvas) { super.onDraw(canvas); } }
3 )在onDraw()方法中減加透明度與同心圓半徑,然後繪製同心圓
public classMyView extends View {
privatePaint mPaint;//1 定義畫筆
privateList<String> mAlphaList = newArrayList<String>();//2透明度緩衝集合
privateList<String> mWidthList = newArrayList<String>();//3半徑緩衝集合
private int mMaxWidth =255;//4 同心圓最大半徑
publicMyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
publicMyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
publicMyView(Context context) {
super(context);
init();
}
/**
* 5初始化畫筆,緩衝集合
*/
private voidinit(){
mPaint = newPaint();
mPaint.setColor(Color.YELLOW);
mAlphaList.add("255");
mWidthList.add("0");
}
@Override
protected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
//初始時就一個同心圓,但後面會增加多個同心圓,所以繪製的時候使用迴圈
for(int i=0;i< mWidthList.size();i++){
//獲取緩衝集合中的透明度並減1
int alpha =Integer.parseInt(mAlphaList.get(i))-1;
//獲取緩衝集合中的同心圓半徑並加1
int radius =Integer.parseInt(mWidthList.get(i))+1;
//改變畫筆的透明度
mPaint.setAlpha(alpha);
//以MyView的中心點為中心點,繪製同心圓
canvas.drawCircle(getWidth()/2,getHeight()/2, radius, mPaint);
//判斷透明度>0&&半徑<最大半徑,則緩衝透明度值與半徑值
if(alpha>0&&radius<mMaxWidth){
mAlphaList.set(i, alpha+"");
mWidthList.set(i, radius+"");
}
}
}
}
4)增加下一個同心圓,並且當增加到第6個時,刪除最開始的同心圓,以確保最多隻有5個同心圓。最後要重新整理才可生效。
@Override
protected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
//初始時就一個同心圓,但後面會增加多個同心圓,所以繪製的時候使用迴圈
for(int i=0;i< mWidthList.size();i++){
//獲取緩衝集合中的透明度並減1
int alpha =Integer.parseInt(mAlphaList.get(i))-1;
//獲取緩衝集合中的同心圓半徑並加1
int radius =Integer.parseInt(mWidthList.get(i))+1;
//改變畫筆的透明度
mPaint.setAlpha(alpha);
//以MyView的中心點為中心點,繪製同心圓
canvas.drawCircle(getWidth()/2,getHeight()/2, radius, mPaint);
//判斷透明度>0&&半徑<最大半徑,則緩衝透明度值與半徑值
if(alpha>0&&radius<mMaxWidth){
mAlphaList.set(i, alpha+"");
mWidthList.set(i, radius+"");
}
}
//新增下一個同心圓(主要是設定同心圓半徑和透明度)
if (Integer.parseInt(mWidthList.get(mWidthList.size()- 1)) == mMaxWidth / 5) {
mAlphaList.add("255");
mWidthList.add("0");
}
//控制同心圓的個數不超過5個
if(mWidthList.size()==6){
mAlphaList.remove(0);
mWidthList.remove(0);
}
//一定要的呼叫此方法,重新整理,所謂重新整理就是重新呼叫onDraw()方法,這樣新增加的同心圓就可以被繪製了
invalidate();
}
5)使用MyView根據需要進行佈局(這個比較簡單,就不解釋了)
<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"
android:background="#40000000"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.kedi.dizhenbodemo.MyView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true">
</com.kedi.dizhenbodemo.MyView>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@drawable/icon12"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<com.kedi.dizhenbodemo.MyView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true">
</com.kedi.dizhenbodemo.MyView>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@drawable/icon13"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true">
<com.kedi.dizhenbodemo.MyView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true">
</com.kedi.dizhenbodemo.MyView>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@drawable/icon14"/>
</RelativeLayout>
</RelativeLayout>
到此,執行專案就可以看到效果圖那樣的效果了。