效果图,gif图片看起来略卡顿,实际很流畅
【实现ListView的弹性效果,下拉隐藏ToolBar(ActionBar),上拉显示ToolBar】
文章图片
ToolBar要注意,如果不是5.0以上的话,需要在gradle中引入V7包
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
1、布局文件
Item布局文件
主界面的代码实现
public class MainActivity extends ActionBarActivity implements AbsListView.OnScrollListener {public ArrayList data= https://www.it610.com/article/new ArrayList<>();
ListView lv;
int lastVisibleItem;
int mTouchSlop;
//获取系统认为的滑动的最小距离
float mFirstY;
float mCurrentY;
int direction;
boolean mShow;
private Toolbar toolbar;
Animator mAnimator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化toolBar
toolbar = (Toolbar) findViewById(R.id.tool);
if(toolbar != null) {
setSupportActionBar(toolbar);
}initLayout();
}/**
* 初始化数据
*/
private void initLayout() {//模拟数据
for (int i = 0;
i < 50;
i++) {
data.add("测试数据"+i);
}//获取系统认为的最低滑动距离
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
//对滑动时间进行判断
View.OnTouchListener myTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mFirstY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
mCurrentY = event.getY();
if(mCurrentY - mFirstY> mTouchSlop){
direction = 0;
//down
}else if (mFirstY - mCurrentY > mTouchSlop){
direction = 1;
//up
}if(direction == 1){
if(mShow){
toolbarAnimal(1);
//隐藏toolBar
mShow = !mShow;
}
}else if(direction == 0){
if(!mShow){
toolbarAnimal(0);
//显示toolBar
mShow = !mShow;
}
}break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
};
lv = (ListView) findViewById(R.id.lv);
View header = new View(this);
header.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
(int)getResources().getDimension(R.dimen.abc_action_bar_default_height)));
lv.addHeaderView(header);
lv.setAdapter(new MyAdapter());
lv.setOnTouchListener(myTouchListener);
lv.setOnScrollListener(this);
}/**
* 隐藏toolbar动画
* @param flag
*/
private void toolbarAnimal(int flag) {
if(mAnimator != null && mAnimator.isRunning()){
mAnimator.cancel();
}if(flag == 0){
mAnimator = ObjectAnimator.ofFloat(toolbar,"translationY",toolbar.getTranslationY(),0);
}else{
mAnimator = ObjectAnimator.ofFloat(toolbar,"translationY",toolbar.getTranslationY(),-toolbar.getHeight());
}mAnimator.start();
}/**
* 这里可以无视,是测试滑动状态
* @param view
* @param scrollState
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState){
case NumberPicker.OnScrollListener.SCROLL_STATE_IDLE:
Log.e("SCROLL_STATE_IDLE","停止");
break;
case NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
Log.e("SCROLL_STATE_TOUCH_SCROLL","滚动");
break;
case NumberPicker.OnScrollListener.SCROLL_STATE_FLING:
Log.e("SCROLL_STATE_FLING","惯性滑动");
break;
}
}/**
* 这里是判断上滑或者listView滑动的位置
* @param view
* @param firstVisibleItem
* @param visibleItemCount
* @param totalItemCount
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0){
Log.e("滑到底部了", "滑到底部了");
}if(firstVisibleItem > lastVisibleItem){
Log.e("正在上滑","正在上滑");
}else if(firstVisibleItem
自定义ListView代码,这里主要实现的是弹性效果
public class MyListView extends ListView {
Context mContxt;
int mMaxOverDistance = 30;
public MyListView(Context context) {
this(context, null);
}public MyListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContxt = context;
getmMaxOverDistance();
}@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent);
}//实用屏幕的density来计算具体的值,是为了让不同分辨率的弹性距离一致
public void getmMaxOverDistance(){
DisplayMetrics metrics = mContxt.getResources().getDisplayMetrics();
float density = metrics.density;
mMaxOverDistance = (int)(density*mMaxOverDistance);
}@Override
public void setOnScrollChangeListener(OnScrollChangeListener l) {
super.setOnScrollChangeListener(l);
}
}
项目下载地址https://github.com/GimiZhang/ListViewDemo.git