不知道細心的同學注意到?jīng)]有,新版手機QQ的底部tab按鈕特別有意思,當手放在上面的時候,這個按鈕可以隨手指的移動而改變形狀,如下圖:

hdssh.gif
于是我就仿寫了一個,其實實現(xiàn)原理也挺簡單的,最終的效果圖如下:

hdsxxxsh.gif
第一步我們得下載QQ的apk文件,把里面的按鈕圖片資源解壓出來,不過解壓之后一看瞬間懵逼了,居然有這么多文件夾,而且還是混淆過后的:

image.png
還好機智的我試著搜索tab、menu、selected等關鍵詞后才其中一個文件夾發(fā)現(xiàn)了這些圖片:

image.png
原來每個tab按鈕都是由1~2張圖片拼在一起的,那我就封裝成一個控件,然后仿寫第一個按鈕好了。
實現(xiàn)原理很簡單,繼承FrameLayout,添加1~2張圖片,在onTouchEvent方法中移動。當然為了實現(xiàn)上述效果,兩張圖片移動的比例(或者阻尼值)是不同的,而且還要限制兩張圖片的移動范圍。
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE: {
changeWhenMove(x, y);
return true;
}
case MotionEvent.ACTION_UP: {
restorePosition();
if (isContain(this, event.getRawX(), event.getRawY())) {
setHasClick(!hasClick);
if (OnMenuClickListener != null) {
OnMenuClickListener.onItemClick(this);
}
}
return true;
}
}
return true;
}
核心代碼如上:ACTION_MOVE時移動控件,ACTION_UP時還原至原位置。如果手指抬起的位置在按鈕范圍內(nèi)則響應點擊事件。這樣就簡單實現(xiàn)了QQ動態(tài)按鈕的效果。實際使用也很簡單:簡單在布局文件中聲明,并在代碼中設置普通狀態(tài)的圖片id和按下狀態(tài)的圖片的id就行了:
<com.renny.qqmenu.QQMenu
android:id="@+id/avater_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
QQMenu.setImgages(R.drawable.skin_tab_icon_conversation_normal
, R.drawable.skin_tab_icon_conversation_selected
, R.drawable.rvq, R.drawable.rvr);
QQMenu.setOnMenuClickListener(new QQMenu.OnMenuClickListener() {
@Override
public void onItemClick(View view) {
Toast.makeText(MainActivity.this, "Click "+QQMenu.isHasClick(),
Toast.LENGTH_SHORT).show();
}
});