ListView飞入加载item及滑动删除item

来源:互联网 发布:南昌云迈网络做什么的 编辑:程序博客网 时间:2024/06/15 04:42

在listview中,可以加入动画使其效果更炫一点。这个demo修改至网上下载的一个版本,改动还算比较大。因为有动画,所以不好上演示图,不知道看到博客的各位有什么可以生成gif的工具,希望能够推荐一下。

因为是修改的别人的代码,他的demo中item数据的意义,我也不是太明白,先上一张图片:


进入程序时,呈现飞入效果。从左向右滑动item时,删除该item。

下面进入代码:

[java] view plaincopy
  1. public class ListdemoActivity extends Activity implements OnItemClickListener, OnTouchListener{  
  2.     private ArrayList<Map<String, Object>> mData;  
  3.     private ListView mListView;  
  4.     private MyAdapter mAdapter;  
  5.     private Button mDeleteButton,mEditButton;  
  6.     float x , y , upx, upy;  
  7.       
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.history_record);  
  12.         final Calendar c = Calendar.getInstance();         
  13.         int year = c.get(Calendar.YEAR); //获取当前年份   
  14.         int month = c.get(Calendar.MONTH);//获取当前月份   
  15.         int day  = c.get(Calendar.DAY_OF_MONTH);//获取当前月份的日期号码   
  16.         int hour = c.get(Calendar.HOUR_OF_DAY);//获取当前的小时数   
  17.         int minute = c.get(Calendar.MINUTE);//获取当前的分钟数  
  18.         String minutes = "";  
  19.         if (minute<10) {  
  20.             minutes = "0"+minute;  
  21.         }  
  22.         String time_value = year+":"+month+":"+day+":"+hour+":"+ minutes;  
  23.   
  24.         mData = new ArrayList<Map<String, Object>>();  
  25.         for (int i = 0; i < 10; i++) {     
  26.             Map<String, Object> map = new HashMap<String, Object>();  
  27.             map.put("image", R.drawable.ic_launcher);  
  28.             map.put("maxValue""最高值:" + i);  
  29.             map.put("avgValue""平均值:" + i);  
  30.             map.put("time", time_value);  
  31.             map.put("how_time""持续时间: " + i);  
  32.             map.put("last_time""最后时间:2012-11");  
  33.             map.put("isVisible"false);  
  34.             mData.add(map);  
  35.   
  36.         }         
  37.         mAdapter = new MyAdapter(this);  
  38.         mListView = (ListView)findViewById(R.id.list);  
  39.         mListView.setCacheColorHint(Color.TRANSPARENT); // 设置背景透明度  
  40.         mListView.setAdapter(mAdapter);  
  41.         mListView.setOnTouchListener(this);  
  42. //      mListView.setOnItemClickListener(this);  
  43.         mListView.setLayoutAnimation(getListAnim());  
  44.           
  45.     }  


在onCreate()方法里面,主要是初始化控件和数据。x、y、upx、upy是onTouch时判定位移的参数,以上代码比较简单。

下面就是mListView.setOnTouchListener(this)里面的内容,该activity继承了OnTouchListener接口,下面是它的实现:

[java] view plaincopy
  1. @Override  
  2.     public boolean onTouch(View v, MotionEvent event) {  
  3.               
  4.          if (event.getAction() == MotionEvent.ACTION_DOWN) {   
  5.              x = event.getX();   
  6.              y = event.getY();   
  7.          }   
  8.          if (event.getAction() == MotionEvent.ACTION_UP) {   
  9.              upx = event.getX();   
  10.              upy = event.getY();   
  11.              int position1 = ((ListView) v).pointToPosition((int) x, (int) y);   
  12.              int position2 = ((ListView) v).pointToPosition((int) upx,(int) upy);               
  13.              if (position1 == position2 && Math.abs(x - upx) > 10) {   
  14.                  View view = ((ListView) v).getChildAt(position1);   
  15.                  removeListItem(view, position1);   
  16.              }   
  17.          }   
  18.           
  19.         return false;  
  20.     }  

判断是否滑动,如果滑动,调用removeListItem方法:

[java] view plaincopy
  1. protected void removeListItem(View rowView, final int positon) {          
  2.         final Animation animation = (Animation) AnimationUtils.loadAnimation(rowView.getContext(), R.anim.item_anim);   
  3.         animation.setAnimationListener(new AnimationListener() {   
  4.             public void onAnimationStart(Animation animation) {}   
  5.             public void onAnimationRepeat(Animation animation) {}   
  6.             public void onAnimationEnd(Animation animation) {   
  7.                 mData.remove(positon);   
  8.                 mAdapter.notifyDataSetChanged();   
  9.                 animation.cancel();   
  10.             }   
  11.         });   
  12.            
  13.         rowView.startAnimation(animation);   
  14.     }  

在代码中,我们可以看到在onAnimationEnd()中,是删除了数据。同理,当你想在动画开始时进行一些操作,就可以在回调函数onAnimationStart中进行。另外,方法里使用了动画:

item_anim.xml:

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <translate xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:duration="800"   
  4.     android:fromXDelta="0"   
  5.     android:fromYDelta="0"   
  6.     android:toXDelta="800"   
  7.     android:toYDelta="0" />   

下面再看飞入效果,mListView.setLayoutAnimation(getListAnim()):


也可以在listView的xml中:android:layoutAnimation="@anim/item_anim"这样定义

[java] view plaincopy
  1. private LayoutAnimationController getListAnim() {  
  2.         AnimationSet set = new AnimationSet(true);  
  3.         Animation animation = new AlphaAnimation(0.0f, 1.0f);  
  4.         animation.setDuration(300);  
  5.         set.addAnimation(animation);  
  6.   
  7.         animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,  
  8.         Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,  
  9.         -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);  
  10.         animation.setDuration(500);  
  11.         set.addAnimation(animation);  
  12.         LayoutAnimationController controller = new LayoutAnimationController(  
  13.         set, 0.5f);  
  14.         return controller;  
  15.         }  

使用LayoutAnimation实现。

在代码中,屏蔽掉了mListView.setOnItemClickListener(this)这行代码,因为它对onTouch会造成干扰,当然它的方法中是弹出一个Dialog进行删除操作:

[java] view plaincopy
  1. @Override  
  2.     public void onItemClick(AdapterView<?> parent, View view, final int position,  
  3.             long id) {  
  4.         new AlertDialog.Builder(ListdemoActivity.this).setTitle("标题")  
  5.         .setMessage("提示内容").setPositiveButton("删除",  
  6.                 new DialogInterface.OnClickListener() {  
  7.             public void onClick(DialogInterface dialog,  
  8.                     int whichButton) {  
  9.                 mData.remove(position);  
  10.                 mAdapter.notifyDataSetChanged();  
  11.             }  
  12.         }).setNegativeButton("取消"new DialogInterface.OnClickListener() {  
  13.             public void onClick(DialogInterface dialog, int which) {  
  14.                 System.out.println("你好啊");  
  15.             }  
  16.         }).show();  
  17.     }  

比较重要,但是又最常见的自定义Adapter:

[java] view plaincopy
  1. class ViewHolder {  
  2.         public TextView maxValue;  
  3.         public Button del_btn;  
  4.         public TextView how_time;  
  5.         public TextView last_time;  
  6.         public TextView  avgValue;  
  7.         public ImageView image;  
  8.         public boolean isVisible = true;  
  9.     }  
  10.       
  11.     public class MyAdapter extends BaseAdapter {      
  12.         private Context mContext;  
  13.         private MyAdapter(Context context) {  
  14.             mContext = context;  
  15.         }  
  16.   
  17.         public int getCount() {  
  18.             return mData.size();  
  19.         }  
  20.   
  21.         public Object getItem(int position) {  
  22.             return position;  
  23.         }  
  24.   
  25.         public long getItemId(int position) {  
  26.             return position;  
  27.         }  
  28.   
  29.         public View getView(final int position, View convertView, ViewGroup parent) {  
  30.             ViewHolder holder = null;  
  31.             if(convertView == null) {  
  32.                 holder = new ViewHolder();  
  33.                 LayoutInflater inflater = LayoutInflater.from(mContext);  
  34.                 convertView = inflater.inflate(R.layout.record_info, null);  
  35.                 holder.del_btn = (Button) convertView.findViewById(R.id.del);  
  36.                 holder.how_time = (TextView) convertView.findViewById(R.id.how_time);  
  37.                 holder.last_time = (TextView) convertView.findViewById(R.id.last_time);  
  38.                 holder.avgValue = (TextView) convertView.findViewById(R.id.avgValue);  
  39.                 holder.image = (ImageView)convertView.findViewById(R.id.image);  
  40.                 holder.maxValue = (TextView)convertView.findViewById(R.id.maxValue);  
  41.                 convertView.setTag(holder);  
  42.             } else {  
  43.                 holder = (ViewHolder)convertView.getTag();  
  44.             }  
  45.             holder.image.setBackgroundResource((Integer)mData.get(position).get("image"));  
  46.             holder.del_btn.setOnClickListener(new View.OnClickListener() {  
  47.                 public void onClick(View v) {  
  48.                     mData.remove(position);  
  49.                     mAdapter.notifyDataSetChanged();    
  50.   
  51.                 }  
  52.             });  
  53.             holder.how_time.setText((String)(mData.get(position).get("how_time")));             
  54.             holder.last_time.setText((String)(mData.get(position).get("last_time")));            
  55.             holder.avgValue.setText((String)(mData.get(position).get("avgValue")));           
  56.             holder.maxValue.setText((String)(mData.get(position).get("maxValue")));  
  57.             return convertView;  
  58.         }  
  59.   
  60.     }  

这个相信都写烂了。

最后:代码下载地址:http://download.csdn.net/detail/aomandeshangxiao/4696742

   晚安!

好吧,其实上面的代码是有问题的,就是下面的一位童鞋提到的问题,当滑动到最后几项,选择滑动删除的时候,会报空指针异常,为什么会出现这种情况?我在打印的log中发现listView只是会创建前5个View,后面看到显示的View,均是重用。当尝试从ListView中获取第十个item的View的时候,肯定会报空指针异常。

所以在onTouch方法中做了一下修改:

[java] view plaincopy
  1. @Override  
  2. public boolean onTouch(View v, MotionEvent event) {  
  3.           
  4.      if (event.getAction() == MotionEvent.ACTION_DOWN) {   
  5.             x = event.getX();   
  6.             y = event.getY();               
  7.         }   
  8.         if (event.getAction() == MotionEvent.ACTION_UP) {   
  9.             upx = event.getX();   
  10.             upy = event.getY();   
  11.             int position1 = ((ListView) v).pointToPosition((int) x, (int) y);   
  12.             int position2 = ((ListView) v).pointToPosition((int) upx,(int) upy);               
  13.             int FirstVisiblePosition = mListView.getFirstVisiblePosition();               
  14.             if (position1 == position2 && Math.abs(x - upx) > 10) {   
  15.                 View view = ((ListView) v).getChildAt(position1);                   
  16.                 if (view == null) {                    
  17.                  view = ((ListView) v).getChildAt(position1 - FirstVisiblePosition);  
  18.                 }                   
  19.                 removeListItem(view, position1);   
  20.             }   
  21.         }   
  22.       
  23.     return false;  
  24. }   

获取选中项重用的那个View,然后执行动画。在最后要感谢立涛和方涛对我的帮助!!!
原创粉丝点击