示例:
xml代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/bottomLL"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="horizontal"
android:background="@color/colorAccent"
android:layout_alignParentBottom="true">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</RelativeLayout>
java代码:
public class MainActivity extends AppCompatActivity {
private LinearLayout bottomLL;// 容器
private ListView listView;// 列表
private ArrayAdapter adapter;// adapter
private int initHeight;// 布局容器初始化高度
private float posX;// 手指初碰屏幕时x值
private float posY;// 手指初碰屏幕时y值
private float curPosX;// 实时x值
private float curPosY;// 实时v值
private int UP = 0;// 上
private int DOWN = 1;// 下
private int LEFT = 2;// 左
private int RIGHT = 3;// 右
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化容器
bottomLL = findViewById(R.id.bottomLL);
// 初始化布局容器高度赋值
initHeight = bottomLL.getLayoutParams().height;
// 数据
String[] arrs = {"head","111","111","111","111","111","111",
"111","111","111","111","111","345","111","111","111","111","111"
,"111","111","111","111","111","222","333","444","111","111","111"
,"111","111","666","777","888","999"};
// 初始化纵向列表
listView = findViewById(R.id.listView);
adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrs);
listView.setAdapter(adapter);
// 设置触摸手势
listView.setOnTouchListener(directionListener);
// 设置滚动手势
listView.setOnScrollListener(scrollChangeListener);
}
/**
* OnTouch监听事件
* */
View.OnTouchListener directionListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v,MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
posX = event.getX();
posY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
curPosX = event.getX();
curPosY = event.getY();
if ((curPosX - posX > 0) && (Math.abs(curPosX - posX) > 10)){
System.out.println("向右滑动");
}
else if ((curPosX - posX < 0) && (Math.abs(curPosX-posX) > 10)){
System.out.println("向左滑动");
}
if ((curPosY - posY > 0) && (Math.abs(curPosY - posY) > 10)){
System.out.println("向下滑动");
float downHeight = - Math.abs(curPosY - posY);
changeHeight(DOWN,(int) downHeight);
}
else if ((curPosY - posY < 0) && (Math.abs(curPosY-posY) > 10)){
System.out.println("向上滑动");
float upHeight = Math.abs(curPosY-posY);
changeHeight(UP,(int) upHeight);
}
break;
case MotionEvent.ACTION_UP:
/*if ((curPosX - posX > 0) && (Math.abs(curPosX - posX) > 25)){
System.out.println("向右滑动");
}
else if ((curPosX - posX < 0) && (Math.abs(curPosX-posX) > 25)){
System.out.println("向左滑动");
}
if ((curPosY - posY > 0) && (Math.abs(curPosY - posY) > 25)){
System.out.println("向下滑动");
}
else if ((curPosY - posY < 0) && (Math.abs(curPosY-posY) > 25)){
System.out.println("向上滑动");
}*/
break;
}
return true;
}
};
/**
* 改变容器高度
* @param DIRECTION 方向:
* UP = 0;// 上
* DOWN = 1;// 下
* LEFT = 2;// 左
* RIGHT = 3;// 右
* @param changeHeight 改变高度
* */
private void changeHeight(int DIRECTION, int changeHeight){
//Display屏幕显示的详细信息
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//int screenWidth = dm.widthPixels;// 当前屏幕宽度
int screenHeight = dm.heightPixels;// 当前屏幕高度
int density = (int) dm.density;// 屏幕单位
// 获取视图原本高度
final ViewGroup.LayoutParams params = bottomLL.getLayoutParams();
// 变化的高度
final int finalChangeHeight = changeHeight/density;
// 获取改变后最终高度
final int finalHeight = params.height + finalChangeHeight;
/**
*finalHeight绝对值大于等于布局容器初始高度并且finalHeight小于屏幕高度
* */
if (Math.abs(finalHeight) >= initHeight && finalHeight < screenHeight){
bottomLL.post(new Runnable() {
@Override
public void run() {
// 布局容器高度随手指滑动而改变
params.height = finalHeight;
bottomLL.setLayoutParams(params);
}
});
}
/**
* 手指向上滑动并且改变后的最终高度大于等于屏幕高度
*/
if (DIRECTION == UP && finalHeight >= screenHeight){
// 恢复listView自己的滑动事件
listView.setOnTouchListener(null);
}
}
/**
* OnScroll 监听事件
* */
AbsListView.OnScrollListener scrollChangeListener = new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,int scrollState) {
/**
*scrollState有三种状态,分别是SCROLL_STATE_IDLE、SCROLL_STATE_TOUCH_SCROLL、SCROLL_STATE_FLING
*SCROLL_STATE_IDLE是当屏幕停止滚动时
*SCROLL_STATE_TOUCH_SCROLL是当用户在以触屏方式滚动屏幕并且手指仍然还在屏幕上时(The user is scrolling using touch, and their finger is still on the screen)
*SCROLL_STATE_FLING是当用户由于之前划动屏幕并抬起手指,屏幕产生惯性滑动时(The user had previously been scrolling using touch and had performed a fling)
*/
}
/**
* 滚动实时监听
* */
@Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) {
/**
* firstVisibleItem 表示在当前屏幕显示的第一个listItem在整个listView里面的位置(下标从0开始)
* visibleItemCount表示在显示屏幕可以见到的ListItem(部分显示的ListItem也算)总数
* totalItemCount表示ListView的ListItem总数
* listView.getLastVisiblePosition()表示在显示屏幕最后一个ListItem
* (最后ListItem要完全显示出来才算)在整个ListView的位置(下标从0开始)
*/
/**
* listView的第一个item在初始位置时
* 恢复布局高度跟随手指滑动改变
*/
if (firstVisibleItem == 0){
listView.setOnTouchListener(directionListener);
}
}
};
}