转自http://blog.csdn.net/lilu_leo/article/details/8122367
在listview中,可以加入动画使其效果更炫一点。这个demo修改至网上下载的一个版本,改动还算比较大。因为有动画,所以不好上演示图,不知道看到博客的各位有什么可以生成gif的工具,希望能够推荐一下。
因为是修改的别人的代码,他的demo中item数据的意义,我也不是太明白,先上一张图片:
进入程序时,呈现飞入效果。从左向右滑动item时,删除该item。
下面进入代码:
- public class ListdemoActivity extends Activity implements OnItemClickListener, OnTouchListener{
- private ArrayList<Map<String, Object>> mData;
- private ListView mListView;
- private MyAdapter mAdapter;
- private Button mDeleteButton,mEditButton;
- float x , y , upx, upy;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.history_record);
- final Calendar c = Calendar.getInstance();
- int year = c.get(Calendar.YEAR); //获取当前年份
- int month = c.get(Calendar.MONTH);//获取当前月份
- int day = c.get(Calendar.DAY_OF_MONTH);//获取当前月份的日期号码
- int hour = c.get(Calendar.HOUR_OF_DAY);//获取当前的小时数
- int minute = c.get(Calendar.MINUTE);//获取当前的分钟数
- String minutes = "";
- if (minute<10) {
- minutes = "0"+minute;
- }
- String time_value = year+":"+month+":"+day+":"+hour+":"+ minutes;
- mData = new ArrayList<Map<String, Object>>();
- for (int i = 0; i < 10; i++) {
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("image", R.drawable.ic_launcher);
- map.put("maxValue", "最高值:" + i);
- map.put("avgValue", "平均值:" + i);
- map.put("time", time_value);
- map.put("how_time", "持续时间: " + i);
- map.put("last_time", "最后时间:2012-11");
- map.put("isVisible", false);
- mData.add(map);
- }
- mAdapter = new MyAdapter(this);
- mListView = (ListView)findViewById(R.id.list);
- mListView.setCacheColorHint(Color.TRANSPARENT); // 设置背景透明度
- mListView.setAdapter(mAdapter);
- mListView.setOnTouchListener(this);
- // mListView.setOnItemClickListener(this);
- mListView.setLayoutAnimation(getListAnim());
- }
在onCreate()方法里面,主要是初始化控件和数据。x、y、upx、upy是onTouch时判定位移的参数,以上代码比较简单。
下面就是mListView.setOnTouchListener(this)里面的内容,该activity继承了OnTouchListener接口,下面是它的实现:
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- x = event.getX();
- y = event.getY();
- }
- if (event.getAction() == MotionEvent.ACTION_UP) {
- upx = event.getX();
- upy = event.getY();
- int position1 = ((ListView) v).pointToPosition((int) x, (int) y);
- int position2 = ((ListView) v).pointToPosition((int) upx,(int) upy);
- if (position1 == position2 && Math.abs(x - upx) > 10) {
- View view = ((ListView) v).getChildAt(position1);
- removeListItem(view, position1);
- }
- }
- return false;
- }
判断是否滑动,如果滑动,调用removeListItem方法:
- protected void removeListItem(View rowView, final int positon) {
- final Animation animation = (Animation) AnimationUtils.loadAnimation(rowView.getContext(), R.anim.item_anim);
- animation.setAnimationListener(new AnimationListener() {
- public void onAnimationStart(Animation animation) {}
- public void onAnimationRepeat(Animation animation) {}
- public void onAnimationEnd(Animation animation) {
- mData.remove(positon);
- mAdapter.notifyDataSetChanged();
- animation.cancel();
- }
- });
- rowView.startAnimation(animation);
- }
在代码中,我们可以看到在onAnimationEnd()中,是删除了数据。同理,当你想在动画开始时进行一些操作,就可以在回调函数onAnimationStart中进行。另外,方法里使用了动画:
item_anim.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <translate xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="800"
- android:fromXDelta="0"
- android:fromYDelta="0"
- android:toXDelta="800"
- android:toYDelta="0" />
下面再看飞入效果,mListView.setLayoutAnimation(getListAnim()):
也可以在listView的xml中:android:layoutAnimation="@anim/item_anim"这样定义
- private LayoutAnimationController getListAnim() {
- AnimationSet set = new AnimationSet(true);
- Animation animation = new AlphaAnimation(0.0f, 1.0f);
- animation.setDuration(300);
- set.addAnimation(animation);
- animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
- Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
- -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
- animation.setDuration(500);
- set.addAnimation(animation);
- LayoutAnimationController controller = new LayoutAnimationController(
- set, 0.5f);
- return controller;
- }
使用LayoutAnimation实现。
在代码中,屏蔽掉了mListView.setOnItemClickListener(this)这行代码,因为它对onTouch会造成干扰,当然它的方法中是弹出一个Dialog进行删除操作:
- @Override
- public void onItemClick(AdapterView<?> parent, View view, final int position,
- long id) {
- new AlertDialog.Builder(ListdemoActivity.this).setTitle("标题")
- .setMessage("提示内容").setPositiveButton("删除",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog,
- int whichButton) {
- mData.remove(position);
- mAdapter.notifyDataSetChanged();
- }
- }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- System.out.println("你好啊");
- }
- }).show();
- }
比较重要,但是又最常见的自定义Adapter:
- class ViewHolder {
- public TextView maxValue;
- public Button del_btn;
- public TextView how_time;
- public TextView last_time;
- public TextView avgValue;
- public ImageView image;
- public boolean isVisible = true;
- }
- public class MyAdapter extends BaseAdapter {
- private Context mContext;
- private MyAdapter(Context context) {
- mContext = context;
- }
- public int getCount() {
- return mData.size();
- }
- public Object getItem(int position) {
- return position;
- }
- public long getItemId(int position) {
- return position;
- }
- public View getView(final int position, View convertView, ViewGroup parent) {
- ViewHolder holder = null;
- if(convertView == null) {
- holder = new ViewHolder();
- LayoutInflater inflater = LayoutInflater.from(mContext);
- convertView = inflater.inflate(R.layout.record_info, null);
- holder.del_btn = (Button) convertView.findViewById(R.id.del);
- holder.how_time = (TextView) convertView.findViewById(R.id.how_time);
- holder.last_time = (TextView) convertView.findViewById(R.id.last_time);
- holder.avgValue = (TextView) convertView.findViewById(R.id.avgValue);
- holder.image = (ImageView)convertView.findViewById(R.id.image);
- holder.maxValue = (TextView)convertView.findViewById(R.id.maxValue);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder)convertView.getTag();
- }
- holder.image.setBackgroundResource((Integer)mData.get(position).get("image"));
- holder.del_btn.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- mData.remove(position);
- mAdapter.notifyDataSetChanged();
- }
- });
- holder.how_time.setText((String)(mData.get(position).get("how_time")));
- holder.last_time.setText((String)(mData.get(position).get("last_time")));
- holder.avgValue.setText((String)(mData.get(position).get("avgValue")));
- holder.maxValue.setText((String)(mData.get(position).get("maxValue")));
- return convertView;
- }
- }
这个相信都写烂了。
最后:代码下载地址:http://download.csdn.net/detail/aomandeshangxiao/4696742
晚安!
好吧,其实上面的代码是有问题的,就是下面的一位童鞋提到的问题,当滑动到最后几项,选择滑动删除的时候,会报空指针异常,为什么会出现这种情况?我在打印的log中发现listView只是会创建前5个View,后面看到显示的View,均是重用。当尝试从ListView中获取第十个item的View的时候,肯定会报空指针异常。
所以在onTouch方法中做了一下修改:
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- x = event.getX();
- y = event.getY();
- }
- if (event.getAction() == MotionEvent.ACTION_UP) {
- upx = event.getX();
- upy = event.getY();
- int position1 = ((ListView) v).pointToPosition((int) x, (int) y);
- int position2 = ((ListView) v).pointToPosition((int) upx,(int) upy);
- int FirstVisiblePosition = mListView.getFirstVisiblePosition();
- if (position1 == position2 && Math.abs(x - upx) > 10) {
- View view = ((ListView) v).getChildAt(position1);
- if (view == null) {
- view = ((ListView) v).getChildAt(position1 - FirstVisiblePosition);
- }
- removeListItem(view, position1);
- }
- }
- return false;
- }