編輯:關於Android編程
Android 從 5.0 提供了新的API VectorDrawable,通過該對象,我們可以使用矢量圖SVG。
在編寫
xml文件中,通過關鍵的幾個標簽節點
,
下面我們將實現兩個例子來演示
VectorDrawable和
SVG的使用。先上實現的效果圖。
登錄特效
搜索特效
登錄特效的實現
首先需要分析該特效。根據整個動畫,整個特效對應的SVG 圖案如下所示:
整個圖案分為五個部分,兩條橫線,兩個半圓,以及一個對號。為了凸顯,所以把顏色稍微修改了一下。
那麼使用
edit_login.xml
:該文件存放在res-> drawable文件夾下。
如上代碼,我們可以通過
Android Studio的預覽效果,直接看到圖案。
在代碼中出現了兩個標簽
width:畫布的寬度。 height:畫布的高度。 viewportWidth:將具體的寬度劃分成相對的單位單元。300dp被分割成了150個單元單位。 viewportHeight:將具體的高度劃分成相對的單元單位。96dp被分割成48個單元單位。
name:聲明一個標記。類似於id。 便於對其做動畫的時候可以找到該節點。 pathData:矢量圖SVG 的描述。(後面會提) strokeWidth:畫筆的寬度 strokeColor:畫筆的顏色 strokeAlpha:透明度 strokeLineCap:畫出線條的結束點的形狀。正方向或圓角矩形。。。
圖案畫出以後,需要針對該圖案做動畫,整個圖案過程分為三個:
初次點擊第一個對話框時,顯示第一條橫線,其余的不顯示。
1 動畫顯示。2,3,4,5不顯示。 驗證輸入是否正確,如果正確,顯示對號。
1 默認顯示,2,3 動畫顯示 4,5 隱藏 點擊第二個對話框,第一條橫線個向第二條橫線過度。
1 動畫隱藏 ,2 隱藏,3顯示。 4,5動畫顯示。
當然,還很很多的用戶交互,在此不再做實現。
根據上面的順序,分別定義
anim1.xml,
anim2.xml,
anim3.xml。注意,該文件存在
drawable中。ps: 無視命名.
anim1.xml
anim2.xml
anim3.xml
在三個文件中,最外層
進行包裹,該文件的作用類似於溝通的作用,將SVG和動畫相整合,產生新的
drawable。
drawable:目標SVG.
name: 目標文件的標識。 animation:動畫。
在其中定義了n多個動畫。默認顯示和默認不顯示的動畫(此時沒有動畫效果).ps: 動畫定義的都是屬性動畫,所以需要放在
animator文件夾中。
anim_default.xml
默認顯示
動畫屬性
trimPathEnd這個字段之前未出現過。它也是
同時也有一個
trimPathStart,這個字段顯示的也是百分比。不過其表示的是不顯示的百分比。0~1代表從開始隱藏的百分比。
anim_default_gone.xml
默認隱藏
anim_bar_fill.xml
—–1 的顯示動畫。
anim_bar_empty.xml
—–1 的隱藏動畫。
anim_round.xml
– 2 的顯示動畫
anim_aa.xml
– 3 的顯示動畫
anim_round2.xml
– 4 的顯示動畫
anim_bar_fill2.xml
– 5 的顯示動畫
如上的代碼已經實現了圖片以及動畫的實現。下面就是使用,首先看布局文件:
兩個文本框之間要有間隔,用以顯示我們的動畫。
由於文本框的存在,導致打開頁面是自動彈出鍵盤,所以把焦點定在了
ImageView上,防止打開頁面時自動彈出軟鍵盤。
/**
* SVG 動畫
* Created by MH on 2016/7/19.
*/
public class SVGMainActivity extends AppCompatActivity implements View.OnFocusChangeListener, TextWatcher {
private ImageView img1;
private EditText edit1, edit2;
// 顯示
private AnimatedVectorDrawable anim1, anim2, anim3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_svg);
img1 = ((ImageView) findViewById(R.id.img1));
edit1 = ((EditText) findViewById(R.id.edit1));
edit2 = ((EditText) findViewById(R.id.edit2));
// 加載SVG
anim1 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim1);
anim2 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim2);
anim3 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim3);
// 設置焦點變化的監聽
edit1.setOnFocusChangeListener(this);
edit2.setOnFocusChangeListener(this);
// 文本變化的監聽
edit1.addTextChangedListener(this);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
switch (v.getId()) {
case R.id.edit1:
if (hasFocus) {
img1.setImageDrawable(anim1);
anim1.start();
}
break;
case R.id.edit2:
if (hasFocus) {
img1.setImageDrawable(anim3);
anim3.start();
}
break;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// 內容變化之後,判斷內容
if (!TextUtils.isEmpty(s) && edit1.getText().toString().trim().equals("1234")) {
Toast.makeText(SVGMainActivity.this, "right", Toast.LENGTH_SHORT).show();
img1.setImageDrawable(anim2);
anim2.start();
}
}
}
核心的三個步驟;
anim1 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim1);,將之前編寫的xml文件加載為drawable,同時強轉為AnimatedVectorDrawable。 img.setImageDrawable(anim1)設置Drawable。 anim1.start():啟動動畫
因為細節的處理上比較麻煩。所以此處只是做了一個簡單的實現。
SVG Path Data
在上面的實現中,定義SVG 圖像時,節點中pathData中,用字符和數字描繪了一個圖案。
其中主要有如下命令:
M : move to 移動繪制點 L : line to 直線 Z : close 閉合 C : cubic bezier 三次貝塞爾曲線 Q : quatratic bezier 二次貝塞爾曲線 A : 圓弧
每個命令都有大寫和小寫,大寫代表絕對位置。小寫代表當前點的相對位置。
在使用中,唯一個需要說的便是圓弧(A)問題。
在代碼中使用了M138 23 A 10 10 0 1 0 128 13。
M138 23:先畫筆移動到(138,23)的位置。 A 10 10 0 1 0 128 13: 畫圓弧。分別對應: x軸半徑,y軸半徑,x軸偏移量,弧度(0代表取小弧度,1代表大弧度) ,方向(0取逆時針,1為順時針),目標X坐標,目標y坐標。
搜索特效的實現
按照之前的步驟,分別如下實現:
定義SVG圖像。 定義VectorDrawable的xml文件。 定義動畫。 加載,使用。
search_bar.xml
畫出SVG.
anim_bar_to_search.xml
下劃線向搜索圖案的過渡。
anim_search_to_bar.xml
搜索向下劃線過渡的動畫
下劃線消失和隱藏的動畫使用的是上一個例子的動畫。代碼不在貼。
搜索框的動畫和下劃線動畫類似。
布局文件:
<framelayout android:focusable="true" android:focusableintouchmode="true" android:layout_height="wrap_content" android:layout_width="wrap_content">
</framelayout>
布局文件,在最外層添加點擊事件,當點擊文本框之外時,顯示搜索圖標。點擊圖標時顯示下劃線。同時,將焦點設置移開文本框。
在activity中設置:
/**
*
* 搜索動畫的實現
* Created by MH on 2016/7/19.
*/
public class SVGMain2Activity extends AppCompatActivity {
private ImageView iv;
private TextView text;
private AnimatedVectorDrawable searchToBar;
private AnimatedVectorDrawable barToSearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_svg2);
iv = (ImageView) findViewById(R.id.search);
text = (TextView) findViewById(R.id.text);
// 加載SVG
searchToBar = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim_search_to_bar);
barToSearch = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim_bar_to_search);
// 設置監聽
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
iv.setImageDrawable(searchToBar);
searchToBar.start();
}
});
}
public void lost_focus(View view) {
// 點擊文本框之外時,隱藏下劃線
iv.setImageDrawable(barToSearch);
barToSearch.start();
}
}
找到第一份實習,老大給我的第一個任務是實現美顏功能,網上找了一大堆資料,總的來說美顏的實現的步驟是:1.用具有保邊效果的濾波算法對圖像進行模糊處理2.用膚色檢測算法保護非
一般情況下,客戶端和服務端的數據交互都是使用json和XML,相比於XML,json更加輕量級,並且省流量,但是,無論我們用json還是用xml,都需要我們先將數據封裝成
Google API:http://developer.android.com/guide/topics/connectivity/bluetooth-le.html
ListView是Android中最常用的視圖之一,使用的頻率僅僅次於三大基礎布局,雖然由於使用性和擴展性等原因備受爭議,且盡管後來出現了RecyclerView的替代方