1. 程式人生 > >波浪互動設計與技術實現

波浪互動設計與技術實現

       有時候為了吸引使用者聚焦某個圖示,我們可以給圖示新增一種波浪放射效果,這樣可以很好的做到聚焦使用者視覺的目的。比如地圖上定位到某個位置點時,我們可以在這個點新增一個Marker,然後讓Marker波浪式放射,再比如在社交APP中,如果發現你附近有多個好友,則可以在好友頭像上新增波浪式放射互動,以吸引使用者去關注他們等等。

設計效果:

技術實現:

(1)實現原理

       主要是自定義了一個View,重寫onDraw()方法得到畫布,然後建立一支有顏色的畫筆,不斷的畫同心圓。因為每個同心圓不一樣大,所以要不斷改變同心圓半徑,因為波浪的效果設計成由中心出發,顏色不斷變淡,所以要不斷的改變畫筆的透明度。為了讓變化效果比較細膩,每次同心圓半徑增1,畫筆透明度減1。

為了讓半徑和透明度的改變保持同步,我們定義同心圓的半徑最大為透明度最大值(255),且我們暫且設計只產生5個同心圓,這樣的話每當同心圓的半徑增加到255/5=51,我們就可心去生成下一個同心圓了,直到同心圓的個數為5為止。

(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>

到此,執行專案就可以看到效果圖那樣的效果了。