先看效果
具备按下抬起效果的VIEW
如视频中,我们有很多按钮,这些按钮都用共同的属性,按下时亮起,抬起时恢复原背景,因此我们要自定义一个View,轻松实现这个功能,避免写太多重复代码。
一、自定义属性
在values文件夹中建一个attrs.xml文件,定义属性,如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--自定义属性-->
<declare-styleable name="HHHH">
<attr name="txt" format="string"/>
<attr name="txt_size" format="dimension"/>
<attr name="txt_color" format="reference|color"/>
<attr name="down_img" format="reference"/>
<attr name="up_img" format="reference"/>
</declare-styleable>
</resources>
二、自定义ButtonView,并使用上面的属性
(1)在layout包下新建一个名为view_button的xml布局文件,代码如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/btn"
android:gravity="center"
android:textSize="@dimen/dp20"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
(2)实现逻辑
public class ButtonView extends LinearLayout {
public ButtonViewK9(Context context) {
this(context,null);
}
public ButtonViewK9(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
private View view;
public ButtonViewK9(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
view = LayoutInflater.from(context).inflate(R.layout.view_button,this,true);
//通过TypedArray获取相应的属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BridgeView);
Drawable downImg = typedArray.getDrawable(R.styleable.HHHH_down_img);
Drawable upImg = typedArray.getDrawable(R.styleable.HHHH_up_img);
String text = typedArray.getString(R.styleable.HHHH_txt);
int textColor=typedArray.getColor(R.styleable.HHHH_txt_color, Color.BLACK);
float textSize = typedArray.getDimension(R.styleable.HHHH_txt_size,-1f);
TextView textView=(TextView) view.findViewById(R.id.btn);
textView.setBackground(upImg);
textView.setText(text);
//这个属性值可以不用设置
if (textColor!=Color.BLACK)textView.setTextColor(textColor);
//这个属性值可以不用设置
if (textSize!=-1f)textView.setTextSize(textSize);
//监听触摸事件
textView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float downX=0;
float downY=0;
if (motionEvent.getAction()==MotionEvent.ACTION_DOWN){
//设置按下显示的背景
textView.setBackground(downImg);
//记录按下坐标点
downX=motionEvent.getX();
downY=motionEvent.getY();
return true;
}
if (motionEvent.getAction()==MotionEvent.ACTION_UP){
//设置抬起显示的背景
textView.setBackground(upImg);
//手势拖到按下点以外100px的地方,视为放弃点击
if (Math.abs(motionEvent.getX()-downX)>100)return false;
if (Math.abs(motionEvent.getY()-downY)>100)return false;
//把事件传递给点击事件接口,使用时我们就能直接使用OnClickListener获取点击事件
if (onClickListener!=null)onClickListener.onClick(ButtonView.this);
return true;
}
return false;
}
});
}
private OnClickListener onClickListener;
@Override
public void setOnClickListener(@Nullable OnClickListener onClickListener) {
//拦截单击事件,使用时我们就能直接使用OnClickListener获取点击事件
this.onClickListener=onClickListener;
}
}
二、使用方法
(1)先准备两张背景图,这里我用xml的shape绘制背景, 在drawable包下新建名:down_back.xml 和 up_back.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--<gradient
android:startColor="#FFFFFF"
android:endColor="#97B5C3"
android:angle="50"/>-->
<!--背景颜色渐变 angle为渐变角度-->
<solid android:color="#FFC107" />
<!-- 背景填充颜色 -->
<stroke android:width="0dp" android:color="#252525" />
<!--描边,边框宽度、颜色-->
<corners android:radius="10dp" />
<!-- 边角圆弧的半径 -->
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
<!-- 四周留出来的空白 -->
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--<gradient
android:startColor="#FFFFFF"
android:endColor="#97B5C3"
android:angle="50"/>-->
<!--背景颜色渐变 angle为渐变角度-->
<solid android:color="#F4F4F4" />
<!-- 背景填充颜色 -->
<stroke android:width="0dp" android:color="#252525" />
<!--描边,边框宽度、颜色-->
<corners android:radius="10dp" />
<!-- 边角圆弧的半径 -->
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
<!-- 四周留出来的空白 -->
</shape>
(2) 在最终使用的布局中引用上面两个背景
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:demo="http://schemas.android.com/apk/res-auto" (需要特别注意的是这一句,不能缺少)
android:orientation="vertical"
android:gravity="center"
android:id="@+id/out_view"
android:background="#77000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.包路径.ButtonView
android:id="@+id/ok"
android:layout_margin="@dimen/dp10"
android:layout_width="@dimen/dp100"
android:layout_height="@dimen/dp60"
demo:down_img="@drawable/down_back"
demo:up_img="@drawable/up_back"
demo:txt="确定"
demo:txt_size="20dp"
demo:txt_color="#FFFFFF"/>
</LinearLayout>
到此,就实现了开头的效果。