android自定义view-强大的点击灰色背景imageview
来源:互联网 发布:监控网络防雷器 20ka 编辑:程序博客网 时间:2024/05/18 01:54
前言:
微信作为很火的社交平台广受大众推崇,作为开发者不仅要学会使用软件,更重要的是要琢磨那些吸引人的控件的研发思路。刷了好久的朋友圈,作为一个安卓开发者来说,朋友圈九宫格的图片显示,以及点击图片会有灰色蒙板的效果吸引了我,为了方便大家,也为了给自己温习知识,写下这篇博文。
效果图:
就是这样的效果!
正文:
今天我们就来实现这样的一个效果,在我们动笔写代码之前,我们必须要理清自己的思路,不能一开始就盲目的去写代码,磨刀不误砍柴工。我们唯一能够确定的是,继承自imageview。然后呢?然后重写构造方法,由于用到了点击,所以还要去手动处理一下onTouchEvent方法。看似困难的问题处理起来也会游刃有余了。想法都是对的,其实我们还少分析一个问题,图片会分为本地和远程两种形式,这样的图片如何去加一个灰色的蒙板,远程图片又如何加载呢?带着这些个问题,我们来一一探寻答案。
思考一:继承ImageView
public class GrayScaleImageView extends ImageView
思考二:重写构造方法
public GrayScaleImageView(Context context) {super(context);}public GrayScaleImageView(Context context, AttributeSet attrs) {super(context, attrs);}public GrayScaleImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}我没有进行一些初始化操作,因为这里还没有什么需要初始化。
思考三:处理onTouchEvent事件
@Overridepublic boolean onTouchEvent(MotionEvent event) {Drawable drawable = getDrawable();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (drawable != null) {// drawable.mutate使得此drawable共享状态,改变时全部改变drawable.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if (drawable != null) {drawable.mutate().clearColorFilter();}break;}return true;// return super.onTouchEvent(event);}这是整个博文最核心的一部分。首先我们通过getDrawable()获取ImageView的drawable图片,手指按下的时候需要给这个drawable加上灰色蒙板,我们通过:
drawable.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);这段代码给drawable加上了一个颜色过滤,那么这边的mutate方法,需要看一下官方解释:
最重要的一句话,By default, all drawables instances loaded from the same resource share a common state; if you modify the state of one instance, all the other instances will receive the same modification.中文简言就是状态共享。
手指抬起的时候,就要清除我们加的过滤层。
drawable.mutate().clearColorFilter();这里我需要特别提醒的就是,这边的事件处理完之后,需要return true,如果你return super.onTouchEvent(event);就会发现move,和up事件不会执行,只会执行down事件,觉得奇怪的同学去深入看一下安卓的事件分发处理机制。
思考四:如何设置imageview本地和远程图片
首先,我们需要确定一下我们的远程图片加载框架,网上有很多优秀的图片加载框架,在前面的博文中我也有提到过,这里我用的是Picasso。那么在什么时候去设置图片呢?
android view有以下14个周期:
1、onFinishInflate() 当View中所有的子控件均被映射成xml后触发 。
2、onMeasure( int , int ) 确定所有子元素的大小 。
3、onLayout( boolean , int , int , int , int ) 当View分配所有的子元素的大小和位置时触发 。
4、onSizeChanged( int , int , int , int ) 当view的大小发生变化时触发 。
5、onDraw(Canvas) view渲染内容的细节。
6、onKeyDown( int , KeyEvent) 有按键按下后触发 。
7、onKeyUp( int , KeyEvent) 有按键按下后弹起时触发 。
8、onTrackballEvent(MotionEvent) 轨迹球事件 。
9、onTouchEvent(MotionEvent) 触屏事件 。
10、onFocusChanged( boolean , int , Rect) 当View获取或失去焦点时触发 。
11、onWindowFocusChanged( boolean ) 当窗口包含的view获取或失去焦点时触发 。
12、onAttachedToWindow() 当view被附着到一个窗口时触发 。
13、onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和 onAttachedToWindow() 是相反的。
14、onWindowVisibilityChanged( int ) 当窗口中包含的可见的view发生变化时触发。
安卓的大致执行流程为:从构造方法开始,依次执行onAttachToWindow——>onMeasure——>onSizeChanged——>onLayout——>onMeasure——>onLayout——>onDraw——>onDetachedFromWindow
看到这边的话,就应该确定了,我们在onAttachToWindow方法中进行图片设置,在onDetachedFromWindow取消图片设置
@Overrideprotected void onAttachedToWindow() {isAttachWindow = true;if (!TextUtils.isEmpty(url)) {if (isAttachWindow) {Picasso.with(getContext()).load(url).placeholder(new ColorDrawable(Color.parseColor("#f5f5f5"))).into(this);}}super.onAttachedToWindow();}@Overrideprotected void onDetachedFromWindow() {Picasso.with(getContext()).cancelRequest(this);isAttachWindow = false;setImageBitmap(null);super.onDetachedFromWindow();}如果是本地图片的话,我们直接在xml中设置android:src,如果是远程的图片的话,就需要在activity中调用这个方法。
public void setImageUrl(String url) {if (!TextUtils.isEmpty(url)) {this.url = url;}}好了,我贴上全部代码咯,GrayScaleImageView.java:
package com.beyole.view;import android.content.Context;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.text.TextUtils;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.ImageView;import com.squareup.picasso.Picasso;public class GrayScaleImageView extends ImageView {// 图片地址private String url;// 是否依附在window上private boolean isAttachWindow = false;public GrayScaleImageView(Context context) {super(context);}public GrayScaleImageView(Context context, AttributeSet attrs) {super(context, attrs);}public GrayScaleImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Drawable drawable = getDrawable();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (drawable != null) {// drawable.mutate使得此drawable共享状态,改变时全部改变drawable.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if (drawable != null) {drawable.mutate().clearColorFilter();}break;}return true;// return super.onTouchEvent(event);}@Overrideprotected void onAttachedToWindow() {isAttachWindow = true;if (!TextUtils.isEmpty(url)) {if (isAttachWindow) {Picasso.with(getContext()).load(url).placeholder(new ColorDrawable(Color.parseColor("#f5f5f5"))).into(this);}}super.onAttachedToWindow();}@Overrideprotected void onDetachedFromWindow() {Picasso.with(getContext()).cancelRequest(this);isAttachWindow = false;setImageBitmap(null);super.onDetachedFromWindow();}public void setImageUrl(String url) {if (!TextUtils.isEmpty(url)) {this.url = url;}}}使用:MainActivity.java
package com.beyole.grayscaleimageview;import android.app.Activity;import android.os.Bundle;import com.beyole.view.GrayScaleImageView;public class MainActivity extends Activity {private GrayScaleImageView imageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//imageView = (GrayScaleImageView) findViewById(R.id.img1);//imageView.setImageUrl("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1461129468&di=07dab3112befff0b84bd7c5933ff5523&src=http://img5.duitang.com/uploads/item/201411/08/20141108162654_xthYT.jpeg");}}
activity_main.xml:
<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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.beyole.grayscaleimageview.MainActivity" > <com.beyole.view.GrayScaleImageView android:id="@+id/img1" android:layout_width="100dip" android:src="@drawable/timg" android:layout_height="100.0dip" /></RelativeLayout>行了,其实写这篇博客是为下篇微信朋友圈九宫格显示图片做准备的,就当是下篇博文的预告了吧。
好了,今天的代码教程到此结束。赶着去改论文了,忙里偷着写这一篇博客,我真的不适合搞论文写作。。
csdn下载地址:http://download.csdn.net/detail/smarticeberg/9496918
题外话:
Android交流群:279031247(广告勿入)
新浪微博:SmartIceberg
- android自定义view-强大的点击灰色背景imageview
- android自定义View之仿携程首页点击缩放ImageView
- Android 自定义View (ImageView )
- Android自定义点击效果的ImageView
- Android 自定义Imageview的点击效果
- android自定义点击后背景跟文字会修改的view
- 自定义TabLayout的tab标签内容在点击的时候出现灰色背景
- Android自定义view的点击事件
- Android,自定义一个点击变暗效果的ImageView
- android自定义view之自定义imageview
- Android自定义View之仿去哪儿ImageView标签点击效果
- 去除点击tableView灰色背景
- android自定义view--指南针背景
- Android中自定义点击缩放ImageView
- android自定义圆形头像view,继承imageview
- android自定义view-打造圆形ImageView(一)
- android自定义view-打造圆形ImageView(二)
- android自定义view-打造圆形ImageView(三)
- ubuntu14.04安装cuda
- Hypertable 简介 一个 C++ 的Bigtable开源实现
- HDU-5667-Sequence(矩阵快速幂+费马小定理)
- 启动memcache的方法参数
- 为什么Hibernate中使用serializable来加载或更新实体
- android自定义view-强大的点击灰色背景imageview
- 修改tomcat编码和设置可读写
- Intent传递对象
- nodejs 保存数组/对象,对其进行处理,而不影响原数组/对象
- 分析注入代码的两种方法
- 同步、异步、阻塞与非阻塞详解
- 模拟iOS网络环境
- 高斯模糊
- 牛腩讨论组上课