第一次开通博客,先写一些笔记试一下吧~
IOS由于不包含返回按钮,所以经常有一个滑动删除当前页面的用户习惯。有时产品为了保持iOS和Android 的风格一致,也会要求侧滑结束当前页面,我也是看的别人的Demo,自己写一些简单的笔记整理一下思路,供大家参考。
自定义可以滑动的RelativeLayout, 类似于IOS的滑动删除页面效果,当我们要使用 此功能的时候,需要将该Activity的顶层布局设置为SildingFinishLayout, 然后需要调用setTouchView()方法来设置需要滑动的View。
1、自定义顶层布局SildingFinishLayout
1.首先要获取其所在的父布局,判断其中的不同操作手势。
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
// 获取SildingFinishLayout所在布局的父布局
mParentView = (ViewGroup) this.getParent();
viewWidth = this.getWidth();
}
}
2.定义接口监听,结束页面
public interface OnSildingFinishListener {
public void onSildingFinish();
}
3.点击内部控件,执行该控件的相应操作
public void setTouchView(View touchView) {
this.touchView = touchView;
touchView.setOnTouchListener(this);
}
public View getTouchView() {
return touchView;
}
4.定义几个Boolean类型的方法,当用户点击的是内部的按钮或者AbsListView, 例如ListView, GridView等其子类时,禁止把当前页面finish掉。
private boolean isTouchOnAbsListView() {
return touchView instanceof AbsListView ? true : false;
}
private boolean isTouchOnScrollView() {
return touchView instanceof ScrollView ? true : false;
}
5.当页面很长时,就需要滑动,此时要设置布局能继续加载出来
/**
* 滚动出界面
*/
private void scrollRight() {
final int delta = (viewWidth + mParentView.getScrollX());
// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
mScroller.startScroll(mParentView.getScrollX(), 0, -delta + 1, 0,
Math.abs(delta));
postInvalidate();
}
/**
* 滚动到起始位置
*/
private void scrollOrigin() {
int delta = mParentView.getScrollX();
mScroller.startScroll(mParentView.getScrollX(), 0, -delta, 0,
Math.abs(delta));
postInvalidate();
}
6.进行最重要的手势判断,判断不同的手势,滑动时的位移,来判断是否结束当前页面
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = tempX = (int) event.getRawX();
downY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) event.getRawX();
int deltaX = tempX - moveX;
tempX = moveX;
if (Math.abs(moveX - downX) > mTouchSlop
&& Math.abs((int) event.getRawY() - downY) < mTouchSlop) {
isSilding = true;
// 若touchView是AbsListView,
// 则当手指滑动,取消item的点击事件,不然我们滑动也伴随着item点击事件的发生
if (isTouchOnAbsListView()) {
MotionEvent cancelEvent = MotionEvent.obtain(event);
cancelEvent
.setAction(MotionEvent.ACTION_CANCEL
| (event.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
v.onTouchEvent(cancelEvent);
}
}
if (moveX - downX >= 0 && isSilding) {
mParentView.scrollBy(deltaX, 0);
// 屏蔽在滑动过程中ListView ScrollView等自己的滑动事件
if (isTouchOnScrollView() || isTouchOnAbsListView()) {
return true;
}
}
break;
case MotionEvent.ACTION_UP:
isSilding = false;
if (mParentView.getScrollX() <= -viewWidth / 2) {
isFinish = true;
scrollRight();
} else {
scrollOrigin();
isFinish = false;
}
break;
}
// 假如touch的view是AbsListView或者ScrollView 我们处理完上面自己的逻辑之后
// 再交给AbsListView, ScrollView自己处理其自己的逻辑
if (isTouchOnScrollView() || isTouchOnAbsListView()) {
return v.onTouchEvent(event);
}
// 其他的情况直接返回true
return true;
}
2、页面布局
<com.example.view.SildingFinishLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sildingFinishLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#556677" >
<ListView
android:id="@+id/listView"
android:cacheColorHint="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</com.example.view.SildingFinishLayout>
我只是简单的写了一个,自定义布局继承的是RelativeLayout,按照RelativeLayout写布局即可
3、监听页面
ListView mListView = (ListView) findViewById(R.id.listView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
AbsActivity.this, android.R.layout.simple_list_item_1, list);
mListView.setAdapter(adapter);
SildingFinishLayout mSildingFinishLayout = (SildingFinishLayout) findViewById(R.id.sildingFinishLayout);
mSildingFinishLayout
.setOnSildingFinishListener(new OnSildingFinishListener() {
@Override
public void onSildingFinish() {
AbsActivity.this.finish();
}
});
// touchView要设置到ListView上面
mSildingFinishLayout.setTouchView(mListView);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
startActivity(new Intent(AbsActivity.this, NormalActivity.class));
overridePendingTransition(R.anim.base_slide_right_in,
R.anim.base_slide_remain);
}
});
我只是简单的理一下思路,文笔不好,慢慢练吧。附上源码,不然就太不厚道了