自定義控件給Imageview設置點擊效果
Imageview的點擊效果,可能是個很容易被忽視的問題。
對於本地圖片的點擊效果,可以準備兩張圖片,加selector實現。
但是如果是動態加載來的圖片呢?動態加載圖片的一般應用場景都是在listview等控件中,這個時候通常是給itemview整體設置點擊效果,而通常不需要imageview反饋點擊效果。這個效果我就不舉例了,有點開發經驗的應該都很熟練了。
但是有時候我們需要Imageview來顯示點擊的效果,當itemview中Imageview控件作爲主體佔據全部或者絕大多數面積的時候。
比如豆瓣閱讀中書列表
來分析下這種效果的實現邏輯,最直接能想到的就是繼承view,然後在onDraw方法裏畫圖片,監聽onTouchEvent事件改變繪製內容的狀態。但是我們已經有了Imageview這個現成的類爲我們做好了許多工作,所以本文采用繼承自Imageview的方式。Imageview內容的繪製當言也是在onDraw方法中,關於點擊事件的觸發處理,當言也可以放在onTouchEvent方法中,但是我閱讀了下view的源碼發現有一個天然的回調方法dispatchSetPressed,或許可以一試。
選好了內容改變的時機,接下來就是內容改變的方式。我第一個想法圖片變暗就像多繪製了一層透明的黑色,代碼如下
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (pressed) {
canvas.drawColor(Color.parseColor("#7a000000"));
}
}
@Override
protected void dispatchSetPressed(boolean pressed) {
super.dispatchSetPressed(pressed);
this.pressed = pressed;
invalidate();
}
效果也還行
但是對於一些內容圖片本身不是矩形的情況就不好使了。所以不是最佳方案。
那怎麼能針對所有的圖片都有效果呢,答案自然是改變繪製的內容本身。
既然改變內容,imageview繪製的主要內容當然就是裏邊的drawable對象了,看看drawable對象的一些方法。
第一個方法clearColorFilter吸引了我的注意,既然是clearColorFilter,drawAble對象肯定用到了ColorFilter,於是想到了愛哥文章自定義控件其實很簡單1/6中提到的一個變暗的ColorFilter,或許可以一戰。
代碼如下:
final ColorMatrix colorMatrix = new ColorMatrix(new float[] { 0.5F, 0, 0, 0, 0, 0, 0.5F, 0, 0, 0, 0, 0, 0.5F, 0, 0, 0, 0, 0, 1, 0, });
@Override
protected void dispatchSetPressed(boolean pressed) {
super.dispatchSetPressed(pressed);
if (pressed) {
getDrawable().setColorFilter(new ColorMatrixColorFilter(colorMatrix));
} else {
getDrawable().setColorFilter(null);
}
}
注意這裏使用getDrawable得到的對象就是繪製的內容,調用方法setColorFilter之後就會回調drawable對象綁定的回調對象也就是當前的view對象的invalidate方法。所以不用手動再調用invalidate方法。
最後附上一個整體的效果。
第一個imageview的背景selector
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<color android:color="#efefef"></color>
</item>
<item android:state_pressed="false">
<color android:color="#ffffff" />
</item>
</selector>