前言:这几天房子真是把我搞得头大,天天也睡不好,奶奶个熊,不知道决策对不对,听天由命吧。
相关文章:
1、《 ListView滑动删除实现之一——merge标签与LayoutInflater.inflate()》
2、《ListView滑动删除实现之二——scrollTo、scrollBy详解》
3、《 ListView滑动删除实现之三——创建可滑动删除的ListView》
4、《ListView滑动删除实现之四——Scroller类与listview缓慢滑动》
今天就要来实现我们开头所说的那个滑动删除的效果了,首先来看看如何让视图跟随手指移动而移动。然后再进一步看看在ListView中又该如何做。
知识补充
这里先补充一个知识。这里会用到一个函数:
View.getScrollX()
它返回当前的view视角横向移动的坐标,即我们调用View.scrollX(x,y),getScrollX()返回的就是这里的x
View.getScrollY()同理。
一、如何让VIEW跟随手指反向移动
先看下面效果图:
这个图大家估计很容易看懂,就是让里面的View(蓝色框和黄色框)跟着我们的手指移动。但大家注意了,我们调用scrollTo移动的它们父容器(LinearLayout)的视角。所以我们LinearLayout的移动方向与手指移动方向正好反过来。你比如,开始时,我们手指向左滑动。这时候我们的LinearLayout的视角要向右走,才能看到删除的黄框!后来,当手指向右滑动时,我们的LinearLayout的视角只有向左走才能回到蓝色框视图!所以,从效果图里可以看到的最重要一点是:父窗口(LinearLayout)的视角移动向方与手指的移动方向正好是相反的!!!!这一点大家一定要理解出来,不然代码上就会出错。这里看不懂也没关系,下面会结合代码和视图具体讲解。
然后我们看一下具体实现:
1、首先,我们看看布局(acitivty_main.xml)
先列出代码:
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/lin_root"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0000ff"
android:text="ITEM"
android:gravity="center"
android:textSize="25dp" />
<TextView
android:layout_width="200dp"
android:layout_height="fill_parent"
android:background="#ffff00"
android:text="删除"
android:textSize="25dp"
android:textColor="#ffffff"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
从效果图中,我们也可以看到,主布局是一个LinearLayout的垂直布局,我们要滑动的布局页面是其中的第二个LinearLayout,它是一个水平布局,我们在前一节讲过它的布局方式:
<LinearLayout
android:id="@+id/lin_root"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0000ff"
android:text="ITEM"
android:gravity="center"
android:textSize="25dp" />
<TextView
android:layout_width="200dp"
android:layout_height="fill_parent"
android:background="#ffff00"
android:text="删除"
android:textSize="25dp"
android:textColor="#ffffff"
android:gravity="center" />
</LinearLayout>
首先,将第一个TextView(蓝色块)width_layout设置为fill_parent或者match_parent来填满整个窗口。然后旁边再附一个黄色块的TextView;由于父容器LinearLayout是水平布局,所以蓝色框会占满整个父容器,黄色框会被挤到右边看不到的位置。下面我们看看操作代码.
2、MainActivity代码
操作代码如下:
public class MainActivity extends Activity {
private LinearLayout itemRoot;
private int mlastX = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemRoot = (LinearLayout)findViewById(R.id.lin_root);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int scrollX = itemRoot.getScrollX();
int x = (int)event.getX();
if (event.getAction() == MotionEvent.ACTION_MOVE){
int newScrollX = scrollX + mlastX - x;
itemRoot.scrollTo(newScrollX,0);
}
mlastX = x;
return super.onTouchEvent(event);
}
}
这里最难的就是如何计算移动距离了。我们下面用一个图来讲解移动距离的计算方法。
先看下面这个图,表示的是根部的LinearLayout(lin_root)的视角跟随手指的移动方向。下面为了讲解方便起见,就用根布局的ID:lin_root来代表根布局的视图。
图(1),表示程序的初始化情况:黑色框表示屏幕,从这张图中可以看到,蓝色块显示在屏幕中,但黄色块在屏幕外。
图(2),这个图模拟此时lin_root.scrollTo到了一个点,其中红色框表示移动后的lin_root视角。它对应的显示效果图就是它下面的那个图。
图(3),在图(2)的基础上,用户手指又滑动的一段距离,此时lin_root视角继续往后移动,在图(3)中的绿色框就表示这时候移动后的lin_root视角。它对应的显示效果是它下面的那个图。
但这里有个问题必须注意:我们的手指是向左移动的,而lin_root的视角是向右移动的。也就是说,手指的移动方向与lin_root视角的移动方向是反过来的。
理解了上面的视角的移动方向与手指的移动方向是反过来的之后,然后我们再看下面这个图:
在这个图中,显示了如何计算出手指的移动距离
要计算出手指的移动距离,必须利用lin_root的父容器