【Java】Android中View的滑动

Android中View的滑动

小二玩编程发布于 16 分钟前

在生活中我们使用 Android 的 App 经常会看到一些炫丽的动态界面,出现这种效果很多是因为 View 的滑动,比如 RecyclerView 的滑动,掌握 View 的滑动方式,我们也能做出这样的效果;实现 View 的滑动常见的有5种方法,它们分别是 使用 scrollTo/scrollBy、使用动画、改变布局参数和使用 layout,下面将对它们一一进行介绍。

1、使用 scrollTo/scrollBy
View提供了 scrollTo(int x,int y) 和 scrollBy(int x,int y) 这两个方法实现了它的滑动,具体实现代码(基于 Android Api 27)如下所示:

public void scrollTo(int x, int y) {

if (mScrollX != x || mScrollY != y) {

int oldX = mScrollX;

int oldY = mScrollY;

mScrollX = x;

mScrollY = y;

invalidateParentCaches();

onScrollChanged(mScrollX, mScrollY, oldX, oldY);

if (!awakenScrollBars()) {

postInvalidateOnAnimation();

}

}

}

public void scrollBy(int x, int y) {

scrollTo(mScrollX + x, mScrollY + y);

}

从scrollTo(int x,int y) 和 scrollBy(int x,int y) 这两个方法总结得出,scrollTo(int x,int y) 实现了所传递参数的绝对滑动,而 scrollBy(int x,int y) 实现了当前位置的相对滑动,因为它调用了 scrollTo(int x,int y) 方法。在这2个方法中,出现了 mScrollX 和 mScrollY 这两个成员变量,其中 mScrollX 表示 View 的左边缘和 View 内容左边缘在水平方向的距离,mScrollY 表示 View 上边缘和 View 内容上边缘在垂直方向上的距离。下面写一个例子来使用 scrollBy(int x,int y) 方法;首先新建一个布局文件 activity_view_general_slide.xml,它的代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.example.administrator.androidart.activites.ViewGeneralSlideActivity">

<TextView

android:id="@+id/tv_scroll"

android:layout_width="match_parent"

android:layout_marginTop="20px"

android:text="scrollBy滑动"

android:background="#00FF00"

android:onClick="onClickView"

android:gravity="bottom"

android:layout_height="match_parent" />

</LinearLayout>

然后再新建一个Java文件,名字为 ViewGeneralSlideActivity,代码如下所示:

private TextView mTv;

private MyHandler mHandler = null;

private int mSlideY = 20;

private int mSlideX = 20;

private MyThread thread = null;

private boolean isRunThread = true;

class MyHandler extends Handler {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

mTv.scrollBy(0,mSlideY);

mSlideY += 10;

}

}

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_view_general_slide);

mTv = findViewById(R.id.tv_scroll);

mHandler = new MyHandler();

thread = new MyThread();

}

public void onClickView(View view) {

thread.start();

}

class MyThread extends Thread {

@Override

public void run() {

super.run();

while (isRunThread) {

try {

Thread.sleep(500);

sendMessage();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

@Override

protected void onDestroy() {

super.onDestroy();

isRunThread = false;

if (mHandler != null) {

mHandler.removeCallbacksAndMessages(null);

}

}

private void sendMessage() {

Message message = Message.obtain();

mHandler.sendMessage(message);

}

没点击“scrollBy滑动”控件之前的效果如下所示:
【Java】Android中View的滑动

点击“scrollBy滑动”控件之后的效果如下所示:
【Java】Android中View的滑动

注意:不管是 scrollBy(int x,int y) 还是 scrollTo(int x,int y) 方法,滑动的并非是 View 本身,而是 View 的内容。

2、使用动画

使用动画来移动 View ,是通过 View 的 translationX 和 translationY 这两个属性来实现的,它即可以采用传统的 View 动画,也可以采用属性动画;在使用属性动画方面,如果要在 Android 3.0以下版本使用,那么就要使用到开源动画库 nineoldandroids,它的官方地址为:http://nineoldandroids.com/ 。下面举个例子用代码实现使用 View 动画来移动。

2、1 采用传统的 View 动画

(1) 在 res 目录新建 anim 文件夹并在 anim 文件夹下创建 view_translate.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:fillAfter="true"

android:zAdjustment="normal">

<translate android:fromXDelta="0"

android:fromYDelta="0"

android:toXDelta="200"

android:toYDelta="200"

android:duration="3000"

/>

</set>

(2) 新建一个 Java 文件,名字叫 AnimationActivity,并实现它的代码,如下所示:

private TextView mTv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_animation);

mTv = findViewById(R.id.tv);

}

public void onClick(View view) {

Animation animation = AnimationUtils.loadAnimation(this, R.anim.view_translate);

mTv.startAnimation(animation);

}

(3) 在 layout 文件夹下新建一个 activity_animation.xml 文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.AnimationActivity">

<Button android:layout_width="match_parent"

android:text="点击该按钮可移动view"

android:onClick="onClick"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="300px"

android:gravity="center"

android:text="可移动的传统view"

android:background="#FF0000"

android:layout_height="wrap_content" />

</LinearLayout>

没点击 “点击该按钮可移动view” 这个按钮之前,它运行的效果图如下所示:

【Java】Android中View的滑动

点击 “点击该按钮可移动view” 这个按钮之后,它运行时移动的过程中,某一瞬间的效果图如下所示:

【Java】Android中View的滑动

2、2 使用属性动画移动

(1) 为了兼容 Android 3.0 以下版本的手机,在项目 app 目录下的 build.gradle文件中添加 nineoldandroids 的依赖:

implementation 'com.nineoldandroids:library:2.4.0'

(2) 新建一个 Java 文件,名字叫 Animation2Activity,它的代码如下所示:

private TextView mTv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_animation2);

mTv = findViewById(R.id.tv);

}

public void onClick(View view) {

ObjectAnimator.ofFloat(mTv,"translationY",0,300).setDuration(1000).start();

}

public void onClick2(View view) {

Toast.makeText(this, "点击了“可移动的属性view”", Toast.LENGTH_SHORT).show();

}

(3) 在 layout 文件夹下新建一个 activity_animation2.xml 文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.AnimationActivity">

<Button android:layout_width="match_parent"

android:text="点击该按钮可属性动画移动view"

android:onClick="onClick"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="300px"

android:gravity="center"

android:text="可移动的属性view"

android:background="#FF0000"

android:onClick="onClick2"

android:layout_height="wrap_content" />

</LinearLayout>

没点击 “点击该按钮可属性动画移动view” 之前,它的运行效果图如下所示:

【Java】Android中View的滑动

点击 “点击该按钮可属性动画移动view” 这个按钮之后,它运行时移动的过程中,某一瞬间的效果图如下所示:

【Java】Android中View的滑动

对以上使用动画的例子进行总结得出:(1) 传统的 View 动画只是对影像做移动,并不是真正的改变 View 的位置,它的 fillAfter 属性默认值为 false,也就等同于做完动画之后会回到原位置;当 fillAfter 属性设置为 true 的时候,View 做完动画后,影像不会回到原始的位置,但如果在该 View 做一个事件监听,点击做完动画后的 View 是不会响应事件的,点击 View 的原始位置就会响应事件,因为在系统眼里 View 做完动画之后它的位置没有发生改变。(2) 属性动画在 Android 3.0版本以下的手机不可以用,要想使用,必须添加 nineoldandroids 这个依赖酷;属性动画不是对影像做移动,而是真正的改变了 View 的位置,如果在该 View 做一个事件监听,点击 View 的原始位置是不会有事件响应的,而点击做完动画之后的位置就会有事件响应。

3、改变布局参数

通过改变布局参数来实现 View 的滑动的思路有2个:(1) 向右移动一个View,只需要把它的 marginLeft 参数增大,向其它方向移动同理,只需改变相应的 margin 参数;(2) 要移动的 View 的旁边预先放一个 View,它的初始化宽度为0,然后要想右移动View,只需把预先放置的那个View的宽度增大,这样就把要移动的 View “推”到右边了。示例如下所示:

(1) 新建一个布局文件,名字叫 activity_change_layout_parameter.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.ChangeLayoutParameterActivity">

<Button android:layout_width="match_parent"

android:text="点击我可移动第一个View"

android:onClick="onClick"

android:layout_height="wrap_content" />

<Button android:layout_width="match_parent"

android:text="点击我可移动第二个View"

android:onClick="onClick2"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="350px"

android:onClick="onClick3"

android:text="改变布局参数可移动的View"

android:layout_height="wrap_content" />

<LinearLayout android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

<View android:id="@+id/view"

android:layout_width="0px"

android:layout_height="1px"/>

<TextView android:id="@+id/tv2"

android:layout_width="350px"

android:onClick="onClick4"

android:text="改变布局参数可移动的View"

android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

新建一个 Java 文件,名字叫 ChangeLayoutParameterActivity,它的代码如下所示:

TextView mTv;

View mView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_change_layout_parameter);

mTv = findViewById(R.id.tv);

mView = findViewById(R.id.view);

}

public void onClick(View view) {

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mTv.getLayoutParams();

params.leftMargin += 200;

params.width += 200;

mTv.requestLayout();

}

public void onClick2(View view) {

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();

params.width += 200;

mView.requestLayout();

}

public void onClick3(View view) {

Toast.makeText(this,"点击了“改变布局参数可移动的第一个View” ",Toast.LENGTH_SHORT).show();

}

public void onClick4(View view) {

Toast.makeText(this,"点击了“改变布局参数可移动的第二个View” ",Toast.LENGTH_SHORT).show();

}

没点击 “点击我可移动第一个View” 按钮之前,效果图如下所示:

【Java】Android中View的滑动

点击 “点击我可移动第一个View” 按钮之后,效果图如下所示:

【Java】Android中View的滑动

对以上改变布局参数移动 View 进行总结:不管是对 View 的 marginLeft 参数进行增大;还是要移动的 View 的旁边预先放一个 View,然后要向右移动View;他们两种方法都实现了 View 真正位置的移动,而不是 View 影像的移动;如果在 移动的 View 做事件监听,点击原始位置不会事件响应,点击移动后的位置会有事件响应。

4、使用 layout

使用 layout 移动 View 的思路是这样的:在View的onTouchEvent方法中对MotionEvent中的坐标进行记录,记录按下的时候记录,在移动的时候计算他们的偏移量,调用layout()对view的位置进行重绘制;下面举个例子:

(1) 新建一个布局文件,名叫 activity_use_layout.xml :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="demo1.xe.com.myapplication2.UseLayoutActivity">

<TextView android:id="@+id/tv"

android:layout_width="wrap_content"

android:text="使用 Layout移动View"

android:onClick="onClick"

android:layout_height="wrap_content" />

</RelativeLayout>

(2) 新建一个 Java 文件,名叫 UseLayoutActivity,它的实现代码如下所示:

TextView mTv;

private int lastX,lastY;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_use_layout);

mTv = findViewById(R.id.tv);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getRawX();

int y = (int) event.getRawY();

switch (event.getAction()){

case MotionEvent.ACTION_DOWN:

lastX = x;

lastY = y;

break;

case MotionEvent.ACTION_MOVE:

int offsetX = x - lastX;

int offsetY = y - lastY;

mTv.layout(mTv.getLeft()+offsetX,

mTv.getTop()+offsetY,

mTv.getRight()+offsetX,

mTv.getBottom()+offsetY);

lastX = x;

lastY = y;

break;

}

return true;

}

public void onClick(View v){

Toast.makeText(this," 点击了 “使用 Layout移动View” 按钮 ",Toast.LENGTH_SHORT).show();

}

没滑动屏幕之前的效果图如下所示:

【Java】Android中View的滑动

滑动屏幕某一瞬间的效果图如下所示:

【Java】Android中View的滑动

对以上使用 layout 移动 View 进行总结:使用 layout 移动 View,改变的不是 View 的影像,而是 View 真正的位置,所以如果要设置 View 的事件监听,点击移动后的 View 才会响应事件;使用 layout 移动 View 是和 Activity 的触摸事件结合使用的,触摸的时候获取相对于屏幕触摸的x 和 y 坐标,然后手指移动的过程中计算出移动的距离再加上 View 相对于父视图的位置,得到 View 移动后的位置,最后 View 使用 layout 方法 重新布局再进行重新绘画。

好了,本篇文章写到这里就结束了,由于本人技术水平有限,难免会有出错的地方,欢迎批评指正,谢谢大家的阅读,另外附上Android的View滑动demo

【Java】Android中View的滑动关注微信公众号,阅读更多有趣的技术文章

javaandroid

阅读 16发布于 16 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

小二玩编程

活到老,学到老。

1 声望

1 粉丝

0 条评论

得票时间

avatar

小二玩编程

活到老,学到老。

1 声望

1 粉丝

宣传栏

在生活中我们使用 Android 的 App 经常会看到一些炫丽的动态界面,出现这种效果很多是因为 View 的滑动,比如 RecyclerView 的滑动,掌握 View 的滑动方式,我们也能做出这样的效果;实现 View 的滑动常见的有5种方法,它们分别是 使用 scrollTo/scrollBy、使用动画、改变布局参数和使用 layout,下面将对它们一一进行介绍。

1、使用 scrollTo/scrollBy
View提供了 scrollTo(int x,int y) 和 scrollBy(int x,int y) 这两个方法实现了它的滑动,具体实现代码(基于 Android Api 27)如下所示:

public void scrollTo(int x, int y) {

if (mScrollX != x || mScrollY != y) {

int oldX = mScrollX;

int oldY = mScrollY;

mScrollX = x;

mScrollY = y;

invalidateParentCaches();

onScrollChanged(mScrollX, mScrollY, oldX, oldY);

if (!awakenScrollBars()) {

postInvalidateOnAnimation();

}

}

}

public void scrollBy(int x, int y) {

scrollTo(mScrollX + x, mScrollY + y);

}

从scrollTo(int x,int y) 和 scrollBy(int x,int y) 这两个方法总结得出,scrollTo(int x,int y) 实现了所传递参数的绝对滑动,而 scrollBy(int x,int y) 实现了当前位置的相对滑动,因为它调用了 scrollTo(int x,int y) 方法。在这2个方法中,出现了 mScrollX 和 mScrollY 这两个成员变量,其中 mScrollX 表示 View 的左边缘和 View 内容左边缘在水平方向的距离,mScrollY 表示 View 上边缘和 View 内容上边缘在垂直方向上的距离。下面写一个例子来使用 scrollBy(int x,int y) 方法;首先新建一个布局文件 activity_view_general_slide.xml,它的代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.example.administrator.androidart.activites.ViewGeneralSlideActivity">

<TextView

android:id="@+id/tv_scroll"

android:layout_width="match_parent"

android:layout_marginTop="20px"

android:text="scrollBy滑动"

android:background="#00FF00"

android:onClick="onClickView"

android:gravity="bottom"

android:layout_height="match_parent" />

</LinearLayout>

然后再新建一个Java文件,名字为 ViewGeneralSlideActivity,代码如下所示:

private TextView mTv;

private MyHandler mHandler = null;

private int mSlideY = 20;

private int mSlideX = 20;

private MyThread thread = null;

private boolean isRunThread = true;

class MyHandler extends Handler {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

mTv.scrollBy(0,mSlideY);

mSlideY += 10;

}

}

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_view_general_slide);

mTv = findViewById(R.id.tv_scroll);

mHandler = new MyHandler();

thread = new MyThread();

}

public void onClickView(View view) {

thread.start();

}

class MyThread extends Thread {

@Override

public void run() {

super.run();

while (isRunThread) {

try {

Thread.sleep(500);

sendMessage();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

@Override

protected void onDestroy() {

super.onDestroy();

isRunThread = false;

if (mHandler != null) {

mHandler.removeCallbacksAndMessages(null);

}

}

private void sendMessage() {

Message message = Message.obtain();

mHandler.sendMessage(message);

}

没点击“scrollBy滑动”控件之前的效果如下所示:
【Java】Android中View的滑动

点击“scrollBy滑动”控件之后的效果如下所示:
【Java】Android中View的滑动

注意:不管是 scrollBy(int x,int y) 还是 scrollTo(int x,int y) 方法,滑动的并非是 View 本身,而是 View 的内容。

2、使用动画

使用动画来移动 View ,是通过 View 的 translationX 和 translationY 这两个属性来实现的,它即可以采用传统的 View 动画,也可以采用属性动画;在使用属性动画方面,如果要在 Android 3.0以下版本使用,那么就要使用到开源动画库 nineoldandroids,它的官方地址为:http://nineoldandroids.com/ 。下面举个例子用代码实现使用 View 动画来移动。

2、1 采用传统的 View 动画

(1) 在 res 目录新建 anim 文件夹并在 anim 文件夹下创建 view_translate.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:fillAfter="true"

android:zAdjustment="normal">

<translate android:fromXDelta="0"

android:fromYDelta="0"

android:toXDelta="200"

android:toYDelta="200"

android:duration="3000"

/>

</set>

(2) 新建一个 Java 文件,名字叫 AnimationActivity,并实现它的代码,如下所示:

private TextView mTv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_animation);

mTv = findViewById(R.id.tv);

}

public void onClick(View view) {

Animation animation = AnimationUtils.loadAnimation(this, R.anim.view_translate);

mTv.startAnimation(animation);

}

(3) 在 layout 文件夹下新建一个 activity_animation.xml 文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.AnimationActivity">

<Button android:layout_width="match_parent"

android:text="点击该按钮可移动view"

android:onClick="onClick"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="300px"

android:gravity="center"

android:text="可移动的传统view"

android:background="#FF0000"

android:layout_height="wrap_content" />

</LinearLayout>

没点击 “点击该按钮可移动view” 这个按钮之前,它运行的效果图如下所示:

【Java】Android中View的滑动

点击 “点击该按钮可移动view” 这个按钮之后,它运行时移动的过程中,某一瞬间的效果图如下所示:

【Java】Android中View的滑动

2、2 使用属性动画移动

(1) 为了兼容 Android 3.0 以下版本的手机,在项目 app 目录下的 build.gradle文件中添加 nineoldandroids 的依赖:

implementation 'com.nineoldandroids:library:2.4.0'

(2) 新建一个 Java 文件,名字叫 Animation2Activity,它的代码如下所示:

private TextView mTv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_animation2);

mTv = findViewById(R.id.tv);

}

public void onClick(View view) {

ObjectAnimator.ofFloat(mTv,"translationY",0,300).setDuration(1000).start();

}

public void onClick2(View view) {

Toast.makeText(this, "点击了“可移动的属性view”", Toast.LENGTH_SHORT).show();

}

(3) 在 layout 文件夹下新建一个 activity_animation2.xml 文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.AnimationActivity">

<Button android:layout_width="match_parent"

android:text="点击该按钮可属性动画移动view"

android:onClick="onClick"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="300px"

android:gravity="center"

android:text="可移动的属性view"

android:background="#FF0000"

android:onClick="onClick2"

android:layout_height="wrap_content" />

</LinearLayout>

没点击 “点击该按钮可属性动画移动view” 之前,它的运行效果图如下所示:

【Java】Android中View的滑动

点击 “点击该按钮可属性动画移动view” 这个按钮之后,它运行时移动的过程中,某一瞬间的效果图如下所示:

【Java】Android中View的滑动

对以上使用动画的例子进行总结得出:(1) 传统的 View 动画只是对影像做移动,并不是真正的改变 View 的位置,它的 fillAfter 属性默认值为 false,也就等同于做完动画之后会回到原位置;当 fillAfter 属性设置为 true 的时候,View 做完动画后,影像不会回到原始的位置,但如果在该 View 做一个事件监听,点击做完动画后的 View 是不会响应事件的,点击 View 的原始位置就会响应事件,因为在系统眼里 View 做完动画之后它的位置没有发生改变。(2) 属性动画在 Android 3.0版本以下的手机不可以用,要想使用,必须添加 nineoldandroids 这个依赖酷;属性动画不是对影像做移动,而是真正的改变了 View 的位置,如果在该 View 做一个事件监听,点击 View 的原始位置是不会有事件响应的,而点击做完动画之后的位置就会有事件响应。

3、改变布局参数

通过改变布局参数来实现 View 的滑动的思路有2个:(1) 向右移动一个View,只需要把它的 marginLeft 参数增大,向其它方向移动同理,只需改变相应的 margin 参数;(2) 要移动的 View 的旁边预先放一个 View,它的初始化宽度为0,然后要想右移动View,只需把预先放置的那个View的宽度增大,这样就把要移动的 View “推”到右边了。示例如下所示:

(1) 新建一个布局文件,名字叫 activity_change_layout_parameter.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="demo1.xe.com.myapplication2.ChangeLayoutParameterActivity">

<Button android:layout_width="match_parent"

android:text="点击我可移动第一个View"

android:onClick="onClick"

android:layout_height="wrap_content" />

<Button android:layout_width="match_parent"

android:text="点击我可移动第二个View"

android:onClick="onClick2"

android:layout_height="wrap_content" />

<TextView android:id="@+id/tv"

android:layout_width="350px"

android:onClick="onClick3"

android:text="改变布局参数可移动的View"

android:layout_height="wrap_content" />

<LinearLayout android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

<View android:id="@+id/view"

android:layout_width="0px"

android:layout_height="1px"/>

<TextView android:id="@+id/tv2"

android:layout_width="350px"

android:onClick="onClick4"

android:text="改变布局参数可移动的View"

android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

新建一个 Java 文件,名字叫 ChangeLayoutParameterActivity,它的代码如下所示:

TextView mTv;

View mView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_change_layout_parameter);

mTv = findViewById(R.id.tv);

mView = findViewById(R.id.view);

}

public void onClick(View view) {

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mTv.getLayoutParams();

params.leftMargin += 200;

params.width += 200;

mTv.requestLayout();

}

public void onClick2(View view) {

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();

params.width += 200;

mView.requestLayout();

}

public void onClick3(View view) {

Toast.makeText(this,"点击了“改变布局参数可移动的第一个View” ",Toast.LENGTH_SHORT).show();

}

public void onClick4(View view) {

Toast.makeText(this,"点击了“改变布局参数可移动的第二个View” ",Toast.LENGTH_SHORT).show();

}

没点击 “点击我可移动第一个View” 按钮之前,效果图如下所示:

【Java】Android中View的滑动

点击 “点击我可移动第一个View” 按钮之后,效果图如下所示:

【Java】Android中View的滑动

对以上改变布局参数移动 View 进行总结:不管是对 View 的 marginLeft 参数进行增大;还是要移动的 View 的旁边预先放一个 View,然后要向右移动View;他们两种方法都实现了 View 真正位置的移动,而不是 View 影像的移动;如果在 移动的 View 做事件监听,点击原始位置不会事件响应,点击移动后的位置会有事件响应。

4、使用 layout

使用 layout 移动 View 的思路是这样的:在View的onTouchEvent方法中对MotionEvent中的坐标进行记录,记录按下的时候记录,在移动的时候计算他们的偏移量,调用layout()对view的位置进行重绘制;下面举个例子:

(1) 新建一个布局文件,名叫 activity_use_layout.xml :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="demo1.xe.com.myapplication2.UseLayoutActivity">

<TextView android:id="@+id/tv"

android:layout_width="wrap_content"

android:text="使用 Layout移动View"

android:onClick="onClick"

android:layout_height="wrap_content" />

</RelativeLayout>

(2) 新建一个 Java 文件,名叫 UseLayoutActivity,它的实现代码如下所示:

TextView mTv;

private int lastX,lastY;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_use_layout);

mTv = findViewById(R.id.tv);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getRawX();

int y = (int) event.getRawY();

switch (event.getAction()){

case MotionEvent.ACTION_DOWN:

lastX = x;

lastY = y;

break;

case MotionEvent.ACTION_MOVE:

int offsetX = x - lastX;

int offsetY = y - lastY;

mTv.layout(mTv.getLeft()+offsetX,

mTv.getTop()+offsetY,

mTv.getRight()+offsetX,

mTv.getBottom()+offsetY);

lastX = x;

lastY = y;

break;

}

return true;

}

public void onClick(View v){

Toast.makeText(this," 点击了 “使用 Layout移动View” 按钮 ",Toast.LENGTH_SHORT).show();

}

没滑动屏幕之前的效果图如下所示:

【Java】Android中View的滑动

滑动屏幕某一瞬间的效果图如下所示:

【Java】Android中View的滑动

对以上使用 layout 移动 View 进行总结:使用 layout 移动 View,改变的不是 View 的影像,而是 View 真正的位置,所以如果要设置 View 的事件监听,点击移动后的 View 才会响应事件;使用 layout 移动 View 是和 Activity 的触摸事件结合使用的,触摸的时候获取相对于屏幕触摸的x 和 y 坐标,然后手指移动的过程中计算出移动的距离再加上 View 相对于父视图的位置,得到 View 移动后的位置,最后 View 使用 layout 方法 重新布局再进行重新绘画。

好了,本篇文章写到这里就结束了,由于本人技术水平有限,难免会有出错的地方,欢迎批评指正,谢谢大家的阅读,另外附上Android的View滑动demo

【Java】Android中View的滑动关注微信公众号,阅读更多有趣的技术文章

以上是 【Java】Android中View的滑动 的全部内容, 来源链接: utcz.com/a/114192.html

回到顶部