项目中用到滑动按钮,折腾了好长时间,一直想用seekbar实现,但总是有问题。
后来看到了一个matrix的讲解,果断试了一下,竟然成功了。
做一下记录,也顺便分享下,不喜勿喷。
如果大家有更好方法,请指教。
首先介绍下 matrix ,matrix是图像处理的一个方法,他是一个3X3 的矩阵。对图像处理有4个基本方式,平移,旋转,缩放,错切。
matrix 有3个常用的方法 set(图片matrix值),post(后乘,根据矩阵的原理,相当于左乘)、pre(先乘,相当于矩阵中的右乘)。默认时,这四种变换都是围绕(0,0)点变换的,当然可以自定义围绕的中心点,通常围绕中心点。
接下来进入正题,滑动按钮是如何实现的。
第一步,得到图片当前“位置”的值,这里的位置用matrix表示,看看,这就用上了。
这是在我acton_down的时候,就会触发以下内容。
private Matrix currentMatrix=new Matrix();//得到matrix的对象,注意是当前的位置哦
//得到当前图片的位置的值
<pre name="code" class="java">currentMatrix.set(img.getImageMatrix());<pre name="code" class="java">
第二部,当然是得到action_move的时候的位置的值啦。<pre name="code" class="java">action_move的时候的matrix 和currentMatrix可是有区别的,想想,一个是图片原来的“位置”,另一个是图片移动后的“位置”。
所以要重新得到一个matrix对象。
<pre name="code" class="java">private Matrix matrix=new Matrix(); //得到了移动的matrix,那我们现在从哪里开始移动呢,
是不是从currentMatrix开始的,所以把currentMatrix给Matrix。
<pre name="code" class="java">matrix.set(currentMatrix);
//现在就可以把移动的值赋给Matrix了
<pre name="code" class="java">matrix.postTranslate(dx, dy);//dx,dy 是指图片在x,y轴上移动的距离。我们这里实现按钮上下滑动,所以dx可以不管。得到dy就可以
//dy是这样得来的
<pre name="code" class="java"> dy=event.getY()-point.y; //event.getY() 是滑动时(acton_move)y轴的值,point.y <span style="font-family: Arial, Helvetica, sans-serif;">是手指触摸到(action_down)</span>
<span style="font-family: Arial, Helvetica, sans-serif;"> 屏幕上时候的y轴的值 </span><span style="font-family: Arial, Helvetica, sans-serif;">point.set(event.getX(),event.getY())</span><span style="font-family: Arial, Helvetica, sans-serif;">
</span>
//postTranslate 方法的解释。
<pre name="code" class="java">public boolean postTranslate (float dx, float dy)
Added in API level 1
Postconcats the matrix with the specified translation. M' = T(dx, dy) * M
核心代码就是这样。
</pre><pre>
上一段我写的代码,实现的效果是,向上滑动或线下滑动触发,松手时按钮回到滑道的中间位置,图就不上了,有问题可以留言。
private final class TouchListener implements OnTouchListener{
private PointF point=new PointF();
private Matrix currentMatrix=new Matrix();
private Matrix matrix=new Matrix();
private boolean upFlag=false,moveFlag=false;
private float dy;
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
// TODO Auto-generated method stub
// if(v.getId()==R.id.img_drag2)img=img2;else img=img1;
img=(ImageView)v;
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
upFlag=true;
currentMatrix.set(img.getImageMatrix());
point.set(event.getX(),event.getY());
Log.d("seekbarlog--", " down"+point.x+point.y);
break;
case MotionEvent.ACTION_MOVE:
float dx=0;
moveFlag=true;
dy=event.getY()-point.y;
if(dy>=30)dy=40;if(dy<=-30)dy=-40;
matrix.set(currentMatrix);
matrix.postTranslate(dx, dy);
Log.d("seekbarlog--", "move"+dy);
break;
case MotionEvent.ACTION_UP:
upFlag=false;
moveFlag=false;
img.setImageMatrix(currentMatrix);
// matrix=currentMatrix;
Log.d("seekbarlog--", " up");
break;
}
switch(v.getId()){
case R.id.img_back_positon:
if(dy==40)clickBackDown(event);
if(dy==-40)clickBackUp(event);
break;
case R.id.img_foot_position:
if(dy==40)clickLegBend(event);
if(dy==-40)clickLegStraighten(event);
break;
case R.id.img_foot_stretch:
if(dy==40)clickLegStretch(event);
if(dy==-40)clickLegShrink(event);
break;
}
if(upFlag&moveFlag){
img.setImageMatrix(matrix);
Log.d("seekbarlog--", "setImageMatrix---");}
return true;
}}
<ImageView
android:id="@+id/img_back_positon"
android:scaleType="matrix"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="115dp"
android:paddingTop="29dp"
android:focusable="true"
android:background="@drawable/bk_line"
android:src="@drawable/img_back_position_bk"/>