android listview 的弹性滑动 简单demo 实现
弹性滑动的效果比较好看。但是 在2.2以下版本中,android 本身没有实现,想要实现这中效果要自己去写
前几天在iteye上看见了一个博客给我很大的启示,于是自己动手实验了一下感觉还可以。在这里把我的源码给大家贴上让大家一起分享,希望大家也能提出更好的意见。废话不多说上源码:
1.自己些一个MyListview 继承listview 类:
package com.wljie; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.GestureDetector.OnGestureListener; import android.view.animation.TranslateAnimation; import android.widget.ListView; public class MyListView extends ListView { private Context context; private boolean outBound = false ; private int distance; private int firstOut; private static final String TAG = "wljie" ; public MyListView(Context context, AttributeSet attrs) { super (context, attrs); this .context = context; Log.d(TAG, "IN 1" ); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super (context, attrs, defStyle); this .context = context; Log.d(TAG, "IN 2" ); } public MyListView(Context context) { super (context); this .context = context; Log.d(TAG, "IN 3" ); } GestureDetector gestureDetector = new GestureDetector( new OnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false ; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } /** * 手势滑动的时候触发 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.d(TAG, "ENTER onscroll" ); int firstPos = getFirstVisiblePosition(); int lastPos = getLastVisiblePosition(); int itemCount = getCount(); // outbound Top if (outBound && firstPos != 0 && lastPos != (itemCount - 1 )) { scrollTo( 0 , 0 ); return false ; } View firstView = getChildAt(firstPos); if (!outBound) firstOut = ( int ) e2.getRawY(); if (firstView != null && (outBound || (firstPos == 0 && firstView.getTop() == 0 && distanceY < 0 ))) { // Record the length of each slide distance = firstOut - ( int ) e2.getRawY(); scrollTo( 0 , distance / 2 ); return true ; } // outbound Bottom return false ; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub return false ; } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false ; } }); @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(TAG, "dispatchTouchEvent" ); int act = event.getAction(); if ((act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_CANCEL) && outBound) { outBound = false ; // scroll back } if (!gestureDetector.onTouchEvent(event)) { outBound = false ; } else { outBound = true ; } Rect rect = new Rect(); getLocalVisibleRect(rect); TranslateAnimation am = new TranslateAnimation( 0 , 0 , -rect.top, 0 ); am.setDuration( 300 ); startAnimation(am); scrollTo( 0 , 0 ); return super .dispatchTouchEvent(event); } } |
2.在main.xml 中写入
<?xml version= "1.0" encoding= "utf-8" ?> <LinearLayout android:id= "@+id/LinearLayout01" android:layout_width= "fill_parent" android:layout_height= "fill_parent" xmlns:android= "http://schemas.android.com/apk/res/android" > <com.wljie.MyListView android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:id= "@+id/MyListView" /> </LinearLayout> |
3.创建一个my_listitem.xml
<?xml version= "1.0" encoding= "utf-8" ?> <LinearLayout android:layout_width= "fill_parent" xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation= "vertical" android:layout_height= "wrap_content" android:id= "@+id/MyListItem" android:paddingBottom= "3dip" android:paddingLeft= "10dip" > <TextView android:layout_height= "wrap_content" android:layout_width= "fill_parent" android:id= "@+id/ItemTitle" android:textSize= "30dip" > </TextView> <TextView android:layout_height= "wrap_content" android:layout_width= "fill_parent" android:id= "@+id/ItemText" > </TextView> </LinearLayout> |
4.在Main.java中进行下一步的显示
package com.wljie; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.graphics.Rect; import android.os.Bundle; import android.view.animation.TranslateAnimation; import android.widget.SimpleAdapter; public class Main extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); // 绑定XML中的ListView,作为Item的容器 MyListView list = (MyListView) findViewById(R.id.MyListView); // 生成动态数组,并且转载数据 ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); for ( int i = 0 ; i < 30 ; i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put( "ItemTitle" , "This is Title....." ); map.put( "ItemText" , "This is text....." ); mylist.add(map); } // 生成适配器,数组===》ListItem SimpleAdapter mSchedule = new SimpleAdapter( this , // 没什么解释 mylist, // 数据来源 R.layout.my_listitem, // ListItem的XML实现 // 动态数组与ListItem对应的子项 new String[] { "ItemTitle" , "ItemText" }, // ListItem的XML文件里面的两个TextView ID new int [] { R.id.ItemTitle, R.id.ItemText }); // 添加并且显示 list.setAdapter(mSchedule); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架